All Downloads are FREE. Search and download functionalities are using the official Maven repository.

protoj.lang.internal.ProtoProject Maven / Gradle / Ivy

The newest version!
/**
 * Copyright 2009 Ashley Williams
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you
 * may not use this file except in compliance with the License. You may
 * obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
 * implied. See the License for the specific language governing
 * permissions and limitations under the License.
 */
package protoj.lang.internal;

import java.io.File;
import java.util.ArrayList;
import java.util.Collection;

import org.apache.commons.io.FileUtils;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.taskdefs.Expand;
import org.apache.tools.ant.taskdefs.Java;

import protoj.lang.ArchiveFeature;
import protoj.lang.ClassesArchive;
import protoj.lang.DependencyInfo;
import protoj.lang.DependencyStore;
import protoj.lang.JavadocArchive;
import protoj.lang.ProjectLayout;
import protoj.lang.ResourceFeature;
import protoj.lang.SourceArchive;
import protoj.lang.StandardProject;
import protoj.lang.ClassesArchive.ClassesEntry;
import protoj.lang.JavadocArchive.JavadocEntry;
import protoj.lang.command.ArchiveCommand;
import protoj.lang.command.PublishCommand;
import protoj.util.AntTarget;
import protoj.util.ArgRunnable;

/**
 * Represents the use-cases available to be carried out against the protoj
 * delegate.
 * 
 * @author Ashley Williams
 * 
 */
public final class ProtoProject {
	/**
	 * See {@link ProtoProject}.
	 * 
	 * @param args
	 */
	public static void main(String[] args) {
		new ProtoProject(args).dispatchCommands();
	}

	/**
	 * See {@link #getDelegate()}.
	 */
	private StandardProject delegate;

	/**
	 * See {@link #getReleaseCommand()}.
	 */
	private ReleaseCommand releaseCommand;

	/**
	 * See {@link #getProtoconfCommand()}.
	 */
	private ProtoconfCommand protoconfCommand;

	/**
	 * See {@link #getReleaseFeature()}.
	 */
	private ReleaseFeature releaseFeature;

	/**
	 * See {@link #getSampleProjectFeature()}.
	 */
	private SampleProjectFeature sampleProjectFeature;

	/**
	 * Responsible for extracting the google wiki pages.
	 */
	private DocsCommand siteCommand;

	/**
	 * See {@link #getStrictRepoDependencies()}.
	 */
	private ArrayList strictRepoDependencies;

	/**
	 * See {@link #getStrictDependencies()}.
	 */
	private ArrayList strictDependencies;

	/**
	 * Constructor that uses system properties protoj.rootDir and
	 * protoj.scriptName.
	 */
	public ProtoProject() {
		init(new StandardProject(null));
	}

	/**
	 * See the
	 * StandardProject.StandardProject(String[], String, String)
	 * constructor for a discussion of the arguments to main().
	 * 
	 * @param args
	 */
	public ProtoProject(String[] args) {
		init(new StandardProject(args, null));
	}

	/**
	 * Call this constructor in order to set the project root and script.
	 * 
	 * @param rootDir
	 * @param script
	 * @param versionInfo
	 */
	public ProtoProject(File rootDir, String script, String versionInfo) {
		init(new StandardProject(rootDir, script, versionInfo));
	}

	/**
	 * Create with the underlying project delegate.
	 * 
	 * @param project
	 */
	public void init(StandardProject project) {
		// objects that much functionality will be delegated to
		delegate = project;
		releaseFeature = new ReleaseFeature(this);
		sampleProjectFeature = new SampleProjectFeature(this);

		// change the name of the profile from default using property override
		project.initDirConfig(getProjectHome());

		// add a reference to ourselves to the velocity context
		project.getResourceFeature().getContext().put("protoProject", this);

		// the location of the ivy resource used for retrieving dependencies
		project.getRetrieveFeature().initIvy("/protoj-dev/ivy.xml");

		// don't want our own project as a dependency since we are creating it
		initStrictDependencies();
		initStrictRepoDependencies();

		// configure the ProtoJ jar files for creation
		initProtoExeJar();
		initProtoJar();

		delegate.initJunit("32m");
		delegate.initUploadGoogleCode("protoj");
		delegate
				.initPublish("scp://shell.sourceforge.net:/home/groups/p/pr/protojrepo/htdocs/mavensync");
		delegate.getPublishFeature().initProvider("wagon-ssh", "1.0-beta-2");
		PublishCommand publishCommand = delegate.getCommands().getPublish();
		publishCommand.getDelegate().setMemory("32m");
		ArchiveCommand archiveCommand = delegate.getCommands().getArchive();
		archiveCommand.getDelegate().setMemory("32m");
		releaseCommand = new ReleaseCommand(this, this.getClass().getName());
		protoconfCommand = new ProtoconfCommand(this);
		siteCommand = new DocsCommand(this);
	}

	/**
	 * See {@link #getStrictDependencies()}.
	 */
	private void initStrictDependencies() {
		DependencyStore store = delegate.getDependencyStore();
		strictDependencies = new ArrayList();
		strictDependencies.addAll(store.getDependencies());
		strictDependencies.remove(store.getProtoj());

	}

	/**
	 * See {@link #getStrictRepoDependencies()}.
	 */
	private void initStrictRepoDependencies() {
		DependencyStore store = delegate.getDependencyStore();
		strictRepoDependencies = new ArrayList();
		strictRepoDependencies.addAll(store.getRepoDependencies());
		strictRepoDependencies.remove(store.getProtoj());

	}

	/**
	 * Configures the artifacts for the executable archive.
	 */
	private void initProtoExeJar() {
		final String projectVersion = getVersion();
		// the no-dependencies jar file merged with all jars in the lib dir
		ClassesArchive classes = delegate.getArchiveFeature()
				.getClassesArchive();
		String jarName = getVersionedExeJarTag();
		classes.addEntry(jarName, "MANIFEST",
				"protoj/**/* protoj-common/**/* protoj-exe/**/*", null);
		classes.getEntry(jarName).initConfig(new ArgRunnable() {
			public void run(ClassesArchive archive) {
				archive.getCurrentAssembleTask().initManifest("ProtoJ-Version",
						projectVersion);
				archive.initExecutableJar(ProtoExecutableMain.class.getName());
			}
		});
		classes.initExcludeArchives(jarName, "aspectjtools.jar");
	}

	/**
	 * Configures the artifacts for the dependencies archive.
	 */
	private void initProtoJar() {
		final String projectVersion = getVersion();

		// merge with just those lib jars that can't be found at
		// the maven central repository or with recent updates
		ClassesArchive classes = delegate.getArchiveFeature()
				.getClassesArchive();
		String jarName = getVersionedJarTag();

		classes.addEntry(jarName, "MANIFEST", "protoj/**/* protoj-common/**/*",
				null);
		classes.initClasspathLib(jarName);
		classes.getEntry(jarName).initConfig(new ArgRunnable() {
			public void run(ClassesArchive archive) {
				archive.getCurrentAssembleTask().initManifest("ProtoJ-Version",
						projectVersion);
				archive.initExecutableJar(ProtoExecutableMain.class.getName());
			}
		});
		String pomName = "/protoj-dev/pom.publish.xml";
		classes.initPublish(jarName, pomName, getGpgOptions());

		// creates a source code jar file
		SourceArchive source = delegate.getArchiveFeature().getSourceArchive();
		source.addEntry(jarName, null, null, null);
		source.getEntry(jarName).initConfig(new ArgRunnable() {
			public void run(SourceArchive archive) {
				archive.getCurrentAssembleTask().initManifest("ProtoJ-Version",
						projectVersion);
			}
		});

		// creates a javadoc jar file
		JavadocArchive archive = delegate.getArchiveFeature()
				.getJavadocArchive();
		archive.addEntry(jarName, null, null, null, "16m");
		archive.getEntry(jarName).initConfig(new ArgRunnable() {
			public void run(JavadocArchive archive) {
				archive.getCurrentAssembleTask().initManifest("ProtoJ-Version",
						projectVersion);
				archive.getJavadocTask().getjavadoc().setLinksource(true);
			}
		});
	}

	private String getGpgOptions() {
		return "--armor --local-user agwilliams1000 --output %2$s --detach-sign %1$s";
	}

	/**
	 * The downloaded jboss 5 and 6 zips are too big to include in the protoj
	 * jar file and so they are kept just under the source directory and copied
	 * when the serverdemo project is being created here.
	 * 
	 * @return
	 */
	public StandardProject createServerDemoProjectDelegate() {
		StandardProject demoDelegate = createSampleProject("serverdemo");
		File thisSrcDir = delegate.getLayout().getSrcDir();
		File demoSrcDir = demoDelegate.getLayout().getSrcDir();
		File jboss5 = new File(thisSrcDir, "jboss-5.0.1.GA.zip");
		FileUtils.copyFileToDirectory(jboss5, demoSrcDir);
		File jboss6 = new File(thisSrcDir, "jboss-5.0.1.GA-jdk6.zip");
		FileUtils.copyFileToDirectory(jboss6, demoSrcDir);
		return demoDelegate;
	}

	/**
	 * Ensures the executable jar file is present and executes it so that the
	 * requested sample project gets created. See {@link ProtoExecutableMain}
	 * for a list of the available sample projects.
	 * 
	 * @param projectName
	 *            the name of the sample project to create
	 * @return
	 */
	public StandardProject createSampleProject(String projectName) {
		createClassesArchives();
		AntTarget target = new AntTarget("sample");
		ProjectLayout layout = delegate.getLayout();
		target.initLogging(Project.MSG_INFO);
		Java java = new Java();
		target.addTask(java);
		java.setTaskName("sample-java");
		java.setJar(getExeFile());
		java.createArg().setValue("-sample");
		java.createArg().setValue(projectName);
		java.setFork(true);
		java.setFailonerror(true);
		java.setDir(layout.getTargetDir());
		target.execute();
		File rootDir = new File(layout.getTargetDir(), projectName);
		return new StandardProject(rootDir, projectName, null);
	}

	/**
	 * The executable jar we shall use to create the sample project. Helper for
	 * {@link #createSampleProject(String)}.
	 * 
	 * @return
	 */
	public File getExeFile() {
		ArchiveFeature feature = getDelegate().getArchiveFeature();
		ClassesArchive classes = feature.getClassesArchive();
		ClassesEntry entry = classes.getEntry(getVersionedExeJarTag());
		return entry.getArchiveEntry().getArtifact();
	}

	/**
	 * Just extracts the googlecode website files from the classpath resources
	 * and copies to the checked out wiki directory as a sibling of the protoj
	 * project root dir.
	 */
	public void extractSite() {
		File rootDir = delegate.getLayout().getRootDir();
		File wikiDir = new File(rootDir.getParentFile(), "wiki");
		if (!wikiDir.exists()) {
			String message = "checked out wiki directory is required: "
					+ wikiDir.getAbsolutePath();
			throw new RuntimeException(message);
		}
		ResourceFeature feature = getDelegate().getResourceFeature();
		File targetDir = getDelegate().getLayout().getTargetDir();
		File siteDir = new File(targetDir, "google-site");
		feature.filterResourceToDir("/protoj-dev/site/project-summary.wiki",
				siteDir);
		feature.filterResourceToDir(
				"/protoj-dev/site/wiki/AlternativeProjects.wiki", siteDir);
		feature.filterResourceToDir("/protoj-dev/site/wiki/BasicConcepts.wiki",
				siteDir);
		feature.filterResourceToDir(
				"/protoj-dev/site/wiki/BuildingFromSource.wiki", siteDir);
		feature.filterResourceToDir("/protoj-dev/site/wiki/CommandSetup.wiki",
				siteDir);
		feature.filterResourceToDir("/protoj-dev/site/wiki/Sidebar.wiki",
				siteDir);
		feature.filterResourceToDir(
				"/protoj-dev/site/wiki/UseCaseCompile.wiki", siteDir);
		feature.filterResourceToDir(
				"/protoj-dev/site/wiki/UseCaseProfile.wiki", siteDir);
		feature.filterResourceToDir("/protoj-dev/site/wiki/UseCaseDebug.wiki",
				siteDir);
		feature.filterResourceToDir(
				"/protoj-dev/site/wiki/UseCaseDependencies.wiki", siteDir);
		feature.filterResourceToDir("/protoj-dev/site/wiki/UseCaseDeploy.wiki",
				siteDir);
		feature.filterResourceToDir("/protoj-dev/site/wiki/UseCaseHelp.wiki",
				siteDir);
		feature.filterResourceToDir("/protoj-dev/site/wiki/UseCaseLog.wiki",
				siteDir);
		feature.filterResourceToDir(
				"/protoj-dev/site/wiki/UseCasePackage.wiki", siteDir);
		feature.filterResourceToDir(
				"/protoj-dev/site/wiki/UseCaseUploadMavenRepo.wiki", siteDir);
		feature.filterResourceToDir(
				"/protoj-dev/site/wiki/UseCaseUploadGoogleCode.wiki", siteDir);
		feature.filterResourceToDir(
				"/protoj-dev/site/wiki/UseCaseProfile.wiki", siteDir);
		feature.filterResourceToDir(
				"/protoj-dev/site/wiki/UseCasePackageRelationships.wiki",
				siteDir);
		feature.filterResourceToDir(
				"/protoj-dev/site/wiki/UseCaseSpecifyProperties.wiki", siteDir);
		feature.filterResourceToDir("/protoj-dev/site/wiki/UseCaseTest.wiki",
				siteDir);
		feature.filterResourceToDir(
				"/protoj-dev/site/wiki/DemoJbossProject.wiki", siteDir);
		feature.filterResourceToDir(
				"/protoj-dev/site/wiki/DemoAlienProject.wiki", siteDir);
		feature.filterResourceToDir(
				"/protoj-dev/site/wiki/DemoBasicProject.wiki", siteDir);
		feature.filterResourceToDir(
				"/protoj-dev/site/wiki/DemoHelloWorldProject.wiki", siteDir);

		File srcDir = new File(siteDir, "protoj-dev/site/wiki");
		FileUtils.copyDirectory(srcDir, wikiDir);
	}

	/**
	 * Extracts the javadoc files from the javadoc jar file into the docs/api
	 * directory. That directory should not yet exist and should be deleted from
	 * source control first of all.
	 */
	public void extractJavadocs() {
		File dest = new File(delegate.getLayout().getDocsDir(), "api");
		if (dest.exists()) {
			String message = "first delete the javadoc directory from source control: "
					+ dest.getAbsolutePath();
			throw new RuntimeException(message);
		}
		dest.mkdir();

		// get hold of the javadoc jar file
		ArchiveFeature feature = getDelegate().getArchiveFeature();
		JavadocArchive archive = feature.getJavadocArchive();
		JavadocEntry entry = archive.getEntry(getVersionedJarTag());
		File javadocJar = entry.getArchiveEntry().getArtifact();

		AntTarget target = new AntTarget("serverdemo-project");
		target.initLogging(Project.MSG_INFO);

		// adds a task to expand the jboss zip file
		Expand expand = new Expand();
		target.addTask(expand);
		expand.setTaskName("expand");
		expand.setSrc(javadocJar);
		expand.setDest(dest);
		target.execute();
	}

	/**
	 * Creates all the archives by delegating to
	 * {@link #createClassesArchives()} and {@link #createInfoArchives()}.
	 */
	public void createAllArchives() {
		createClassesArchives();
		createInfoArchives();
	}

	/**
	 * A custom archive use-case for ProtoJ. The exe jar file needs to contain
	 * all the other jar files inside it so that the sample projects can be
	 * expanded with everything they need. This includes the protoj jar file
	 * also. Therefore we build the protoj jar file first, then copy the lib
	 * directory contents over to the protoj-exe dir under the classes directory
	 * and then create the exe jar file as normal to pick them all up.
	 */
	public void createClassesArchives() {
		// create the protoj archive which will be included in the exe archive
		ArchiveFeature archive = delegate.getArchiveFeature();
		archive.getClassesArchive().createArchive(getVersionedJarTag());

		// copy lib dir to resources/proto-exe
		File srcDir = delegate.getLayout().getLibDir();
		File destDir = new File(delegate.getLayout().getClassesDir(),
				"protoj-exe/common/lib");
		destDir.mkdirs();
		DependencyStore store = delegate.getDependencyStore();
		Collection infos = store.getDependencies();
		// first copy all the project dependencies
		for (DependencyInfo info : infos) {
			String jarName = info.getJarName();
			File srcFile = new File(srcDir, jarName);
			FileUtils.copyFileToDirectory(srcFile, destDir);
		}

		// create the exe archive that also contains lib dir for sample projects
		archive.getClassesArchive().createArchive(getVersionedExeJarTag());
	}

	/**
	 * Creates just the sources and javadoc archives.
	 */
	public void createInfoArchives() {
		ArchiveFeature archive = delegate.getArchiveFeature();
		archive.getJavadocArchive().createArchive(getVersionedJarTag());
		archive.getSourceArchive().createArchive(getVersionedJarTag());
	}

	/**
	 * Configures ProtoJ from the default profile with no interpolation. Peforms
	 * a clean first.
	 */
	public void configureDefault() {
		delegate.getDirconfFeature().clean("default");
		delegate.getDirconfFeature().configure("default", false);
	}

	/**
	 * Dispatches any commands held by this project.
	 */
	public void dispatchCommands() {
		delegate.getDispatchFeature().dispatchCommands();
	}

	/**
	 * The command used to invoke release functionality.
	 * 
	 * @return
	 */
	public ReleaseCommand getReleaseCommand() {
		return releaseCommand;
	}

	/**
	 * The command used to configure ProtoJ.
	 * 
	 * @return
	 */
	public ProtoconfCommand getProtoconfCommand() {
		return protoconfCommand;
	}

	/**
	 * The command used to create documentation for the protoj googlecode
	 * website.
	 * 
	 * @return
	 */
	public DocsCommand getSiteCommand() {
		return siteCommand;
	}

	/**
	 * Delegate helper responsible for implementing the release procedure.
	 * 
	 * @return
	 */
	public ReleaseFeature getReleaseFeature() {
		return releaseFeature;
	}

	/**
	 * A reference to the delegate object used to create a sample project. See
	 * {@link SampleProjectFeature}.
	 * 
	 * @return
	 */
	public SampleProjectFeature getSampleProjectFeature() {
		return sampleProjectFeature;
	}

	/**
	 * The main protoj domain object.
	 * 
	 * @return
	 */
	public StandardProject getDelegate() {
		return delegate;
	}

	/**
	 * The name of the protoj jar file with the version number but no extension.
	 * 
	 * @return
	 */
	public String getVersionedJarTag() {
		return getProtoArtifact().getArtifactId() + "-"
				+ getProtoArtifact().getVersion();
	}

	/**
	 * The complete name of the maximum dependencies jar file as deployed to
	 * maven.
	 * 
	 * @return
	 */
	public String getJarName() {
		return getProtoArtifact().getVersionedJarName();
	}

	/**
	 * The project version number.
	 * 
	 * @return
	 */
	public String getVersion() {
		return getProtoArtifact().getVersion();
	}

	/**
	 * The name of the executable protoj jar file with the version number but no
	 * extension.
	 * 
	 * @return
	 */
	public String getVersionedExeJarTag() {
		return getExeJarTag() + "-" + getVersion();
	}

	/**
	 * The name of the executable protoj jar file without the version number or
	 * extension.
	 * 
	 * @return
	 */
	public String getExeJarTag() {
		String tag;
		if (delegate.isJdk6()) {
			tag = "protoj-exe-jdk6";
		} else {
			tag = "protoj-exe-jdk5";
		}
		return tag;
	}

	/**
	 * The complete name of the executable jar file as deployed on google code.
	 * 
	 * @return
	 */
	public String getExeJarName() {
		return getVersionedExeJarTag() + ".jar";
	}

	/**
	 * The ProtoJ home directory.
	 * 
	 * @return
	 */
	public File getProjectHome() {
		String userHome = System.getProperty("user.home");
		return new File(userHome, ".protoj");
	}

	/**
	 * ProtoJ artifacts are deployed to the maven central repository, this is
	 * the url.
	 * 
	 * @return
	 */
	public String getCentralRepositoryUrl() {
		return "http://repo1.maven.org/maven2/com/google/code/protoj/";
	}

	/**
	 * The google code project url for ProtoJ.
	 * 
	 * @return
	 */
	public String getProjectUrl() {
		return "http://code.google.com/p/protoj/" + getVersion();
	}

	/**
	 * The browsable subversion url for the project. This is up to an including
	 * the root of just this release.
	 * 
	 * @return
	 */
	public String getBrowsableUrl() {
		return "http://code.google.com/p/protoj/source/browse/" + getVersion();
	}

	/**
	 * The googlecode download url for the project artifacts.
	 * 
	 * @return
	 */
	public String getDownloadUr() {
		return "http://protoj.googlecode.com/files";
	}

	/**
	 * The url for downloading the executable jar from googlecode.
	 * 
	 * @return
	 */
	public String getExeDownloadUrl() {
		return getDownloadUr() + "/" + getExeJarName();
	}

	/**
	 * The artifact description of the ProtoJ artifact being deployed.
	 * 
	 * @return
	 */
	public DependencyInfo getProtoArtifact() {
		return delegate.getDependencyStore().getProtoj();
	}

	/**
	 * The ProtoJ project is the only project that can't have the protoj jar
	 * file as a dependency, since it is responsible for creating that jar. So
	 * this method returns the list of all dependencies minus the protoj jar.
	 */
	public ArrayList getStrictDependencies() {
		return strictDependencies;
	}

	/**
	 * The ProtoJ project is the only project that can't have the protoj jar
	 * file as a dependency, since it is responsible for creating that jar. So
	 * this method returns the list of dependencies available from the
	 * repository minus the protoj jar.
	 */
	public ArrayList getStrictRepoDependencies() {
		return strictRepoDependencies;
	}

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy