/******************************************************************************* * Copyright (c) 2008 Red Hat, Inc. * Distributed under license by Red Hat, Inc. All rights reserved. * This program is made available under the terms of the * Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ package org.jboss.tools.seam.internal.core.project.facet; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.util.HashSet; import java.util.Properties; import java.util.Set; import org.apache.tools.ant.types.FilterSet; import org.apache.tools.ant.types.FilterSetCollection; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IFolder; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.Path; import org.eclipse.wst.common.componentcore.ComponentCore; import org.eclipse.wst.common.componentcore.resources.IVirtualComponent; import org.eclipse.wst.common.componentcore.resources.IVirtualFolder; import org.eclipse.wst.common.frameworks.datamodel.IDataModel; import org.eclipse.wst.sse.core.StructuredModelManager; import org.eclipse.wst.sse.core.internal.provisional.IModelManager; import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel; import org.eclipse.wst.xml.core.internal.provisional.document.IDOMDocument; import org.eclipse.wst.xml.core.internal.provisional.document.IDOMModel; import org.eclipse.wst.xml.core.internal.provisional.format.FormatProcessorXML; import org.jboss.tools.seam.core.SeamCorePlugin; import org.jboss.tools.seam.core.project.facet.SeamVersion; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.w3c.dom.Text; /** * @author Alexey Kazakov * This class helps New Seam Wizard Page to create EJB, EAR and test projects for seam 2.* WAR project. */ public class Seam2ProjectCreator extends SeamProjectCreator { private static final String STRICT = "strict"; private static final String MODULE_ORDER = "module-order"; // test/*.jar are duplicated here since the filtering seem to be assymetric when matching private static AntCopyUtils.FileSet JBOSS_TEST_LIB_FILESET = new AntCopyUtils.FileSet() .include("testng.*\\.jar") //$NON-NLS-1$ .include("test/hibernate-all\\.jar") //$NON-NLS-1$ .include("hibernate-all\\.jar") //$NON-NLS-1$ .include("test/jboss-embedded-all.jar") //$NON-NLS-1$ .include("jboss-embedded-all.jar") //$NON-NLS-1$ .include("test/jboss-embedded-api.jar") //$NON-NLS-1$ .include("jboss-embedded-api.jar") //$NON-NLS-1$ .include("test/jboss-deployers.jar") //$NON-NLS-1$ .include("jboss-deployers.jar") //$NON-NLS-1$ .include("test/thirdparty-all\\.jar") //$NON-NLS-1$ .include("thirdparty-all\\.jar") //$NON-NLS-1$ .include("core.*\\.jar") //$NON-NLS-1$ .include("ecj.*\\.jar") //$NON-NLS-1$ .exclude(".*/CVS") //$NON-NLS-1$ .exclude(".*/\\.svn"); //$NON-NLS-1$ /** * @param model Seam facet data model * @param seamWebProject Seam web project */ public Seam2ProjectCreator(IDataModel model, IProject seamWebProject, SeamLibFileSetProvider seamLibFileSetProvider) { super(model, seamWebProject, seamLibFileSetProvider); viewFilterSetCollection.addFilterSet(SeamFacetFilterSetFactory.createHibernateDialectFilterSet(model)); droolsLibFolder = new File(seamHomePath, Seam2FacetInstallDelegate.DROOLS_LIB_SEAM_RELATED_PATH); } /* * (non-Javadoc) * @see org.jboss.tools.seam.internal.core.project.facet.SeamProjectCreator#createEarProject() */ @Override protected void createEarProject() { super.createEarProject(); if (!SeamCorePlugin.getDefault().hasM2Facet(seamWebProject) && shouldCopyLibrariesAndTemplates(model) && shouldCopyLibraries(model)) { File earContentsFolder = new File(earProjectFolder, "EarContent"); //$NON-NLS-1$ File earLibFolder = new File(earContentsFolder, "lib"); //$NON-NLS-1$ AntCopyUtils.copyFiles(seamLibFolder, earLibFolder, new AntCopyUtils.FileSetFileFilter(new AntCopyUtils.FileSet(seamLibFileSetProvider.getEarLibFileSet()).dir(seamLibFolder))); } } @Override protected boolean createTestProject() { if(!(Boolean)model.getProperty(ISeamFacetDataModelProperties.TEST_PROJECT_CREATING) || !shouldCopyLibrariesAndTemplates(model)) return false; File testProjectDir = new File(seamWebProject.getLocation().removeLastSegments(1).toFile(), testProjectName); //$NON-NLS-1$ testProjectDir.mkdir(); IVirtualComponent component = ComponentCore.createComponent(seamWebProject); IVirtualFolder webRootVirtFolder = component.getRootFolder().getFolder(new Path("/")); //$NON-NLS-1$ File testLibDir = new File(testProjectDir,"lib"); //$NON-NLS-1$ File embededEjbDir = new File(testProjectDir,"bootstrap"); //$NON-NLS-1$ File testSrcDir = new File(testProjectDir,"test-src"); //$NON-NLS-1$ String seamGenResFolder = seamRuntime.getResourceTemplatesDir(); File dataSourceFile = new File(seamGenResFolder, "datasource-ds.xml"); File seamPropertiesFile = new File(seamGenResFolder, "seam.properties"); //File jbossBeansFile = new File(seamGenResFolder ,"META-INF/jboss-beans.xml"); //$NON-NLS-1$ FilterSet filterSet = new FilterSet(); filterSet.addFilter("projectName", seamWebProject.getName()); //$NON-NLS-1$ filterSet.addFilter("earProjectName", earProjectName); //$NON-NLS-1$ filterSet.addFilter("ejbProjectName", ejbProjectName); //$NON-NLS-1$ filterSet.addFilter("testProjectName", testProjectName); //$NON-NLS-1$ filterSet.addFilter("runtimeName", WtpUtils.getServerRuntimeName(seamWebProject)); //$NON-NLS-1$ filterSet.addFilter("webRootFolder",webRootVirtFolder.getUnderlyingFolder().getFullPath().removeFirstSegments(1).toString()); //$NON-NLS-1$ FilterSet jdbcFilterSet = SeamFacetFilterSetFactory.createJdbcFilterSet(model); // TODO: why are these filters not shared!? filterSet.addConfiguredFilterSet(SeamFacetFilterSetFactory.createHibernateDialectFilterSet(model)); AntCopyUtils.FileSet includeLibs = new AntCopyUtils.FileSet(getJBossTestLibFileset()).dir(new File(seamRuntime.getHomeDir(),"lib")); //$NON-NLS-1$ AntCopyUtils.FileSet secondSetincludeLibs = new AntCopyUtils.FileSet(getJBossTestLibFileset()).dir(new File(seamRuntime.getHomeDir(),"lib/test")); //$NON-NLS-1$ File[] firstlibs = includeLibs.getDir().listFiles(new AntCopyUtils.FileSetFileFilter(includeLibs)); File[] secondLibs = secondSetincludeLibs.getDir().listFiles(new AntCopyUtils.FileSetFileFilter(secondSetincludeLibs)); Set<String> allLibs = new HashSet<String>(); // HACK: needed to be unique because some jboss-*.jars are duplicated if(firstlibs != null) for(File f : firstlibs) { allLibs.add(f.getName()); } if(secondLibs != null) for(File f : secondLibs) { allLibs.add(f.getName()); } StringBuffer testLibraries = new StringBuffer(); if (!SeamCorePlugin.getDefault().hasM2Facet(seamWebProject)) { for (String file : allLibs) { testLibraries.append("\t<classpathentry kind=\"lib\" path=\"lib/" + file + "\"/>\n"); //$NON-NLS-1$ //$NON-NLS-2$ } } StringBuffer requiredProjects = new StringBuffer(); requiredProjects.append( "\t<classpathentry combineaccessrules=\"false\" kind=\"src\" path=\"/" + seamWebProject.getName() + "\"/>"); //$NON-NLS-1$ //$NON-NLS-2$ if(!SeamFacetAbstractInstallDelegate.isWarConfiguration(model)) { requiredProjects.append("\n\t<classpathentry combineaccessrules=\"false\" kind=\"src\" path=\"/" + ejbProjectName + "\"/>"); //$NON-NLS-1$ //$NON-NLS-2$ } filterSet.addFilter("testLibraries",testLibraries.toString()); //$NON-NLS-1$ filterSet.addFilter("requiredProjects",requiredProjects.toString()); //$NON-NLS-1$ File testTemplateDir = null; try { testTemplateDir = new File(SeamFacetInstallDataModelProvider.getTemplatesFolder(), "test-seam2"); //$NON-NLS-1$ } catch (IOException e) { SeamCorePlugin.getPluginLog().logError(e); return false; } AntCopyUtils.FileSet excludeCvsSvn = new AntCopyUtils.FileSet(SeamFacetAbstractInstallDelegate.CVS_SVN).dir(testTemplateDir); AntCopyUtils.copyFilesAndFolders( testTemplateDir, testProjectDir, new AntCopyUtils.FileSetFileFilter(excludeCvsSvn), new FilterSetCollection(filterSet), true); excludeCvsSvn.dir(new File(seamRuntime.getHomeDir(), "bootstrap")); //$NON-NLS-1$ AntCopyUtils.copyFilesAndFolders( new File(seamRuntime.getHomeDir(), "bootstrap"), //$NON-NLS-1$ embededEjbDir, new AntCopyUtils.FileSetFileFilter(excludeCvsSvn), new FilterSetCollection(), true); // AntCopyUtils.copyFileToFile( // persistenceFile, // new File(testProjectDir,"test-src/META-INF/persistence.xml"), //$NON-NLS-1$ // new FilterSetCollection(filterSet), true); FilterSetCollection f = new FilterSetCollection(); f.addFilterSet(filterSet); f.addFilterSet(jdbcFilterSet); AntCopyUtils.copyFileToFile( dataSourceFile, new File(testProjectDir, "test-src/META-INF/"+seamWebProject.getName() + "-test-ds.xml"), //$NON-NLS-1$ f, true); AntCopyUtils.copyFileToFolder( seamPropertiesFile, testSrcDir, //$NON-NLS-1$ new FilterSetCollection(filterSet), true); // Add "org.jboss.seam.core.init.debug=false" for Seam 2.1/2.2/2.3 // to seam.properties file to avoid https://jira.jboss.org/jira/browse/JBIDE-3623 if(getVersion() == SeamVersion.SEAM_2_1 || getVersion() == SeamVersion.SEAM_2_2 || getVersion() == SeamVersion.SEAM_2_3) { Properties seamProperties = new Properties(); File testSeamPropertiesFile = new File(testSrcDir, "seam.properties"); FileInputStream inStream = null; FileOutputStream out = null; try { inStream = new FileInputStream(testSeamPropertiesFile); seamProperties.load(inStream); seamProperties.setProperty("org.jboss.seam.core.init.debug", "false"); //$NON-NLS-1$ //$NON-NLS-2$ out = new FileOutputStream(testSeamPropertiesFile); seamProperties.store(out, "debug is explicitly disabled in test to avoid JBIDE-3623"); } catch (FileNotFoundException e) { SeamCorePlugin.getPluginLog().logError(e); } catch (IOException e) { SeamCorePlugin.getPluginLog().logError(e); } finally { if(inStream!=null) { try { inStream.close(); } catch (IOException e) { /**ignore*/ } } if(out!=null) { try { out.close(); } catch (IOException e) { /**ignore*/ } } } } if (!SeamCorePlugin.getDefault().hasM2Facet(seamWebProject) && shouldCopyLibraries(model)) { AntCopyUtils.copyFiles(new File(seamRuntime.getHomeDir(), "lib"), //$NON-NLS-1$ testLibDir, new AntCopyUtils.FileSetFileFilter(includeLibs)); // seam2 has a lib/test AntCopyUtils.copyFiles(new File(seamRuntime.getHomeDir(), "lib/test"), //$NON-NLS-1$ testLibDir, new AntCopyUtils.FileSetFileFilter(includeLibs)); } SeamFacetAbstractInstallDelegate.createComponentsProperties(testSrcDir, "", true); //$NON-NLS-1$ return true; } @Override protected void createEjbProject() { super.createEjbProject(); // Copy security.drl to source folder if(shouldCopyLibrariesAndTemplates(model)) AntCopyUtils.copyFileToFolder(new File(seamGenResFolder, "security.drl"), new File(ejbProjectFolder, "ejbModule/"), true); //$NON-NLS-1$ //$NON-NLS-2$ } @Override protected void configureJBossAppXml() { IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(earProjectName); IVirtualComponent component = ComponentCore.createComponent(project); IVirtualFolder folder = component.getRootFolder(); IFolder rootFolder = (IFolder) folder.getUnderlyingFolder(); IResource jbossAppXml = rootFolder.findMember("META-INF/jboss-app.xml"); if(jbossAppXml==null || !(jbossAppXml instanceof IFile) || !jbossAppXml.exists()) { return; } IModelManager manager = StructuredModelManager.getModelManager(); if(manager == null) { return; } IStructuredModel model = null; try { model = manager.getModelForEdit((IFile)jbossAppXml); if (model instanceof IDOMModel) { IDOMModel domModel = (IDOMModel) model; IDOMDocument document = domModel.getDocument(); Element root = document.getDocumentElement(); if(root==null) { return; } NodeList children = root.getChildNodes(); boolean strictAdded = false; Node firstChild = null; for(int i=0; i<children.getLength(); i++) { Node currentNode = children.item(i); if(Node.ELEMENT_NODE == currentNode.getNodeType() && firstChild == null) { firstChild = currentNode; } if(Node.ELEMENT_NODE == currentNode.getNodeType() && MODULE_ORDER.equals(currentNode.getNodeName())) { setValue(document,currentNode,STRICT); strictAdded = true; } } if (!strictAdded) { Element moduleOrder = document.createElement(MODULE_ORDER); setValue(document,moduleOrder,STRICT); if (firstChild != null) { root.insertBefore(moduleOrder, firstChild); } else { root.appendChild(moduleOrder); } } model.save(); } } catch (CoreException e) { SeamCorePlugin.getDefault().logError(e); } catch (IOException e) { SeamCorePlugin.getDefault().logError(e); } finally { if (model != null) { model.releaseFromEdit(); } } try { new FormatProcessorXML().formatFile((IFile) jbossAppXml); } catch (IOException e) { SeamCorePlugin.getDefault().logError(e); } catch (CoreException e) { SeamCorePlugin.getDefault().logError(e); } } private void setValue(Document document, Node node, String value) { Text text = document.createTextNode(value); node.appendChild(text); } protected AntCopyUtils.FileSet getJBossTestLibFileset() { return JBOSS_TEST_LIB_FILESET; } protected AntCopyUtils.FileSet getJbossEarContent() { return Seam2FacetInstallDelegate.JBOSS_EAR_CONTENT; } }