/* ==================================================================== * * The ObjectStyle Group Software License, Version 1.0 * * Copyright (c) 2005 - 2006 The ObjectStyle Group, * and individual authors of the software. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, if * any, must include the following acknowlegement: * "This product includes software developed by the * ObjectStyle Group (http://objectstyle.org/)." * Alternately, this acknowlegement may appear in the software itself, * if and wherever such third-party acknowlegements normally appear. * * 4. The names "ObjectStyle Group" and "Cayenne" * must not be used to endorse or promote products derived * from this software without prior written permission. For written * permission, please contact andrus@objectstyle.org. * * 5. Products derived from this software may not be called "ObjectStyle" * nor may "ObjectStyle" appear in their names without prior written * permission of the ObjectStyle Group. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE OBJECTSTYLE GROUP OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the ObjectStyle Group. For more * information on the ObjectStyle Group, please see * <http://objectstyle.org/>. * */ package org.objectstyle.wolips.core.resources.types.project; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import org.eclipse.core.resources.ICommand; import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IFolder; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IProjectDescription; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Platform; import org.eclipse.jdt.core.JavaCore; import org.objectstyle.wolips.baseforplugins.util.WOLipsNatureUtils; import org.objectstyle.wolips.core.CorePlugin; import org.objectstyle.wolips.core.resources.internal.build.AntApplicationNature; import org.objectstyle.wolips.core.resources.internal.build.AntFrameworkNature; import org.objectstyle.wolips.core.resources.internal.types.AbstractResourceAdapter; import org.objectstyle.wolips.core.resources.types.IPBDotProjectOwner; import org.objectstyle.wolips.core.resources.types.file.IPBDotProjectAdapter; import org.objectstyle.wolips.core.resources.types.folder.IBuildAdapter; import org.objectstyle.wolips.core.resources.types.folder.IDotApplicationAdapter; import org.objectstyle.wolips.core.resources.types.folder.IDotFrameworkAdapter; import org.objectstyle.wolips.core.resources.types.folder.IProductAdapter; import org.objectstyle.wolips.core.resources.types.folder.IWoprojectAdapter; import org.objectstyle.wolips.variables.BuildProperties; import org.objectstyle.wolips.variables.VariablesPlugin; public class ProjectAdapter extends AbstractResourceAdapter implements IPBDotProjectOwner { private IProject _underlyingProject; private boolean _isFramework; /** * Comment for <code>BuilderNotFound</code> */ public static final int BuilderNotFound = -1; protected static final String TARGET_BUILDER_ID = "org.objectstyle.wolips.targetbuilder.targetbuilder"; protected static final String INCREMENTAL_BUILDER_ID = "org.objectstyle.wolips.incrementalbuilder"; private static final String ANT_BUILDER_ID = "org.objectstyle.wolips.antbuilder"; public ProjectAdapter(IProject project, boolean isFramework) { super(project); this._underlyingProject = project; this._isFramework = isFramework; } public IProject getUnderlyingProject() { return this._underlyingProject; } public String getBundleName() { // This is not really right ... if your project name differs from your framework name, // this will choke, but it's currently consistent with how dynamic framework resolution // works, and until that is changed over to use this method, we're stuck with it. return getUnderlyingProject().getName(); } /** * Returns true if this project is a Maven project. * * @return true if this project is a Maven project */ public boolean isMaven() { return WOLipsNatureUtils.isMavenNature(getUnderlyingProject()); } public boolean isFramework() { return this._isFramework; } public boolean isApplication() { return !this.isFramework(); } public IPBDotProjectAdapter getPBDotProjectAdapter() { IContainer underlyingContainer = this.getUnderlyingProject(); IResource pbDotProjectResource = underlyingContainer.getFile(new Path(IPBDotProjectAdapter.FILE_NAME)); IPBDotProjectAdapter pbDotProjectAdapter = (IPBDotProjectAdapter) pbDotProjectResource.getAdapter(IPBDotProjectAdapter.class); return pbDotProjectAdapter; } public IWoprojectAdapter getWoprojectAdapter() { IContainer underlyingContainer = this.getUnderlyingProject(); IFolder wprojectFolder = null; IWoprojectAdapter wprojectAdapter = null; wprojectFolder = underlyingContainer.getFolder(new Path(IWoprojectAdapter.FOLDER_NAME)); if (wprojectFolder.exists()) { wprojectAdapter = (IWoprojectAdapter) wprojectFolder.getAdapter(IWoprojectAdapter.class); if (wprojectAdapter != null) { return wprojectAdapter; } } wprojectFolder = underlyingContainer.getFolder(new Path(IWoprojectAdapter.FOLDER_NAME_DEPRECATED)); if (wprojectFolder.exists()) { wprojectAdapter = (IWoprojectAdapter) wprojectFolder.getAdapter(IWoprojectAdapter.class); } return wprojectAdapter; } public IPBDotProjectOwner getPBDotProjectOwner(IResource resource) { if (resource == this.getUnderlyingProject()) { return this; } return super.getPBDotProjectOwner(resource); } public IPBDotProjectOwner getPBDotProjectOwner() { return this; } public boolean hasParentPBDotProjectAdapter() { return false; } private IFolder getBuildFolder() { // :TODO what if we have both folder IResource resource = this.getUnderlyingProject().getFolder(IBuildAdapter.FILE_NAME_DIST); if (resource.exists() && resource instanceof IFolder) { return (IFolder) resource; } resource = this.getUnderlyingProject().getFolder(IBuildAdapter.FILE_NAME_BUILD); if (resource.exists() && resource instanceof IFolder) { return (IFolder) resource; } return null; } public IBuildAdapter getBuildAdapter() { IResource resource = this.getBuildFolder(); if (resource == null) { return null; } return (IBuildAdapter) resource.getAdapter(IBuildAdapter.class); } public IDotApplicationAdapter getDotApplicationAdapter() { IResource resource = this.getUnderlyingProject().getFolder(this.getUnderlyingResource().getProject().getName() + "." + IDotApplicationAdapter.FILE_NAME_EXTENSION); return (IDotApplicationAdapter) resource.getAdapter(IDotApplicationAdapter.class); } public IDotFrameworkAdapter getDotFrameworkAdapter() { IResource resource = this.getUnderlyingProject().getFolder(this.getUnderlyingResource().getProject().getName() + "." + IDotFrameworkAdapter.FILE_NAME_EXTENSION); return (IDotFrameworkAdapter) resource.getAdapter(IDotFrameworkAdapter.class); } public IProductAdapter getProductAdapter() { if (isFramework()) { return this.getDotFrameworkAdapter(); } return this.getDotApplicationAdapter(); } /** * Installs the target builder. * * @param position * @throws CoreException */ public void installTargetBuilder(int position) throws CoreException { if (!this.isTargetBuilderInstalled()) this.installBuilderAtPosition(ProjectAdapter.TARGET_BUILDER_ID, position, null); } /** * Removes the target builder. * * @return postion of TargetBuilder if not found * IBuilderAccessor.BuilderNotFoundwill be returned. * @throws CoreException */ public int removeTargetBuilder() throws CoreException { if (!this.isTargetBuilderInstalled()) return ProjectAdapter.BuilderNotFound; int returnValue = this.positionForBuilder(ProjectAdapter.TARGET_BUILDER_ID); this.removeBuilder(ProjectAdapter.TARGET_BUILDER_ID); return returnValue; } /** * Installs the ant builder. * * @throws CoreException */ public void installAntBuilder() throws CoreException { if (!this.isAntBuilderInstalled()) this.installBuilder(ProjectAdapter.ANT_BUILDER_ID); } /** * Removes the ant builder. * * @throws CoreException */ public void removeAntBuilder() throws CoreException { if (this.isAntBuilderInstalled()) this.removeBuilder(ProjectAdapter.ANT_BUILDER_ID); } /** * Installs the incremetal builder. * * @throws CoreException */ public void installIncrementalBuilder() throws CoreException { if (!this.isIncrementalBuilderInstalled()) this.installBuilder(ProjectAdapter.INCREMENTAL_BUILDER_ID); } /** * Removes the incremental builder. * * @throws CoreException */ public void removeIncrementalBuilder() throws CoreException { if (this.isIncrementalBuilderInstalled()) this.removeBuilder(ProjectAdapter.INCREMENTAL_BUILDER_ID); } /** * Installs the java builder. * * @throws CoreException */ public void installJavaBuilder() throws CoreException { if (!this.isJavaBuilderInstalled()) this.installBuilder(JavaCore.BUILDER_ID); } /** * Installs the java builder. * * @param position * @throws CoreException */ public void installJavaBuilder(int position) throws CoreException { if (!this.isJavaBuilderInstalled()) this.installBuilderAtPosition(JavaCore.BUILDER_ID, position, null); } /** * Removes the incremental builder. * * @return postion of JavaBuilder if not found * IBuilderAccessor.BuilderNotFoundwill be returned. * @throws CoreException */ public int removeJavaBuilder() throws CoreException { if (!this.isJavaBuilderInstalled()) return ProjectAdapter.BuilderNotFound; int returnValue = this.positionForBuilder(JavaCore.BUILDER_ID); this.removeBuilder(JavaCore.BUILDER_ID); return returnValue; } /** * @return Return true if the target builder is installed. */ public boolean isTargetBuilderInstalled() { return this.isBuilderInstalled(ProjectAdapter.TARGET_BUILDER_ID); } /** * @return Return true if the ant builder is installed. */ public boolean isAntBuilderInstalled() { return this.isBuilderInstalled(ProjectAdapter.ANT_BUILDER_ID); } /** * @return Return true if the incremental builder is installed. */ public boolean isIncrementalBuilderInstalled() { return this.isBuilderInstalled(ProjectAdapter.INCREMENTAL_BUILDER_ID); } /** * @return Return true if the java builder is installed. */ public boolean isJavaBuilderInstalled() { return this.isBuilderInstalled(JavaCore.BUILDER_ID); } /** * @return The builer args. */ public Map getBuilderArgs() { Map result = null; try { IProjectDescription desc = this.getUnderlyingProject().getDescription(); List cmdList = Arrays.asList(desc.getBuildSpec()); Iterator iter = cmdList.iterator(); while (iter.hasNext()) { ICommand cmd = (ICommand) iter.next(); if (this.isWOLipsBuilder(cmd.getBuilderName())) { result = cmd.getArguments(); break; } } } catch (Exception up) { // if anything went wrong, we simply don't have any args (yet) // might wanna log the exception, though } if (null == result) { // this doesn't exist pre-JDK1.3, is that a problem? result = Collections.EMPTY_MAP; // result = new HashMap(); } return (result); } /** * @param name * Name of a build command * @return boolean whether this is one of ours */ private boolean isWOLipsBuilder(String name) { return (name.equals(ProjectAdapter.INCREMENTAL_BUILDER_ID) || name.equals(ProjectAdapter.ANT_BUILDER_ID)); } /** * Method removeJavaBuilder. * * @param aBuilder * @throws CoreException */ private void removeBuilder(String aBuilder) throws CoreException { IProjectDescription desc = null; ICommand[] coms = null; ArrayList<ICommand> comList = null; List<ICommand> tmp = null; ICommand[] newCom = null; try { desc = this.getUnderlyingProject().getDescription(); coms = desc.getBuildSpec(); comList = new ArrayList<ICommand>(); tmp = Arrays.asList(coms); comList.addAll(tmp); boolean foundJBuilder = false; for (int i = 0; i < comList.size(); i++) { if ((comList.get(i)).getBuilderName().equals(aBuilder)) { comList.remove(i); foundJBuilder = true; } } if (foundJBuilder) { newCom = new ICommand[comList.size()]; for (int i = 0; i < comList.size(); i++) { newCom[i] = comList.get(i); } desc.setBuildSpec(newCom); this.getUnderlyingProject().setDescription(desc, null); } } finally { desc = null; coms = null; comList = null; tmp = null; newCom = null; } } /** * Method installBuilder. * * @param aBuilder * @throws CoreException */ private void installBuilder(String aBuilder) throws CoreException { IProjectDescription desc = null; ICommand[] coms = null; ICommand[] newIc = null; ICommand command = null; try { desc = this.getUnderlyingProject().getDescription(); coms = desc.getBuildSpec(); boolean foundJBuilder = false; for (int i = 0; i < coms.length; i++) { if (coms[i].getBuilderName().equals(aBuilder)) { foundJBuilder = true; } } if (!foundJBuilder) { command = desc.newCommand(); command.setBuilderName(aBuilder); newIc = new ICommand[coms.length + 1]; System.arraycopy(coms, 0, newIc, 0, coms.length); newIc[coms.length] = command; desc.setBuildSpec(newIc); this.getUnderlyingProject().setDescription(desc, null); } } finally { desc = null; coms = null; newIc = null; command = null; } } /** * Method isBuilderInstalled. * * @param anID * @return boolean */ private boolean isBuilderInstalled(String anID) { try { ICommand[] nids = this.getUnderlyingProject().getDescription().getBuildSpec(); for (int i = 0; i < nids.length; i++) { if (nids[i].getBuilderName().equals(anID)) return true; } } catch (Exception anException) { CorePlugin.getDefault().log(anException); return false; } return false; } /** * Method positionForBuilder. * * @param aBuilder * @return int * @throws CoreException */ private int positionForBuilder(String aBuilder) throws CoreException { IProjectDescription desc = null; ICommand[] coms = null; try { desc = this.getUnderlyingProject().getDescription(); coms = desc.getBuildSpec(); for (int i = 0; i < coms.length; i++) { if (coms[i].getBuilderName().equals(aBuilder)) return i; } } finally { desc = null; coms = null; } return BuilderNotFound; } /** * Method installBuilderAtPosition. * * @param aBuilder * @param installPos * @param arguments * @throws CoreException */ private void installBuilderAtPosition(String aBuilder, int installPos, Map arguments) throws CoreException { if (installPos == ProjectAdapter.BuilderNotFound) { CorePlugin.getDefault() .log("Somebody tries to install builder: " + aBuilder + " at an illegal position. This may happen if the removed builder does not exist."); return; } IProjectDescription desc = this.getUnderlyingProject().getDescription(); ICommand[] coms = desc.getBuildSpec(); Map args = arguments; if (args == null) args = new HashMap(); for (int i = 0; i < coms.length; i++) { if (coms[i].getBuilderName().equals(aBuilder) && coms[i].getArguments().equals(args)) return; } ICommand[] newIc = null; ICommand command = desc.newCommand(); command.setBuilderName(aBuilder); command.setArguments(args); newIc = new ICommand[coms.length + 1]; if (installPos <= 0) { System.arraycopy(coms, 0, newIc, 1, coms.length); newIc[0] = command; } else if (installPos >= coms.length) { System.arraycopy(coms, 0, newIc, 0, coms.length); newIc[coms.length] = command; } else { System.arraycopy(coms, 0, newIc, 0, installPos); newIc[installPos] = command; System.arraycopy(coms, installPos, newIc, installPos + 1, coms.length - installPos); } desc.setBuildSpec(newIc); this.getUnderlyingProject().setDescription(desc, null); } /** * @return null if the project is not an application othewise invokes the * same method on ProjectAdapter */ public IPath getWorkingDir() throws CoreException { IPath path = null; IContainer workingDirFolder = getWorkingDirFolder(); if (workingDirFolder != null && workingDirFolder.exists()) { path = workingDirFolder.getLocation(); } return path; } protected boolean mockBundlesEnabled() { return Platform.getPreferencesService().getBoolean("org.objectstyle.wolips.preferences", "org.objectstyle.wolips.preference.MockBundleEnabled", true, null); } /** * @return null if the project is not an application otherwise invokes the * same method on ProjectAdapter */ public IContainer getWorkingDirFolder() throws CoreException { IContainer workingDirFolder; IProject project = this.getUnderlyingProject(); BuildProperties buildProperties = (BuildProperties)project.getAdapter(BuildProperties.class); if (buildProperties.getWOVersion().isAtLeastVersion(5, 6) || !mockBundlesEnabled()) { workingDirFolder = project; } else { if (this.isAntBuilderInstalled() || (WOLipsNatureUtils.getNature(project) instanceof AntApplicationNature)) { workingDirFolder = this.getUnderlyingProject().getFolder(IBuildAdapter.FILE_NAME_DIST); } else { workingDirFolder = this.getUnderlyingProject().getFolder(IBuildAdapter.FILE_NAME_BUILD); } if (workingDirFolder != null && workingDirFolder.exists()) { IFolder woaFolder = null; IResource[] members = workingDirFolder.members(); for (int i = 0; woaFolder == null && i < members.length; i++) { IResource member = members[i]; if (member.getType() == IResource.FOLDER && member.getName().endsWith(".woa")) { woaFolder = (IFolder) member; } } if (woaFolder != null && woaFolder.exists()) { workingDirFolder = woaFolder; } else { workingDirFolder = null; } } else { workingDirFolder = null; } } return workingDirFolder; } public IPath getWOJavaArchive() throws CoreException { IPath path = null; IProject project = this.getUnderlyingProject(); BuildProperties buildProperties = (BuildProperties)project.getAdapter(BuildProperties.class); if (buildProperties.getWOVersion().isAtLeastVersion(5, 6) || !mockBundlesEnabled()) { path = this.getUnderlyingProject().getLocation(); } else { IResource resource = null; String projectName = project.getName(); // String projectNameLC = projectName.toLowerCase(); // I'd rather use the knowledge from the IncrementalNature, but // that fragment is not // visible here (so I can't use the class, I think) [hn3000] if (this.isFramework()) { if (this.isAntBuilderInstalled() || (WOLipsNatureUtils.getNature(project) instanceof AntFrameworkNature)) { resource = getJar("dist/", ".framework/"); if (!resource.exists()) resource = getJar("", ".framework/"); } else if (this.isIncrementalBuilderInstalled()) { resource = this.getUnderlyingProject().getFolder("build/" + projectName + ".framework/Resources/Java"); } if (resource != null && resource.exists()) { path = resource.getLocation(); } else { IPath externalBuildRoot = VariablesPlugin.getDefault().getProjectVariables(_underlyingProject).getExternalBuildRoot(); if (externalBuildRoot != null) { path = externalBuildRoot.append(projectName + ".framework/Resources/Java/" + projectName + ".jar"); } } } else if (this.isApplication()) { // must be application IContainer wdFolder = getWorkingDirFolder(); if (wdFolder != null && wdFolder.exists()) { IFolder javaFolder = wdFolder.getFolder(new Path("Contents/Resources/Java")); if (this.isAntBuilderInstalled() || (WOLipsNatureUtils.getNature(project) instanceof AntApplicationNature)) { resource = javaFolder.findMember(wdFolder.getName().substring(0, wdFolder.getName().length() - 4).toLowerCase() + ".jar"); if (!resource.exists()) resource = getJar("", ".woa/Contents/"); } else if (this.isIncrementalBuilderInstalled()) { resource = javaFolder; } } if (resource != null && (resource.exists())) { path = resource.getLocation(); } else { IPath externalBuildRoot = VariablesPlugin.getDefault().getProjectVariables(_underlyingProject).getExternalBuildRoot(); if (externalBuildRoot != null) { path = externalBuildRoot.append(projectName + ".woa/Contents/Resources/Java/" + projectName + ".jar"); } } } } return path; } private IResource getJar(String prefix, String postfix) { IResource result = null; String projectName = this.getUnderlyingProject().getName(); result = this.getUnderlyingProject().getFile(prefix + projectName + postfix + "Resources/Java/" + projectName + ".jar"); if (result == null || !result.exists()) { result = this.getUnderlyingProject().getFile(prefix + projectName + postfix + "Resources/Java/" + projectName.toLowerCase() + ".jar"); } return result; } public BuildProperties getBuildProperties() { return (BuildProperties) _underlyingProject.getAdapter(BuildProperties.class); } /** * Returns true if the given resource will be considered a resource to WebObjects. * * @param resource the resource to test * @return true if the given resource will be considered a resource to WebObjects */ public boolean isResource(IResource resource) { IProjectPatternsets patternsets = (IProjectPatternsets)getUnderlyingProject().getAdapter(IProjectPatternsets.class); boolean isResource = patternsets.matchesResourcesPattern(resource); return isResource; } /** * Returns true if a file in the given container will be considered a resource to WebObjects. * * @param container the container to test * @return true if a file in the given container will be considered a resource to WebObjects */ public boolean isResourceContainer(IContainer container) { return isResource(container.getFolder(new Path("Random.eomodeld"))); } /** * Returns the default folder to use for storing Resources (like EOModels). Currently this * is just a best-guess. * * @return the default folder to use for storing Resources */ public IContainer getDefaultResourcesFolder() { IProject project = getUnderlyingProject(); IContainer resourcesFolder = project.getFolder("Resources"); if (!resourcesFolder.exists()) { if (isMaven()) { resourcesFolder = project.getFolder(new Path("src/main/resources")); if (!resourcesFolder.exists()) { resourcesFolder = project; } } else { resourcesFolder = project; } } return resourcesFolder; } /** * Returns true if a file in the given container will be considered a component to WebObjects. * * @param container the container to test * @return true if a file in the given container will be considered a component to WebObjects */ public boolean isComponentsContainer(IContainer container) { return isResource(container.getFolder(new Path("Random.wo"))); } /** * Returns the default folder to use for storing Components. Currently this * is just a best-guess. * * @return the default folder to use for storing Components */ public IContainer getDefaultComponentsFolder() { IProject project = getUnderlyingProject(); IContainer componentsFolder = project.getFolder("Components"); if (!componentsFolder.exists()) { if (isMaven()) { componentsFolder = project.getFolder(new Path("src/main/components")); if (!componentsFolder.exists()) { componentsFolder = project; } } else { componentsFolder = project; } } return componentsFolder; } }