private void createFullSourcePom(List<Dependency> newDependencies) throws MojoFailureException { // Change spring-test and jmock dependencies to use <optional>true</option> instead of // <scope>test</scope>. // This is necessary because Base*TestCase classes are in src/main/java. If we move these // classes to their // own test module, this will no longer be necessary. For the first version of this mojo, it // seems easier // to follow the convention used in AppFuse rather than creating a test module and changing all // modules to // depend on it. // create properties based on dependencies while we're at it Set<String> projectProperties = new TreeSet<String>(); for (Dependency dep : newDependencies) { if (dep.getArtifactId().equals("spring-test") || dep.getArtifactId().contains("jmock") || dep.getArtifactId().equals("junit") || dep.getArtifactId().equals("shale-test")) { dep.setOptional(true); dep.setScope(null); } String version = dep.getVersion(); // trim off ${} if (version.startsWith("${")) { version = version.substring(2); } if (version.endsWith("}")) { version = version.substring(0, version.length() - 1); } projectProperties.add(version); } // add core as a dependency for modular wars if (project.getPackaging().equals("war") && project.hasParent()) { Dependency core = new Dependency(); core.setGroupId("${project.parent.groupId}"); core.setArtifactId("core"); core.setVersion("${project.parent.version}"); newDependencies.add(core); // workaround for JSF requiring JSP 2.1 - this is a true hack if (project.getProperties().getProperty("web.framework").equals("jsf")) { Dependency jsp21 = new Dependency(); jsp21.setGroupId("javax.servlet.jsp"); jsp21.setArtifactId("jsp-api"); jsp21.setVersion("${jsp.version}"); jsp21.setScope("provided"); newDependencies.add(jsp21); // replace jsp.version property as well project.getOriginalModel().getProperties().setProperty("jsp.version", "2.1"); } } Collections.sort(newDependencies, new BeanComparator("groupId")); project.getOriginalModel().setDependencies(newDependencies); Properties currentProperties = project.getOriginalModel().getProperties(); Set<String> currentKeys = new LinkedHashSet<String>(); for (Object key : currentProperties.keySet()) { currentKeys.add((String) key); } StringBuffer sortedProperties = new StringBuffer(); Properties appfuseProperties = getAppFuseProperties(); // holder for properties - stored in ThreadLocale Map<String, String> propertiesForPom = new LinkedHashMap<String, String>(); for (String key : projectProperties) { // don't add property if it already exists in project if (!currentKeys.contains(key)) { String value = appfuseProperties.getProperty(key); // this happens when the version number is hard-coded if (value == null) { continue; } // hack for Tapestry depending on commons-pool (a.k.a. commons-dbcp 1.2.2) if ("tapestry".equals(project.getProperties().getProperty("web.framework")) && key.equals("commons.dbcp.version")) { value = "1.2.2"; } if (value.contains("&")) { value = "<![CDATA[" + value + "]]>"; } sortedProperties .append(" <") .append(key) .append(">") .append(value) .append("</") .append(key) .append(">" + "\n"); propertiesForPom.put(key, value); } } if (project.getPackaging().equals("pom") || project.hasParent()) { // store sorted properties in a thread local for later retrieval Map<String, String> properties = new LinkedHashMap<String, String>(); if (propertiesContextHolder.get() != null) { properties = (LinkedHashMap) propertiesContextHolder.get(); } for (String key : propertiesForPom.keySet()) { if (!properties.containsKey(key)) { properties.put(key, propertiesForPom.get(key)); } } propertiesContextHolder.set(properties); } StringWriter writer = new StringWriter(); try { project.writeOriginalModel(writer); File pom = new File("pom-fullsource.xml"); if (pom.exists()) { pom.delete(); } FileWriter fw = new FileWriter(pom); fw.write(writer.toString()); fw.flush(); fw.close(); } catch (IOException ex) { getLog().error("Unable to create pom-fullsource.xml: " + ex.getMessage(), ex); throw new MojoFailureException(ex.getMessage()); } log("Updated dependencies in pom.xml..."); // I tried to use regex here, but couldn't get it to work - going with the old fashioned way // instead String pomXml = writer.toString(); int startTag = pomXml.indexOf("\n <dependencies>"); String dependencyXml = pomXml.substring(startTag, pomXml.indexOf("</dependencies>", startTag)); // change 2 spaces to 4 dependencyXml = dependencyXml.replaceAll(" ", " "); dependencyXml = "\n <!-- Dependencies calculated by AppFuse when running full-source plugin -->" + dependencyXml; try { String packaging = project.getPackaging(); String pathToPom = "pom.xml"; if (project.hasParent()) { if (packaging.equals("jar")) { pathToPom = "core/" + pathToPom; } else if (packaging.equals("war")) { pathToPom = "web/" + pathToPom; } } String originalPom = FileUtils.readFileToString(new File(pathToPom), "UTF-8"); // replace tabs with spaces (in case user has changed their pom.xml originalPom = originalPom.replace("\t", " "); startTag = originalPom.indexOf("\n <dependencies>"); StringBuffer sb = new StringBuffer(); sb.append(originalPom.substring(0, startTag)); sb.append(dependencyXml); sb.append(originalPom.substring(originalPom.indexOf("</dependencies>", startTag))); String adjustedPom = sb.toString(); // Calculate properties and add them to pom if not a modular project - otherwise properties // are added // near the end of this method from a threadlocal if (!project.getPackaging().equals("pom") && !project.hasParent()) { adjustedPom = addPropertiesToPom(adjustedPom, sortedProperties); } adjustedPom = adjustLineEndingsForOS(adjustedPom); FileUtils.writeStringToFile( new File(pathToPom), adjustedPom, "UTF-8"); // was pomWithProperties } catch (IOException ex) { getLog().error("Unable to write to pom.xml: " + ex.getMessage(), ex); throw new MojoFailureException(ex.getMessage()); } boolean renamePackages = true; if (System.getProperty("renamePackages") != null) { renamePackages = Boolean.valueOf(System.getProperty("renamePackages")); } if (renamePackages && !project.getPackaging().equals("pom")) { log("Renaming packages to '" + project.getGroupId() + "'..."); RenamePackages renamePackagesTool = new RenamePackages(project.getGroupId()); if (project.hasParent()) { if (project.getPackaging().equals("jar")) { renamePackagesTool.setBaseDir("core/src"); } else { renamePackagesTool.setBaseDir("web/src"); } } renamePackagesTool.execute(); } // when performing full-source on a modular project, add the properties to the root pom.xml at // the end if (project.getPackaging().equals("war") && project.hasParent()) { // store sorted properties in a thread local for later retrieval Map properties = propertiesContextHolder.get(); // alphabetize the properties by key Set<String> propertiesToAdd = new TreeSet<String>(properties.keySet()); StringBuffer calculatedProperties = new StringBuffer(); for (String key : propertiesToAdd) { // don't add property if it already exists in project Set<Object> keysInProject = project.getParent().getOriginalModel().getProperties().keySet(); if (!keysInProject.contains(key)) { String value = getAppFuseProperties().getProperty(key); if (value.contains("&")) { value = "<![CDATA[" + value + "]]>"; } calculatedProperties.append(" <"); calculatedProperties.append(key); calculatedProperties.append(">"); calculatedProperties.append(value); calculatedProperties.append("</"); calculatedProperties.append(key); calculatedProperties.append(">"); calculatedProperties.append("\n"); } } try { String originalPom = FileUtils.readFileToString(new File("pom.xml"), "UTF-8"); // Move modules to build section. originalPom = originalPom.replaceAll(" <modules>", ""); // Because I hate f*****g regex. originalPom = originalPom.replaceAll(" <module>.*?</module>", ""); originalPom = originalPom.replaceAll(" </modules>", ""); originalPom = originalPom.replace( "<repositories>", "<modules>\n" + " <module>core</module>\n" + " <module>web</module>\n" + " </modules>\n\n <repositories>"); String pomWithProperties = addPropertiesToPom(originalPom, calculatedProperties); FileUtils.writeStringToFile(new File("pom.xml"), pomWithProperties, "UTF-8"); } catch (IOException ex) { getLog().error("Unable to read root pom.xml: " + ex.getMessage(), ex); throw new MojoFailureException(ex.getMessage()); } } // cleanup so user isn't aware that files were created File pom = new File("pom-fullsource.xml"); if (pom.exists()) { pom.delete(); } }