View Javadoc
1   /*
2    * Copyright (C) 2007-2012 Argeo GmbH
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *         http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.argeo.slc.osgi.build;
17  
18  import java.util.ArrayList;
19  import java.util.HashSet;
20  import java.util.Iterator;
21  import java.util.List;
22  import java.util.Set;
23  import java.util.SortedMap;
24  import java.util.TreeMap;
25  
26  import org.apache.commons.logging.Log;
27  import org.apache.commons.logging.LogFactory;
28  import org.argeo.slc.DefaultNameVersion;
29  import org.argeo.slc.NameVersion;
30  import org.argeo.slc.SlcException;
31  import org.argeo.slc.UnsupportedException;
32  import org.argeo.slc.build.Distribution;
33  import org.argeo.slc.build.ModularDistribution;
34  import org.eclipse.gemini.blueprint.context.BundleContextAware;
35  import org.osgi.framework.BundleContext;
36  import org.osgi.framework.Constants;
37  import org.springframework.beans.factory.InitializingBean;
38  
39  public abstract class AbstractOsgiModularDistribution implements
40  		ModularDistribution, BundleContextAware, InitializingBean {
41  	private final static Log log = LogFactory
42  			.getLog(AbstractOsgiModularDistribution.class);
43  
44  	private BundleContext bundleContext;
45  	private EclipseUpdateSite eclipseUpdateSite;
46  
47  	/** Initialized by the object itself. */
48  	private SortedMap<NameVersion, Distribution> distributions = new TreeMap<NameVersion, Distribution>();
49  
50  	protected abstract void fillDistributions(
51  			SortedMap<NameVersion, Distribution> distributions)
52  			throws Exception;
53  
54  	public Distribution getModuleDistribution(String moduleName,
55  			String moduleVersion) {
56  		return distributions.get(new DefaultNameVersion(moduleName,
57  				moduleVersion));
58  	}
59  
60  	public String getDistributionId() {
61  		return bundleContext.getBundle().getSymbolicName()
62  				+ "-"
63  				+ bundleContext.getBundle().getHeaders()
64  						.get(Constants.BUNDLE_VERSION);
65  	}
66  
67  	public Set<NameVersion> listModulesNameVersions() {
68  		return distributions.keySet();
69  	}
70  
71  	public Iterator<NameVersion> nameVersions() {
72  		return distributions.keySet().iterator();
73  	}
74  
75  	public void setBundleContext(BundleContext bundleContext) {
76  		this.bundleContext = bundleContext;
77  	}
78  
79  	public void afterPropertiesSet() throws Exception {
80  		fillDistributions(distributions);
81  		if (log.isDebugEnabled())
82  			log.debug("Distribution " + getName() + ":" + getVersion()
83  					+ " loaded (" + distributions.size() + " modules)");
84  	}
85  
86  	protected String findVersion(String name) {
87  		Set<String> versions = new HashSet<String>();
88  		for (NameVersion key : distributions.keySet()) {
89  			if (key.getName().equals(name))
90  				versions.add(key.getVersion());
91  		}
92  
93  		if (versions.size() == 0)
94  			throw new SlcException("Cannot find version for name " + name);
95  		else if (versions.size() > 1)
96  			throw new SlcException("Found more than one version for name "
97  					+ name + ": " + versions);
98  		else
99  			return versions.iterator().next();
100 
101 	}
102 
103 	public Object getModulesDescriptor(String descriptorType) {
104 		if (descriptorType.equals("eclipse"))
105 			return writeEclipseUpdateSite();
106 		else
107 			throw new UnsupportedException("descriptorType", descriptorType);
108 	}
109 
110 	protected Set<NameVersion> writePlainUrlList() {
111 		return distributions.keySet();
112 	}
113 
114 	protected String writeEclipseUpdateSite() {
115 		if (eclipseUpdateSite == null)
116 			throw new SlcException("No eclipse update site declared.");
117 
118 		StringBuffer buf = new StringBuffer("");
119 		buf.append("<site>");
120 
121 		List<EclipseUpdateSiteCategory> usedCategories = new ArrayList<EclipseUpdateSiteCategory>();
122 		for (EclipseUpdateSiteFeature feature : eclipseUpdateSite.getFeatures()) {
123 
124 			String featureId = feature.getName();
125 			String featureVersion = findVersion(featureId);
126 			buf.append("<feature");
127 			buf.append(" url=\"features/").append(featureId).append('_')
128 					.append(featureVersion).append(".jar\"");
129 			buf.append(" id=\"").append(featureId).append("\"");
130 			buf.append(" version=\"").append(featureVersion).append("\"");
131 			buf.append(">\n");
132 
133 			for (EclipseUpdateSiteCategory category : feature.getCategories()) {
134 				usedCategories.add(category);
135 				buf.append("  <category name=\"").append(category.getName())
136 						.append("\"/>\n");
137 			}
138 			buf.append("</feature>\n\n");
139 		}
140 
141 		for (EclipseUpdateSiteCategory category : usedCategories) {
142 			buf.append("<category-def");
143 			buf.append(" name=\"").append(category.getName()).append("\"");
144 			buf.append(" label=\"").append(category.getLabel()).append("\"");
145 			buf.append(">\n");
146 			buf.append("  <description>").append(category.getDescription())
147 					.append("</description>\n");
148 			buf.append("</category-def>\n\n");
149 		}
150 
151 		buf.append("</site>");
152 		return buf.toString();
153 	}
154 
155 	public String getName() {
156 		return bundleContext.getBundle().getSymbolicName();
157 	}
158 
159 	public String getVersion() {
160 		return bundleContext.getBundle().getHeaders()
161 				.get(Constants.BUNDLE_VERSION).toString();
162 	}
163 
164 	@Override
165 	public String toString() {
166 		return new DefaultNameVersion(this).toString();
167 	}
168 
169 	public void setEclipseUpdateSite(EclipseUpdateSite eclipseUpdateSite) {
170 		this.eclipseUpdateSite = eclipseUpdateSite;
171 	}
172 
173 	public BundleContext getBundleContext() {
174 		return bundleContext;
175 	}
176 
177 }