1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.geronimo.plugin.car;
21
22 import java.io.File;
23 import java.io.StringWriter;
24
25 import java.util.Iterator;
26 import java.util.LinkedHashSet;
27 import java.util.List;
28 import java.util.Properties;
29
30 import javax.xml.namespace.QName;
31
32 import org.apache.geronimo.deployment.service.EnvironmentBuilder;
33 import org.apache.geronimo.deployment.xbeans.ArtifactType;
34 import org.apache.geronimo.deployment.xbeans.EnvironmentType;
35 import org.apache.geronimo.kernel.repository.Environment;
36 import org.apache.geronimo.kernel.repository.Artifact;
37 import org.apache.geronimo.kernel.repository.ImportType;
38
39 import org.apache.maven.model.Dependency;
40
41 import org.apache.velocity.Template;
42 import org.apache.velocity.VelocityContext;
43 import org.apache.velocity.app.VelocityEngine;
44
45 import org.apache.xmlbeans.XmlCursor;
46 import org.apache.xmlbeans.XmlObject;
47 import org.apache.xmlbeans.XmlOptions;
48 import org.apache.xmlbeans.XmlCursor.TokenType;
49
50
51
52
53
54 /**
55 * Add dependencies to a plan and process with velocity
56 *
57 * @goal prepare-plan
58 *
59 * @version $Rev: 451661 $ $Date: 2006-09-30 13:45:53 -0700 (Sat, 30 Sep 2006) $
60 */
61 public class PlanProcessorMojo
62 extends AbstractCarMojo
63 {
64 private static final String ENVIRONMENT_LOCAL_NAME = "environment";
65
66 private static final QName ENVIRONMENT_QNAME = new QName("http://geronimo.apache.org/xml/ns/deployment-1.2", "environment");
67
68 /**
69 * @parameter expression="${basedir}/src/plan"
70 * @required
71 */
72 protected File sourceDir = null;
73
74 /**
75 * @parameter expression="${project.build.directory}/plan"
76 * @required
77 */
78 protected File targetDir = null;
79
80 /**
81 * @parameter default-value="plan.xml"
82 * @required
83 */
84 protected String planFileName = null;
85
86 /**
87 * @parameter expression="${project.build.directory}/plan/plan.xml"
88 * @required
89 */
90 protected File targetFile = null;
91
92 private VelocityContext createContext() {
93 VelocityContext context = new VelocityContext();
94
95
96 Properties props = project.getProperties();
97 for (Iterator iter = props.keySet().iterator(); iter.hasNext();) {
98 String key = (String) iter.next();
99 String value = props.getProperty(key);
100
101 log.debug("Setting " + key + "=" + value);
102 context.put(key, value);
103 }
104
105 context.put("pom", project);
106
107 return context;
108 }
109
110 protected void doExecute() throws Exception {
111
112
113
114
115
116
117 VelocityContext context = createContext();
118
119 VelocityEngine velocity = new VelocityEngine();
120 velocity.setProperty(VelocityEngine.FILE_RESOURCE_LOADER_PATH, sourceDir.getAbsolutePath());
121 velocity.init();
122
123 Template template = velocity.getTemplate(planFileName);
124 StringWriter writer = new StringWriter();
125 template.merge(context, writer);
126
127 String plan = writer.toString();
128
129 XmlObject doc = XmlObject.Factory.parse(plan);
130 XmlCursor xmlCursor = doc.newCursor();
131 LinkedHashSet dependencies = toDependencies();
132 Artifact configId = new Artifact(project.getGroupId(), project.getArtifactId(), project.getVersion(), "car");
133
134 try {
135 mergeEnvironment(xmlCursor, configId, dependencies);
136
137 if (targetDir.exists()) {
138 if (!targetDir.isDirectory()) {
139 throw new RuntimeException("TargetDir: " + this.targetDir + " exists and is not a directory");
140 }
141 }
142 else {
143 targetDir.mkdirs();
144 }
145
146 XmlOptions xmlOptions = new XmlOptions();
147 xmlOptions.setSavePrettyPrint();
148 doc.save(targetFile, xmlOptions);
149
150 log.info("Generated: " + targetFile);
151 }
152 finally {
153 xmlCursor.dispose();
154 }
155 }
156
157 void mergeEnvironment(final XmlCursor xmlCursor, final Artifact configId, final LinkedHashSet dependencies) {
158 moveToFirstStartElement(xmlCursor);
159
160 boolean atLeastOneChild = xmlCursor.toFirstChild();
161 if (!atLeastOneChild) {
162
163 xmlCursor.toEndToken();
164 }
165 QName childName = xmlCursor.getName();
166 Environment oldEnvironment;
167
168 if (childName != null && childName.getLocalPart().equals(ENVIRONMENT_LOCAL_NAME)) {
169 convertElement(xmlCursor, ENVIRONMENT_QNAME.getNamespaceURI());
170 XmlObject xmlObject = xmlCursor.getObject();
171 EnvironmentType environmentType = (EnvironmentType) xmlObject.copy().changeType(EnvironmentType.type);
172 oldEnvironment = EnvironmentBuilder.buildEnvironment(environmentType);
173 xmlCursor.removeXml();
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 moveToFirstStartElement(XmlCursor xmlCursor) throws AssertionError {
197 xmlCursor.toStartDoc();
198 xmlCursor.toFirstChild();
199 while (!xmlCursor.currentTokenType().isStart()) {
200 if (!xmlCursor.toNextSibling()) {
201 break;
202 }
203 }
204 if (!xmlCursor.currentTokenType().isStart()) {
205 throw new AssertionError("Cannot find first start element");
206 }
207 }
208
209 private void convertElement(final XmlCursor cursor, final String namespace) {
210 cursor.push();
211 XmlCursor end = cursor.newCursor();
212
213 try {
214 end.toCursor(cursor);
215 end.toEndToken();
216
217 while (cursor.hasNextToken() && cursor.isLeftOf(end)) {
218 if (cursor.isStart()) {
219 if (!namespace.equals(cursor.getName().getNamespaceURI())) {
220 cursor.setName(new QName(namespace, cursor.getName().getLocalPart()));
221 }
222 }
223
224 cursor.toNextToken();
225 }
226
227 cursor.pop();
228 }
229 finally {
230 end.dispose();
231 }
232 }
233
234 private LinkedHashSet toDependencies() {
235 List artifacts = project.getDependencies();
236 LinkedHashSet dependencies = new LinkedHashSet();
237
238 Iterator iter = artifacts.iterator();
239 while (iter.hasNext()) {
240 Dependency dependency = (Dependency) iter.next();
241
242
243
244
245
246
247 if (dependency.getGroupId().startsWith("org.apache.geronimo.genesis")) {
248 continue;
249 }
250
251 org.apache.geronimo.kernel.repository.Dependency gdep = toGeronimoDependency(dependency);
252 if (gdep != null) {
253 dependencies.add(gdep);
254 }
255 }
256
257 return dependencies;
258 }
259
260 private static org.apache.geronimo.kernel.repository.Dependency toGeronimoDependency(final Dependency dependency) {
261 Artifact artifact = toGeronimoArtifact(dependency);
262 String type = dependency.getType();
263 String scope = dependency.getScope();
264 String groupId = dependency.getGroupId();
265
266
267 if ("jar".equalsIgnoreCase(type) && !"junit".equals(groupId) && (scope == null || !scope.equals("provided"))) {
268 if (dependency.getVersion() != null) {
269 artifact = new Artifact(
270 artifact.getGroupId(),
271 artifact.getArtifactId(),
272 dependency.getVersion(),
273 artifact.getType());
274 }
275 return new org.apache.geronimo.kernel.repository.Dependency(artifact, ImportType.CLASSES);
276 }
277 else if ("car".equalsIgnoreCase(type) && ("runtime").equalsIgnoreCase(scope)) {
278 return new org.apache.geronimo.kernel.repository.Dependency(artifact, ImportType.SERVICES);
279 }
280 else if ("car".equalsIgnoreCase(type) && ("compile".equalsIgnoreCase(scope))) {
281 return new org.apache.geronimo.kernel.repository.Dependency(artifact, ImportType.CLASSES);
282 }
283 else if ("car".equalsIgnoreCase(type) && (scope == null)) {
284 return new org.apache.geronimo.kernel.repository.Dependency(artifact, ImportType.ALL);
285 }
286 else {
287
288 return null;
289 }
290 }
291
292 private static Artifact toGeronimoArtifact(final Dependency dependency) {
293 String groupId = dependency.getGroupId();
294 String artifactId = dependency.getArtifactId();
295 String version = null;
296 String type = dependency.getType();
297
298 return new Artifact(groupId, artifactId, version, type);
299 }
300
301 interface Inserter {
302 ArtifactType insert(EnvironmentType environmentType);
303 }
304 }