View Javadoc

1   /**
2    *
3    *  Licensed to the Apache Software Foundation (ASF) under one or more
4    *  contributor license agreements.  See the NOTICE file distributed with
5    *  this work for additional information regarding copyright ownership.
6    *  The ASF licenses this file to You under the Apache License, Version 2.0
7    *  (the "License"); you may not use this file except in compliance with
8    *  the License.  You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   *  Unless required by applicable law or agreed to in writing, software
13   *  distributed under the License is distributed on an "AS IS" BASIS,
14   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   *  See the License for the specific language governing permissions and
16   *  limitations under the License.
17   */
18  
19  package org.apache.geronimo.deployment.service;
20  
21  import java.beans.PropertyEditorSupport;
22  import java.util.ArrayList;
23  import java.util.Collection;
24  import java.util.HashSet;
25  import java.util.Iterator;
26  import java.util.LinkedHashSet;
27  import java.util.List;
28  import java.util.Set;
29  
30  import javax.xml.namespace.QName;
31  
32  import org.apache.geronimo.common.DeploymentException;
33  import org.apache.geronimo.common.propertyeditor.PropertyEditorException;
34  import org.apache.geronimo.deployment.xbeans.ArtifactType;
35  import org.apache.geronimo.deployment.xbeans.ClassFilterType;
36  import org.apache.geronimo.deployment.xbeans.DependenciesType;
37  import org.apache.geronimo.deployment.xbeans.EnvironmentDocument;
38  import org.apache.geronimo.deployment.xbeans.EnvironmentType;
39  import org.apache.geronimo.deployment.xbeans.ImportType;
40  import org.apache.geronimo.deployment.xbeans.DependencyType;
41  import org.apache.geronimo.kernel.repository.Artifact;
42  import org.apache.geronimo.kernel.repository.Dependency;
43  import org.apache.geronimo.kernel.repository.Environment;
44  import org.apache.xmlbeans.XmlException;
45  import org.apache.xmlbeans.XmlObject;
46  import org.apache.xmlbeans.XmlOptions;
47  
48  /**
49   * @version $Rev: 470597 $ $Date: 2006-11-02 15:30:55 -0800 (Thu, 02 Nov 2006) $
50   */
51  public class EnvironmentBuilder extends PropertyEditorSupport implements XmlAttributeBuilder {
52      private final static QName QNAME = EnvironmentDocument.type.getDocumentElementName();
53      private final static String NAMESPACE = QNAME.getNamespaceURI();
54  
55      public static Environment buildEnvironment(EnvironmentType environmentType) {
56          Environment environment = new Environment();
57          if (environmentType != null) {
58              if (environmentType.isSetModuleId()) {
59                  environment.setConfigId(toArtifact(environmentType.getModuleId(), null));
60              }
61  
62              if (environmentType.isSetDependencies()) {
63                  DependencyType[] dependencyArray = environmentType.getDependencies().getDependencyArray();
64                  LinkedHashSet dependencies = toDependencies(dependencyArray);
65                  environment.setDependencies(dependencies);
66              }
67              environment.setInverseClassLoading(environmentType.isSetInverseClassloading());
68              environment.setSuppressDefaultEnvironment(environmentType.isSetSuppressDefaultEnvironment());
69              environment.setHiddenClasses(toFilters(environmentType.getHiddenClasses()));
70              environment.setNonOverrideableClasses(toFilters(environmentType.getNonOverridableClasses()));
71          }
72  
73          return environment;
74      }
75  
76      public static void mergeEnvironments(Environment environment, Environment additionalEnvironment) {
77          if (additionalEnvironment != null) {
78              //TODO merge configIds??
79              if (environment.getConfigId() == null) {
80                  environment.setConfigId(additionalEnvironment.getConfigId());
81              }
82              environment.addDependencies(additionalEnvironment.getDependencies());
83              environment.setInverseClassLoading(environment.isInverseClassLoading() || additionalEnvironment.isInverseClassLoading());
84              environment.setSuppressDefaultEnvironment(environment.isSuppressDefaultEnvironment() || additionalEnvironment.isSuppressDefaultEnvironment());
85              environment.addHiddenClasses(additionalEnvironment.getHiddenClasses());
86              environment.addNonOverrideableClasses(additionalEnvironment.getNonOverrideableClasses());
87          }
88      }
89  
90      public static Environment buildEnvironment(EnvironmentType environmentType, Environment defaultEnvironment) {
91          Environment environment = buildEnvironment(environmentType);
92          if (!environment.isSuppressDefaultEnvironment()) {
93              mergeEnvironments(environment, defaultEnvironment);
94          }
95          return environment;
96      }
97  
98      public static EnvironmentType buildEnvironmentType(Environment environment) {
99          EnvironmentType environmentType = EnvironmentType.Factory.newInstance();
100         if (environment.getConfigId() != null) {
101             ArtifactType configId = toArtifactType(environment.getConfigId());
102             environmentType.setModuleId(configId);
103         }
104 
105         List dependencies = toDependencyTypes(environment.getDependencies());
106         DependencyType[] dependencyTypes = (DependencyType[]) dependencies.toArray(new DependencyType[dependencies.size()]);
107         DependenciesType dependenciesType = environmentType.addNewDependencies();
108         dependenciesType.setDependencyArray(dependencyTypes);
109         if (environment.isInverseClassLoading()) {
110             environmentType.addNewInverseClassloading();
111         }
112         if (environment.isSuppressDefaultEnvironment()) {
113             environmentType.addNewSuppressDefaultEnvironment();
114         }
115         environmentType.setHiddenClasses(toFilterType(environment.getHiddenClasses()));
116         environmentType.setNonOverridableClasses(toFilterType(environment.getNonOverrideableClasses()));
117         return environmentType;
118     }
119 
120     private static ClassFilterType toFilterType(Set filters) {
121         String[] classFilters = (String[]) filters.toArray(new String[filters.size()]);
122         ClassFilterType classFilter = ClassFilterType.Factory.newInstance();
123         classFilter.setFilterArray(classFilters);
124         return classFilter;
125     }
126 
127     private static List toDependencyTypes(Collection artifacts) {
128         List dependencies = new ArrayList();
129         for (Iterator iterator = artifacts.iterator(); iterator.hasNext();) {
130             Dependency dependency = (Dependency) iterator.next();
131             ArtifactType artifactType = toDependencyType(dependency);
132             dependencies.add(artifactType);
133         }
134         return dependencies;
135     }
136 
137     private static ArtifactType toArtifactType(Artifact artifact) {
138         ArtifactType artifactType = ArtifactType.Factory.newInstance();
139         fillArtifactType(artifact, artifactType);
140         return artifactType;
141     }
142 
143     private static void fillArtifactType(Artifact artifact, ArtifactType artifactType) {
144         if (artifact.getGroupId() != null) {
145             artifactType.setGroupId(artifact.getGroupId());
146         }
147         if (artifact.getArtifactId() != null) {
148             artifactType.setArtifactId(artifact.getArtifactId());
149         }
150         if (artifact.getVersion() != null) {
151             artifactType.setVersion(artifact.getVersion().toString());
152         }
153         if (artifact.getType() != null) {
154             artifactType.setType(artifact.getType());
155         }
156     }
157 
158     private static DependencyType toDependencyType(Dependency dependency) {
159         DependencyType dependencyType = DependencyType.Factory.newInstance();
160         fillArtifactType(dependency.getArtifact(), dependencyType);
161 
162         org.apache.geronimo.kernel.repository.ImportType importType = dependency.getImportType();
163         if (importType == org.apache.geronimo.kernel.repository.ImportType.CLASSES) {
164             dependencyType.setImport(ImportType.CLASSES);
165         } else if (importType == org.apache.geronimo.kernel.repository.ImportType.SERVICES) {
166             dependencyType.setImport(ImportType.SERVICES);
167         }
168 
169         return dependencyType;
170     }
171 
172     private static Set toFilters(ClassFilterType filterType) {
173         Set filters = new HashSet();
174         if (filterType != null) {
175             String[] filterArray = filterType.getFilterArray();
176             for (int i = 0; i < filterArray.length; i++) {
177                 String filter = filterArray[i].trim();
178                 filters.add(filter);
179             }
180         }
181         return filters;
182     }
183 
184     //package level for testing
185     static LinkedHashSet toArtifacts(ArtifactType[] artifactTypes) {
186         LinkedHashSet artifacts = new LinkedHashSet();
187         for (int i = 0; i < artifactTypes.length; i++) {
188             ArtifactType artifactType = artifactTypes[i];
189             Artifact artifact = toArtifact(artifactType, "jar");
190             artifacts.add(artifact);
191         }
192         return artifacts;
193     }
194 
195     private static LinkedHashSet toDependencies(DependencyType[] dependencyArray) {
196         LinkedHashSet dependencies = new LinkedHashSet();
197         for (int i = 0; i < dependencyArray.length; i++) {
198             DependencyType artifactType = dependencyArray[i];
199             Dependency dependency = toDependency(artifactType);
200             dependencies.add(dependency);
201         }
202         return dependencies;
203     }
204 
205     private static Dependency toDependency(DependencyType dependencyType) {
206         Artifact artifact = toArtifact(dependencyType, null);
207         if (ImportType.CLASSES.equals(dependencyType.getImport())) {
208             return new Dependency(artifact, org.apache.geronimo.kernel.repository.ImportType.CLASSES);
209         } else if (ImportType.SERVICES.equals(dependencyType.getImport())) {
210             return new Dependency(artifact, org.apache.geronimo.kernel.repository.ImportType.SERVICES);
211         } else if (dependencyType.getImport() == null) {
212             return new Dependency(artifact, org.apache.geronimo.kernel.repository.ImportType.ALL);
213         } else {
214             throw new IllegalArgumentException("Unknown import type: " + dependencyType.getImport());
215         }
216     }
217 
218     private static Artifact toArtifact(ArtifactType artifactType, String defaultType) {
219         String groupId = artifactType.isSetGroupId() ? trim(artifactType.getGroupId()) : null;
220         String type = artifactType.isSetType() ? trim(artifactType.getType()) : defaultType;
221         String artifactId = trim(artifactType.getArtifactId());
222         String version = artifactType.isSetVersion() ? trim(artifactType.getVersion()) : null;
223         return new Artifact(groupId, artifactId, version, type);
224     }
225 
226     private static String trim(String string) {
227         if (string == null || string.length() == 0) {
228         return null;
229         }
230         return string.trim();
231     }
232 
233 
234     public String getNamespace() {
235         return NAMESPACE;
236     }
237 
238     public Object getValue(XmlObject xmlObject, String type, ClassLoader cl) throws DeploymentException {
239 
240         EnvironmentType environmentType;
241         if (xmlObject instanceof EnvironmentType) {
242             environmentType = (EnvironmentType) xmlObject;
243         } else {
244             environmentType = (EnvironmentType) xmlObject.copy().changeType(EnvironmentType.type);
245         }
246         try {
247             XmlOptions xmlOptions = new XmlOptions();
248             xmlOptions.setLoadLineNumbers();
249             Collection errors = new ArrayList();
250             xmlOptions.setErrorListener(errors);
251             if (!environmentType.validate(xmlOptions)) {
252                 throw new XmlException("Invalid deployment descriptor: " + errors + "\nDescriptor: " + environmentType.toString(), null, errors);
253             }
254         } catch (XmlException e) {
255             throw new DeploymentException(e);
256         }
257 
258         return buildEnvironment(environmentType);
259     }
260 
261     public String getAsText() {
262         Environment environment = (Environment) getValue();
263         EnvironmentType environmentType = buildEnvironmentType(environment);
264         XmlOptions xmlOptions = new XmlOptions();
265         xmlOptions.setSaveSyntheticDocumentElement(QNAME);
266         xmlOptions.setSavePrettyPrint();
267         return environmentType.xmlText(xmlOptions);
268     }
269 
270     public void setAsText(String text) {
271         try {
272             EnvironmentDocument environmentDocument = EnvironmentDocument.Factory.parse(text);
273             EnvironmentType environmentType = environmentDocument.getEnvironment();
274             Environment environment = (Environment) getValue(environmentType, null, null);
275             setValue(environment);
276 
277         } catch (XmlException e) {
278             throw new PropertyEditorException(e);
279         } catch (DeploymentException e) {
280             throw new PropertyEditorException(e);
281         }
282     }
283 
284 
285     //This is added by hand to the xmlAttributeBuilders since it is needed to bootstrap the ServiceConfigBuilder.
286 }