001 /** 002 * 003 * Licensed to the Apache Software Foundation (ASF) under one or more 004 * contributor license agreements. See the NOTICE file distributed with 005 * this work for additional information regarding copyright ownership. 006 * The ASF licenses this file to You under the Apache License, Version 2.0 007 * (the "License"); you may not use this file except in compliance with 008 * the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018 019 package org.apache.geronimo.deployment.service; 020 021 import java.beans.PropertyEditorSupport; 022 import java.util.ArrayList; 023 import java.util.Collection; 024 import java.util.HashSet; 025 import java.util.Iterator; 026 import java.util.LinkedHashSet; 027 import java.util.List; 028 import java.util.Set; 029 030 import javax.xml.namespace.QName; 031 032 import org.apache.geronimo.common.DeploymentException; 033 import org.apache.geronimo.common.propertyeditor.PropertyEditorException; 034 import org.apache.geronimo.deployment.xbeans.ArtifactType; 035 import org.apache.geronimo.deployment.xbeans.ClassFilterType; 036 import org.apache.geronimo.deployment.xbeans.DependenciesType; 037 import org.apache.geronimo.deployment.xbeans.EnvironmentDocument; 038 import org.apache.geronimo.deployment.xbeans.EnvironmentType; 039 import org.apache.geronimo.deployment.xbeans.ImportType; 040 import org.apache.geronimo.deployment.xbeans.DependencyType; 041 import org.apache.geronimo.kernel.repository.Artifact; 042 import org.apache.geronimo.kernel.repository.Dependency; 043 import org.apache.geronimo.kernel.repository.Environment; 044 import org.apache.xmlbeans.XmlException; 045 import org.apache.xmlbeans.XmlObject; 046 import org.apache.xmlbeans.XmlOptions; 047 048 /** 049 * @version $Rev: 470597 $ $Date: 2006-11-02 15:30:55 -0800 (Thu, 02 Nov 2006) $ 050 */ 051 public class EnvironmentBuilder extends PropertyEditorSupport implements XmlAttributeBuilder { 052 private final static QName QNAME = EnvironmentDocument.type.getDocumentElementName(); 053 private final static String NAMESPACE = QNAME.getNamespaceURI(); 054 055 public static Environment buildEnvironment(EnvironmentType environmentType) { 056 Environment environment = new Environment(); 057 if (environmentType != null) { 058 if (environmentType.isSetModuleId()) { 059 environment.setConfigId(toArtifact(environmentType.getModuleId(), null)); 060 } 061 062 if (environmentType.isSetDependencies()) { 063 DependencyType[] dependencyArray = environmentType.getDependencies().getDependencyArray(); 064 LinkedHashSet dependencies = toDependencies(dependencyArray); 065 environment.setDependencies(dependencies); 066 } 067 environment.setInverseClassLoading(environmentType.isSetInverseClassloading()); 068 environment.setSuppressDefaultEnvironment(environmentType.isSetSuppressDefaultEnvironment()); 069 environment.setHiddenClasses(toFilters(environmentType.getHiddenClasses())); 070 environment.setNonOverrideableClasses(toFilters(environmentType.getNonOverridableClasses())); 071 } 072 073 return environment; 074 } 075 076 public static void mergeEnvironments(Environment environment, Environment additionalEnvironment) { 077 if (additionalEnvironment != null) { 078 //TODO merge configIds?? 079 if (environment.getConfigId() == null) { 080 environment.setConfigId(additionalEnvironment.getConfigId()); 081 } 082 environment.addDependencies(additionalEnvironment.getDependencies()); 083 environment.setInverseClassLoading(environment.isInverseClassLoading() || additionalEnvironment.isInverseClassLoading()); 084 environment.setSuppressDefaultEnvironment(environment.isSuppressDefaultEnvironment() || additionalEnvironment.isSuppressDefaultEnvironment()); 085 environment.addHiddenClasses(additionalEnvironment.getHiddenClasses()); 086 environment.addNonOverrideableClasses(additionalEnvironment.getNonOverrideableClasses()); 087 } 088 } 089 090 public static Environment buildEnvironment(EnvironmentType environmentType, Environment defaultEnvironment) { 091 Environment environment = buildEnvironment(environmentType); 092 if (!environment.isSuppressDefaultEnvironment()) { 093 mergeEnvironments(environment, defaultEnvironment); 094 } 095 return environment; 096 } 097 098 public static EnvironmentType buildEnvironmentType(Environment environment) { 099 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 }