001 /** 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 018 package org.apache.geronimo.deployment.service; 019 020 import java.beans.PropertyEditorSupport; 021 import java.util.ArrayList; 022 import java.util.Collection; 023 import java.util.HashSet; 024 import java.util.Iterator; 025 import java.util.LinkedHashSet; 026 import java.util.List; 027 import java.util.Set; 028 029 import javax.xml.namespace.QName; 030 031 import org.apache.geronimo.common.DeploymentException; 032 import org.apache.geronimo.common.propertyeditor.PropertyEditorException; 033 import org.apache.geronimo.deployment.xbeans.ArtifactType; 034 import org.apache.geronimo.deployment.xbeans.ClassFilterType; 035 import org.apache.geronimo.deployment.xbeans.DependenciesType; 036 import org.apache.geronimo.deployment.xbeans.EnvironmentDocument; 037 import org.apache.geronimo.deployment.xbeans.EnvironmentType; 038 import org.apache.geronimo.deployment.xbeans.ImportType; 039 import org.apache.geronimo.deployment.xbeans.DependencyType; 040 import org.apache.geronimo.kernel.repository.Artifact; 041 import org.apache.geronimo.kernel.repository.Dependency; 042 import org.apache.geronimo.kernel.repository.Environment; 043 import org.apache.xmlbeans.XmlException; 044 import org.apache.xmlbeans.XmlObject; 045 import org.apache.xmlbeans.XmlOptions; 046 047 /** 048 * @version $Rev: 476049 $ $Date: 2006-11-16 23:35:17 -0500 (Thu, 16 Nov 2006) $ 049 */ 050 public class EnvironmentBuilder extends PropertyEditorSupport implements XmlAttributeBuilder { 051 private final static QName QNAME = EnvironmentDocument.type.getDocumentElementName(); 052 private final static String NAMESPACE = QNAME.getNamespaceURI(); 053 054 public static Environment buildEnvironment(EnvironmentType environmentType) { 055 Environment environment = new Environment(); 056 if (environmentType != null) { 057 if (environmentType.isSetModuleId()) { 058 environment.setConfigId(toArtifact(environmentType.getModuleId(), null)); 059 } 060 061 if (environmentType.isSetDependencies()) { 062 DependencyType[] dependencyArray = environmentType.getDependencies().getDependencyArray(); 063 LinkedHashSet dependencies = toDependencies(dependencyArray); 064 environment.setDependencies(dependencies); 065 } 066 environment.setInverseClassLoading(environmentType.isSetInverseClassloading()); 067 environment.setSuppressDefaultEnvironment(environmentType.isSetSuppressDefaultEnvironment()); 068 environment.setHiddenClasses(toFilters(environmentType.getHiddenClasses())); 069 environment.setNonOverrideableClasses(toFilters(environmentType.getNonOverridableClasses())); 070 } 071 072 return environment; 073 } 074 075 public static void mergeEnvironments(Environment environment, Environment additionalEnvironment) { 076 if (additionalEnvironment != null) { 077 //TODO merge configIds?? 078 if (environment.getConfigId() == null) { 079 environment.setConfigId(additionalEnvironment.getConfigId()); 080 } 081 environment.addDependencies(additionalEnvironment.getDependencies()); 082 environment.setInverseClassLoading(environment.isInverseClassLoading() || additionalEnvironment.isInverseClassLoading()); 083 environment.setSuppressDefaultEnvironment(environment.isSuppressDefaultEnvironment() || additionalEnvironment.isSuppressDefaultEnvironment()); 084 environment.addHiddenClasses(additionalEnvironment.getHiddenClasses()); 085 environment.addNonOverrideableClasses(additionalEnvironment.getNonOverrideableClasses()); 086 } 087 } 088 089 public static Environment buildEnvironment(EnvironmentType environmentType, Environment defaultEnvironment) { 090 Environment environment = buildEnvironment(environmentType); 091 if (!environment.isSuppressDefaultEnvironment()) { 092 mergeEnvironments(environment, defaultEnvironment); 093 } 094 return environment; 095 } 096 097 public static EnvironmentType buildEnvironmentType(Environment environment) { 098 EnvironmentType environmentType = EnvironmentType.Factory.newInstance(); 099 if (environment.getConfigId() != null) { 100 ArtifactType configId = toArtifactType(environment.getConfigId()); 101 environmentType.setModuleId(configId); 102 } 103 104 List dependencies = toDependencyTypes(environment.getDependencies()); 105 DependencyType[] dependencyTypes = (DependencyType[]) dependencies.toArray(new DependencyType[dependencies.size()]); 106 DependenciesType dependenciesType = environmentType.addNewDependencies(); 107 dependenciesType.setDependencyArray(dependencyTypes); 108 if (environment.isInverseClassLoading()) { 109 environmentType.addNewInverseClassloading(); 110 } 111 if (environment.isSuppressDefaultEnvironment()) { 112 environmentType.addNewSuppressDefaultEnvironment(); 113 } 114 environmentType.setHiddenClasses(toFilterType(environment.getHiddenClasses())); 115 environmentType.setNonOverridableClasses(toFilterType(environment.getNonOverrideableClasses())); 116 return environmentType; 117 } 118 119 private static ClassFilterType toFilterType(Set filters) { 120 String[] classFilters = (String[]) filters.toArray(new String[filters.size()]); 121 ClassFilterType classFilter = ClassFilterType.Factory.newInstance(); 122 classFilter.setFilterArray(classFilters); 123 return classFilter; 124 } 125 126 private static List toDependencyTypes(Collection artifacts) { 127 List dependencies = new ArrayList(); 128 for (Iterator iterator = artifacts.iterator(); iterator.hasNext();) { 129 Dependency dependency = (Dependency) iterator.next(); 130 ArtifactType artifactType = toDependencyType(dependency); 131 dependencies.add(artifactType); 132 } 133 return dependencies; 134 } 135 136 private static ArtifactType toArtifactType(Artifact artifact) { 137 ArtifactType artifactType = ArtifactType.Factory.newInstance(); 138 fillArtifactType(artifact, artifactType); 139 return artifactType; 140 } 141 142 private static void fillArtifactType(Artifact artifact, ArtifactType artifactType) { 143 if (artifact.getGroupId() != null) { 144 artifactType.setGroupId(artifact.getGroupId()); 145 } 146 if (artifact.getArtifactId() != null) { 147 artifactType.setArtifactId(artifact.getArtifactId()); 148 } 149 if (artifact.getVersion() != null) { 150 artifactType.setVersion(artifact.getVersion().toString()); 151 } 152 if (artifact.getType() != null) { 153 artifactType.setType(artifact.getType()); 154 } 155 } 156 157 private static DependencyType toDependencyType(Dependency dependency) { 158 DependencyType dependencyType = DependencyType.Factory.newInstance(); 159 fillArtifactType(dependency.getArtifact(), dependencyType); 160 161 org.apache.geronimo.kernel.repository.ImportType importType = dependency.getImportType(); 162 if (importType == org.apache.geronimo.kernel.repository.ImportType.CLASSES) { 163 dependencyType.setImport(ImportType.CLASSES); 164 } else if (importType == org.apache.geronimo.kernel.repository.ImportType.SERVICES) { 165 dependencyType.setImport(ImportType.SERVICES); 166 } 167 168 return dependencyType; 169 } 170 171 private static Set toFilters(ClassFilterType filterType) { 172 Set filters = new HashSet(); 173 if (filterType != null) { 174 String[] filterArray = filterType.getFilterArray(); 175 for (int i = 0; i < filterArray.length; i++) { 176 String filter = filterArray[i].trim(); 177 filters.add(filter); 178 } 179 } 180 return filters; 181 } 182 183 //package level for testing 184 static LinkedHashSet toArtifacts(ArtifactType[] artifactTypes) { 185 LinkedHashSet artifacts = new LinkedHashSet(); 186 for (int i = 0; i < artifactTypes.length; i++) { 187 ArtifactType artifactType = artifactTypes[i]; 188 Artifact artifact = toArtifact(artifactType, "jar"); 189 artifacts.add(artifact); 190 } 191 return artifacts; 192 } 193 194 private static LinkedHashSet toDependencies(DependencyType[] dependencyArray) { 195 LinkedHashSet dependencies = new LinkedHashSet(); 196 for (int i = 0; i < dependencyArray.length; i++) { 197 DependencyType artifactType = dependencyArray[i]; 198 Dependency dependency = toDependency(artifactType); 199 dependencies.add(dependency); 200 } 201 return dependencies; 202 } 203 204 private static Dependency toDependency(DependencyType dependencyType) { 205 Artifact artifact = toArtifact(dependencyType, null); 206 if (ImportType.CLASSES.equals(dependencyType.getImport())) { 207 return new Dependency(artifact, org.apache.geronimo.kernel.repository.ImportType.CLASSES); 208 } else if (ImportType.SERVICES.equals(dependencyType.getImport())) { 209 return new Dependency(artifact, org.apache.geronimo.kernel.repository.ImportType.SERVICES); 210 } else if (dependencyType.getImport() == null) { 211 return new Dependency(artifact, org.apache.geronimo.kernel.repository.ImportType.ALL); 212 } else { 213 throw new IllegalArgumentException("Unknown import type: " + dependencyType.getImport()); 214 } 215 } 216 217 private static Artifact toArtifact(ArtifactType artifactType, String defaultType) { 218 String groupId = artifactType.isSetGroupId() ? trim(artifactType.getGroupId()) : null; 219 String type = artifactType.isSetType() ? trim(artifactType.getType()) : defaultType; 220 String artifactId = trim(artifactType.getArtifactId()); 221 String version = artifactType.isSetVersion() ? trim(artifactType.getVersion()) : null; 222 return new Artifact(groupId, artifactId, version, type); 223 } 224 225 private static String trim(String string) { 226 if (string == null || string.length() == 0) { 227 return null; 228 } 229 return string.trim(); 230 } 231 232 233 public String getNamespace() { 234 return NAMESPACE; 235 } 236 237 public Object getValue(XmlObject xmlObject, String type, ClassLoader cl) throws DeploymentException { 238 239 EnvironmentType environmentType; 240 if (xmlObject instanceof EnvironmentType) { 241 environmentType = (EnvironmentType) xmlObject; 242 } else { 243 environmentType = (EnvironmentType) xmlObject.copy().changeType(EnvironmentType.type); 244 } 245 try { 246 XmlOptions xmlOptions = new XmlOptions(); 247 xmlOptions.setLoadLineNumbers(); 248 Collection errors = new ArrayList(); 249 xmlOptions.setErrorListener(errors); 250 if (!environmentType.validate(xmlOptions)) { 251 throw new XmlException("Invalid deployment descriptor: " + errors + "\nDescriptor: " + environmentType.toString(), null, errors); 252 } 253 } catch (XmlException e) { 254 throw new DeploymentException(e); 255 } 256 257 return buildEnvironment(environmentType); 258 } 259 260 public String getAsText() { 261 Environment environment = (Environment) getValue(); 262 EnvironmentType environmentType = buildEnvironmentType(environment); 263 XmlOptions xmlOptions = new XmlOptions(); 264 xmlOptions.setSaveSyntheticDocumentElement(QNAME); 265 xmlOptions.setSavePrettyPrint(); 266 return environmentType.xmlText(xmlOptions); 267 } 268 269 public void setAsText(String text) { 270 try { 271 EnvironmentDocument environmentDocument = EnvironmentDocument.Factory.parse(text); 272 EnvironmentType environmentType = environmentDocument.getEnvironment(); 273 Environment environment = (Environment) getValue(environmentType, null, null); 274 setValue(environment); 275 276 } catch (XmlException e) { 277 throw new PropertyEditorException(e); 278 } catch (DeploymentException e) { 279 throw new PropertyEditorException(e); 280 } 281 } 282 283 284 //This is added by hand to the xmlAttributeBuilders since it is needed to bootstrap the ServiceConfigBuilder. 285 }