1 /**
2 *
3 * Copyright 2005 The Apache Software Foundation
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18 package org.apache.geronimo.plugin.car;
19
20 import java.io.File;
21 import java.io.StringWriter;
22 import java.util.HashMap;
23 import java.util.Iterator;
24 import java.util.LinkedHashSet;
25 import java.util.List;
26 import java.util.Map;
27 import java.util.Properties;
28
29 import javax.xml.namespace.QName;
30
31 import org.apache.geronimo.deployment.service.EnvironmentBuilder;
32 import org.apache.geronimo.deployment.xbeans.ArtifactType;
33 import org.apache.geronimo.deployment.xbeans.EnvironmentType;
34 import org.apache.geronimo.kernel.repository.Environment;
35 import org.apache.geronimo.kernel.repository.Artifact;
36 import org.apache.geronimo.kernel.repository.ImportType;
37
38 import org.apache.maven.model.Dependency;
39
40 import org.apache.velocity.Template;
41 import org.apache.velocity.VelocityContext;
42 import org.apache.velocity.app.VelocityEngine;
43
44 import org.apache.xmlbeans.XmlCursor;
45 import org.apache.xmlbeans.XmlObject;
46 import org.apache.xmlbeans.XmlOptions;
47
48
49
50
51
52 /**
53 * Add dependencies to a plan and process with velocity
54 *
55 * @goal prepare-plan
56 *
57 * @version $Rev: 434144 $ $Date: 2006-08-23 21:56:43 +0200 (mer., 23 août 2006) $
58 */
59 public class PlanProcessorMojo
60 extends AbstractCarMojo
61 {
62 private static final String ENVIRONMENT_LOCAL_NAME = "environment";
63
64 private static final QName ENVIRONMENT_QNAME = new QName("http://geronimo.apache.org/xml/ns/deployment-1.1", ENVIRONMENT_LOCAL_NAME);
65
66 /**
67 * @parameter expression="${basedir}/src/plan"
68 * @required
69 */
70 private File sourceDir;
71
72 /**
73 * @parameter expression="${project.build.directory}/plan"
74 * @required
75 */
76 private File targetDir;
77
78 /**
79 * @parameter default-value="plan.xml"
80 * @required
81 */
82 private String planFileName;
83
84 /**
85 * @parameter expression="${project.build.directory}/plan/plan.xml"
86 * @required
87 */
88 private File targetFile;
89
90 /**
91 * @parameter expression="1.2"
92 * @required
93 */
94 private String geronimoVersion;
95
96 private VelocityContext createContext() {
97 VelocityContext context = new VelocityContext();
98
99
100 Properties props = project.getProperties();
101 for (Iterator iter = props.keySet().iterator(); iter.hasNext();) {
102 String key = (String) iter.next();
103 String value = props.getProperty(key);
104
105 log.debug("Setting " + key + "=" + value);
106 context.put(key, value);
107 }
108
109 context.put("pom", project);
110
111 return context;
112 }
113
114 protected void doExecute() throws Exception {
115
116
117
118
119
120
121 VelocityContext context = createContext();
122
123 VelocityEngine velocity = new VelocityEngine();
124 velocity.setProperty(VelocityEngine.FILE_RESOURCE_LOADER_PATH, sourceDir.getAbsolutePath());
125 velocity.init();
126
127 Template template = velocity.getTemplate(planFileName);
128 StringWriter writer = new StringWriter();
129 template.merge(context, writer);
130
131 String plan = writer.toString();
132
133 XmlObject doc = XmlObject.Factory.parse(plan);
134 XmlCursor xmlCursor = doc.newCursor();
135 LinkedHashSet dependencies = toDependencies();
136 Artifact configId = new Artifact(project.getGroupId(), project.getArtifactId(), project.getVersion(), "car");
137
138 try {
139 mergeEnvironment(xmlCursor, configId, dependencies);
140
141 if (targetDir.exists()) {
142 if (!targetDir.isDirectory()) {
143 throw new RuntimeException("TargetDir: " + this.targetDir + " exists and is not a directory");
144 }
145 }
146 else {
147 targetDir.mkdirs();
148 }
149
150 XmlOptions xmlOptions = new XmlOptions();
151 xmlOptions.setSavePrettyPrint();
152 doc.save(targetFile, xmlOptions);
153
154 log.info("Generated: " + targetFile);
155 }
156 finally {
157 xmlCursor.dispose();
158 }
159 }
160
161 void mergeEnvironment(final XmlCursor xmlCursor, final Artifact configId, final LinkedHashSet dependencies) {
162 xmlCursor.toFirstContentToken();
163 xmlCursor.toFirstChild();
164 QName childName = xmlCursor.getName();
165 Environment oldEnvironment;
166
167 if (childName != null && childName.getLocalPart().equals(ENVIRONMENT_LOCAL_NAME)) {
168 convertElement(xmlCursor, ENVIRONMENT_QNAME.getNamespaceURI());
169 XmlObject xmlObject = xmlCursor.getObject();
170 EnvironmentType environmentType = (EnvironmentType) xmlObject.copy().changeType(EnvironmentType.type);
171 oldEnvironment = EnvironmentBuilder.buildEnvironment(environmentType);
172 xmlCursor.removeXml();
173 }
174 else {
175 oldEnvironment = new Environment();
176 }
177
178 Environment newEnvironment = new Environment();
179 newEnvironment.setConfigId(configId);
180 newEnvironment.setDependencies(dependencies);
181
182 EnvironmentBuilder.mergeEnvironments(oldEnvironment, newEnvironment);
183 EnvironmentType environmentType = EnvironmentBuilder.buildEnvironmentType(oldEnvironment);
184
185 xmlCursor.beginElement(ENVIRONMENT_QNAME);
186 XmlCursor element = environmentType.newCursor();
187
188 try {
189 element.copyXmlContents(xmlCursor);
190 }
191 finally {
192 element.dispose();
193 }
194 }
195
196 private void convertElement(final XmlCursor cursor, final String namespace) {
197 cursor.push();
198 XmlCursor end = cursor.newCursor();
199
200 try {
201 end.toCursor(cursor);
202 end.toEndToken();
203
204 while (cursor.hasNextToken() && cursor.isLeftOf(end)) {
205 if (cursor.isStart()) {
206 if (!namespace.equals(cursor.getName().getNamespaceURI())) {
207 cursor.setName(new QName(namespace, cursor.getName().getLocalPart()));
208 }
209 }
210
211 cursor.toNextToken();
212 }
213
214 cursor.pop();
215 }
216 finally {
217 end.dispose();
218 }
219 }
220
221 private LinkedHashSet toDependencies() {
222 List artifacts = project.getDependencies();
223 LinkedHashSet dependencies = new LinkedHashSet();
224
225 Iterator iter = artifacts.iterator();
226 while (iter.hasNext()) {
227 Dependency dependency = (Dependency) iter.next();
228
229
230
231
232
233
234 if (dependency.getGroupId().startsWith("org.apache.geronimo.genesis")) {
235 continue;
236 }
237
238 org.apache.geronimo.kernel.repository.Dependency gdep = toGeronimoDependency(dependency);
239 if (gdep != null) {
240 dependencies.add(gdep);
241 }
242 }
243
244 return dependencies;
245 }
246
247 private static org.apache.geronimo.kernel.repository.Dependency toGeronimoDependency(final Dependency dependency) {
248 Artifact artifact = toGeronimoArtifact(dependency);
249 String type = dependency.getType();
250 String scope = dependency.getScope();
251 String groupId = dependency.getGroupId();
252
253
254 if ("jar".equalsIgnoreCase(type) && !"junit".equals(groupId) && (scope == null || !scope.equals("provided"))) {
255 if (dependency.getVersion() != null) {
256 artifact = new Artifact(
257 artifact.getGroupId(),
258 artifact.getArtifactId(),
259 dependency.getVersion(),
260 artifact.getType());
261 }
262 return new org.apache.geronimo.kernel.repository.Dependency(artifact, ImportType.CLASSES);
263 }
264 else if ("car".equalsIgnoreCase(type) && ("runtime").equalsIgnoreCase(scope)) {
265 return new org.apache.geronimo.kernel.repository.Dependency(artifact, ImportType.SERVICES);
266 }
267 else if ("car".equalsIgnoreCase(type) && ("compile".equalsIgnoreCase(scope))) {
268 return new org.apache.geronimo.kernel.repository.Dependency(artifact, ImportType.CLASSES);
269 }
270 else if ("car".equalsIgnoreCase(type) && (scope == null)) {
271 return new org.apache.geronimo.kernel.repository.Dependency(artifact, ImportType.ALL);
272 }
273 else {
274
275 return null;
276 }
277 }
278
279 private static Artifact toGeronimoArtifact(final Dependency dependency) {
280 String groupId = dependency.getGroupId();
281 String artifactId = dependency.getArtifactId();
282 String version = null;
283 String type = dependency.getType();
284
285 return new Artifact(groupId, artifactId, version, type);
286 }
287
288 interface Inserter {
289 ArtifactType insert(EnvironmentType environmentType);
290 }
291 }