/* ==================================================================== * * The ObjectStyle Group Software License, Version 1.0 * * Copyright (c) 2002 - 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.builder.internal; import java.util.Map; import org.eclipse.core.resources.IContainer; 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.IResourceDelta; import org.eclipse.core.resources.IncrementalProjectBuilder; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.SubProgressMonitor; import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.core.JavaCore; import org.objectstyle.wolips.baseforplugins.AbstractBaseActivator; import org.objectstyle.wolips.builder.BuilderPlugin; import org.objectstyle.wolips.core.resources.types.folder.IWoprojectAdapter; import org.objectstyle.wolips.core.resources.types.project.ProjectAdapter; import org.objectstyle.wolips.preferences.Preferences; import org.objectstyle.wolips.templateengine.ProjectInput; import org.objectstyle.wolips.templateengine.ProjectTemplate; import org.objectstyle.wolips.variables.BuildProperties; /** * @author Harald Niesche The incremental builder creates the * build/ProjectName.woa or build/ProjectName.framework folder that * contains an approximation of the structure needed to run a WebObjects * application or use a framework */ public class WOIncrementalBuilder extends AbstractIncrementalProjectBuilder { private BuildVisitor _buildVisitor; private JarBuilder _jarBuilder; /** * Constructor for WOProjectBuilder. */ public WOIncrementalBuilder() { super(); } public boolean isEnabled() { return true; } /* * this is duplicated from ProjectNaturePage, couldn't find a good place for * now */ private String getArg(Map values, String key, String defVal) { String result = null; try { result = (String) values.get(key); } catch (Exception up) { getLogger().log(up); } if (null == result) result = defVal; return result; } public void invokeOldBuilder(int kind, Map args, IProgressMonitor progressMonitor, IResourceDelta resourceDelta) throws Exception { if (!Preferences.mockBundleEnabled()) { // just don't do anything here return; } IProgressMonitor subProgressMonitor = null; if (null == progressMonitor) { subProgressMonitor = new NullProgressMonitor(); } else { subProgressMonitor = new SubProgressMonitor(progressMonitor, 100 * 1000); } IResourceDelta delta = resourceDelta; if (kind != IncrementalProjectBuilder.FULL_BUILD && kind != IncrementalProjectBuilder.CLEAN_BUILD && !projectNeedsAnUpdate(delta)) { subProgressMonitor.done(); return; } getLogger().debug("<incremental build>"); subProgressMonitor.beginTask("building WebObjects layout ...", 100); try { ProjectAdapter project = (ProjectAdapter) this.getProject().getAdapter(ProjectAdapter.class); boolean fullBuild = (kind == IncrementalProjectBuilder.FULL_BUILD || kind == IncrementalProjectBuilder.CLEAN_BUILD || patternsetDeltaVisitor().isFullBuildRequired()); String oldPrincipalClass = getArg(args, BuilderPlugin.NS_PRINCIPAL_CLASS, ""); if (oldPrincipalClass.length() == 0) { oldPrincipalClass = null; } BuildProperties buildProperties = project.getBuildProperties(); String principalClass = buildProperties.getPrincipalClass(true); if (principalClass == null && oldPrincipalClass != null) { principalClass = oldPrincipalClass; buildProperties.setPrincipalClass(principalClass); } if (buildProperties.getWOVersion().isAtLeastVersion(5, 6)) { IContainer infoPListContainer = getProject().getFolder(IWoprojectAdapter.FOLDER_NAME); createInfoPlist(infoPListContainer); } else { if (_buildVisitor == null) { _buildVisitor = new BuildVisitor(); } _buildVisitor.reinitForNextBuild(this.getProject()); if (!fullBuild) { subProgressMonitor.subTask("checking directory structure ..."); if (!_buildVisitor._checkDirs()) { delta = null; subProgressMonitor.worked(5); } } else { delta = null; long t0 = System.currentTimeMillis(); IFolder buildFolder = getProject().getFolder("build"); subProgressMonitor.subTask("scrubbing build folder ..."); buildFolder.refreshLocal(IResource.DEPTH_INFINITE, null); subProgressMonitor.worked(1); getLogger().debug("refresh build folder took: " + (System.currentTimeMillis() - t0) + " ms"); t0 = System.currentTimeMillis(); buildFolder.delete(true, false, null); subProgressMonitor.worked(2); getLogger().debug("scrubbing build folder took: " + (System.currentTimeMillis() - t0) + " ms"); t0 = System.currentTimeMillis(); buildFolder.refreshLocal(IResource.DEPTH_INFINITE, null); subProgressMonitor.subTask("re-creating structure ..."); _buildVisitor._checkDirs(); subProgressMonitor.worked(2); getLogger().debug("re-creating build folder took: " + (System.currentTimeMillis() - t0) + " ms"); } subProgressMonitor.subTask("creating Info.plist"); IContainer infoPListContainer = getProject().getWorkspace().getRoot().getFolder(_buildVisitor.getInfoPath()); createInfoPlist(infoPListContainer); subProgressMonitor.worked(1); if ((null != delta)) { getLogger().debug("<partial build>"); subProgressMonitor.subTask("preparing partial build"); long t0 = System.currentTimeMillis(); _buildVisitor.resetCount(); delta.accept(_buildVisitor, IResourceDelta.ALL_WITH_PHANTOMS); getLogger().debug("delta.accept with " + _buildVisitor.getCount() + " delta nodes took: " + (System.currentTimeMillis() - t0) + " ms"); getLogger().debug("</partial build>"); subProgressMonitor.worked(12); } else { getLogger().debug("<full build>"); subProgressMonitor.subTask("preparing full build"); long t0 = System.currentTimeMillis(); t0 = System.currentTimeMillis(); _buildVisitor.resetCount(); getProject().accept(_buildVisitor); getLogger().debug("preparing with " + _buildVisitor.getCount() + " project nodes took: " + (System.currentTimeMillis() - t0) + " ms"); getLogger().debug("</full build>"); subProgressMonitor.worked(12); } long t0 = System.currentTimeMillis(); _buildVisitor.executeTasks(subProgressMonitor); getLogger().debug("building structure took: " + (System.currentTimeMillis() - t0) + " ms"); t0 = System.currentTimeMillis(); subProgressMonitor.subTask("copying classes"); jarBuild(delta, subProgressMonitor, getProject()); getLogger().debug("copying classes took: " + (System.currentTimeMillis() - t0) + " ms"); subProgressMonitor.done(); } } catch (Exception up) { getLogger().log(up); throw up; } getLogger().debug("</incremental build>"); } protected void createInfoPlist(IContainer targetContainer) throws Exception { ProjectTemplate infoPListTemplate; IProject project = getProject(); ProjectAdapter projectAdapter = (ProjectAdapter) project.getAdapter(ProjectAdapter.class); if (projectAdapter.isFramework()) { infoPListTemplate = ProjectTemplate.loadProjectTemplateNamed("MiscTemplates", "FrameworkInfoPList"); } else { infoPListTemplate = ProjectTemplate.loadProjectTemplateNamed("MiscTemplates", "ApplicationInfoPList"); } infoPListTemplate.addInput(new ProjectInput("buildProperties", projectAdapter.getBuildProperties())); targetContainer.refreshLocal(IResource.DEPTH_ZERO, null); infoPListTemplate.createProjectContents(project, targetContainer, new NullProgressMonitor()); IFile infoPList = targetContainer.getFile(new Path("Info.plist")); infoPList.refreshLocal(IResource.DEPTH_ZERO, null); infoPList.setDerived(true, null); } private AbstractBaseActivator getLogger() { return BuilderPlugin.getDefault(); } private void jarBuild(IResourceDelta delta, IProgressMonitor monitor, IProject project) throws CoreException { getLogger().debug("<jar build>"); if (_jarBuilder == null) _jarBuilder = new JarBuilder(); _jarBuilder.reinitForNextBuild(project); long t0 = System.currentTimeMillis(); if (null != delta) { delta.accept(_jarBuilder, IResourceDelta.ALL_WITH_PHANTOMS); } else { IPath outPath = getJavaProject().getOutputLocation(); IContainer output = getProject(); if (!outPath.segment(0).equals(getProject().getName())) { output = getProject().getParent().getFolder(outPath); } output.accept(_jarBuilder); } getLogger().debug("prepare jar copy took " + (System.currentTimeMillis() - t0) + " ms"); monitor.worked(10); t0 = System.currentTimeMillis(); _jarBuilder.executeTasks(monitor); getLogger().debug("executing jar copy took " + (System.currentTimeMillis() - t0) + " ms"); getLogger().debug("</jar build>"); } private IJavaProject getJavaProject() { try { return ((IJavaProject) (getProject().getNature(JavaCore.NATURE_ID))); } catch (CoreException up) { this.getLogger().log(up); } return null; } /** * @see org.eclipse.core.resources.IncrementalProjectBuilder#startupOnInitialize() */ protected void startupOnInitialize() { // try { // IJavaProject javaProject = getJavaProject(); // _getLogger().debug(javaProject.getOutputLocation()); // } catch (Throwable up) { // } // super.startupOnInitialize(); } }