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

protoj.lang.StandardProject 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;

import java.io.File;

import org.apache.log4j.Logger;

import protoj.lang.command.StandardCommands;

/**
 * This is the starting point class for all projects that wish to take advantage
 * of ProtoJ pure java use-cases from compilation and javadoc generation to
 * installation and configuration. There is no need to construct any other
 * protoj class other than this one as it is the domain object that aggregates
 * all the others. Neither is there any need to write even one line of xml -
 * that is unless you take advantage of the dependency download feature or
 * artifact publish feature, which use the xml based ivy/maven API.
 * 

* Although there are many classes in the ProtoJ library many of them are inside * packages qualified with *internal* which means they are implementation * classes. This leaves little more than a couple of dozen pojos to get to grips * with in order to gain an understanding of ProtoJ. You can find these classes * directly under the protoj.lang packages. *

* To get started simply embed an instance of StandardProject in your own pojo * and invoke the initXXX() methods for features that you wish to use and use * the {@link CommandStore} domain object to add your own project specific * commands. Here is a simple but complete example of a class called * foo.Foo: * *

 * package protoj.lang.internal.sample;
 * 
 * import protoj.lang.StandardProject;
 * 
 * final class Foo {
 * 	public static void main(String[] args) {
 * 		StandardProject project = new StandardProject(args, "Foo Version 1.0");
 * 		project.getCompileFeature().initConfig(false,
 * 				new ArgRunnable<CompileFeature>() {
 * 					public void run(CompileFeature feature) {
 * 						feature.getJavacCompileTask().getCompileTask()
 * 								.setMemoryMaximumSize("16m");
 * 						feature.getJavacCompileTask().getCompileTask()
 * 								.setSource("1.5");
 * 					}
 * 				});
 * 		project.initJunit("16m");
 * 		project.getArchiveFeature().initProjectArchive("foo", "foo-1.0-RC1");
 * 		project.getArchiveFeature().addClasses("foo-1.0");
 * 		project.getArchiveFeature().addSources("foo-1.0");
 * 		project.getArchiveFeature().addJavadoc("foo-1.0", "16m");
 * 		project.getCommandStore().addCommand("hello-foo",
 * 				"writes to the console", "16m", new Runnable() {
 * 					public void run() {
 * 						System.out.println("Hello Foo!");
 * 					}
 * 				});
 * 		project.getDispatchFeature().dispatchCommands();
 * 	}
 * }
 * 
* * Take a look at {@link ProjectLayout} to find out more about the directory * structure of a ProtoJ project and where the java code in particular should be * placed. Be sure to modify the demo project though rather than creating a new * project from scratch each time - do this by executing the no-dependencies * ProtoJ jar file with java -jar. *

* In order to get to this world of pure java, some mechanism must take * responsibility for compiling and running the application in the first place * and one solution is to use a shell script. Check out demo.sh and * demo.bat from the demo project for some examples. Here is the * call to java from a typical bash shell script: * *

 * java ... helloworld.HelloWorld "init --rootDir `pwd`/.. --scriptName $0" "$@"
 * 
* * Note the special init command is specified as an argument to * java, with the mandatory --rootDir and --scriptName * options that protoj requires in order to function: * * And also note the use of the bash $@ place-holder so that * additional commands such as compile, jar and * test can be specified at the command line. * * @author Ashley Williams * */ public final class StandardProject { /** * See {@link #getPropertyStore()} */ private PropertyStore propertyStore; /** * See {@link #getDependencyStore()} */ private DependencyStore dependencyStore; /** * See {@link #getProperties()} */ private StandardProperties properties; /** * See {@link #getCommandStore()} */ private CommandStore commandStore; /** * See {@link #getCommands()}. */ private StandardCommands commands; /** * See {@link #getLayout()}. */ private ProjectLayout layout; /** * See {@link #getProtoLogger()}. */ private ProtoLogger protoLogger; /** * See {@link #getInstructionChain()}. */ private InstructionChain instructionChain; /** * See {@link #getRetrieveFeature()}. */ private RetrieveFeature retrieveFeature; /** * See {@link #getDispatchFeature()}. */ private DispatchFeature dispatchFeature; /** * See {@link #getCompileFeature()}. */ private CompileFeature compileFeature; /** * See {@link #getResourceFeature()}. */ private ResourceFeature resourceFeature; /** * See {@link #getInfoFeature()}. */ private InfoFeature infoFeature; /** * See {@link #getPublishFeature()}. */ private PublishFeature publishFeature; /** * See {@link #getJunitFeature()}. */ private JunitFeature junitFeature; /** * See {@link #getArchiveFeature()}. */ private ArchiveFeature archiveFeature; /** * See {@link #getUploadGoogleCodeFeature()}. */ private UploadGoogleCodeFeature uploadGoogleCodeFeature; /** * See {@link #getScpFeature()}. */ private ScpFeature scpFeature; /** * See {@link #getDirconfFeature()}. */ private DirconfFeature dirconfFeature; /** * See {@link #getVerifyTarFeature()}. */ private VerifyTarFeature verifyTarFeature; /** * See {@link #getScpconfFeature()}. */ private ScpconfFeature scpconfFeature; /** * Most projects should use this constructor. *

* Parses arguments originating from main(). The easiest way to * describe the format is with an example: * *

	 * compile "find-alien -gx milky-way" --rootDir ˜/dev/myproj/ --scriptName alien.sh -Dprotoj.debug
	 * 
* * which results in the following args array elements: *

*

    *
  • arg[0]="compile" - command with no arguments
  • *
  • arg[1]="find-alien -gx milky-way" - command with a * single argument
  • *
  • arg[2]="--rootDir" - the project root directory option * name
  • *
  • arg[3]="~/dev/myproj/" - the project root directory * option value
  • *
  • arg[4]="--scriptName" - the project script name option * name
  • *
  • arg[5]="alien.sh" - the project script name option value *
  • *
  • arg[6]="-Dprotoj.debug" - system property
  • *
* So in other words the two types of argument are commands and system * properties. Also the rootDir and scriptName options are mandatory and * used to calculate the project layout - see {@link InstructionChain} for * more information *

* Note that although -D syntax is used for the vm arguments, * these are not the same as the genuine vm arguments that won't appear in * the args parameter at all. This is because we need to store * them so that they can successfully be passed to any new virtual machines * that need starting. * * @param args * these should be the arguments from main() * @param versionInfo * any information to be reported when the version command is * invoked */ public StandardProject(String[] args, String versionInfo) { this(new InstructionChain(args), versionInfo); } /** * This constructor is useful in situations where the commands have to built * up in-code rather than parsed from a command line. For example in unit * tests and also in {@link VerifyTarFeature}. * * @param rootDir * the root directory of the project * @param scriptName * the name of the script responsible for issuing commands - if * no extension is given then ".bat" is assumed for windows and * ".sh" otherwise * @param versionInfo * any information to be reported when the version command is * invoked */ public StandardProject(File rootDir, String scriptName, String versionInfo) { this(new InstructionChain(rootDir, scriptName), versionInfo); } /** * This constructor gets the root dir and script name information from the * protoj.rootDir and protoj.scriptName system properties configured by * junit. So this constructor is intended for junit tests. * * @param versionInfo */ public StandardProject(String versionInfo) { this(new File(System.getProperty("protoj.rootDir")), System .getProperty("protoj.scriptName"), versionInfo); } /** * Common implementation for all constructors. * * @param core * @param versionInfo */ private StandardProject(InstructionChain instructionChain, String versionInfo) { this.instructionChain = instructionChain; this.layout = new ProjectLayout(instructionChain.getRootDir(), instructionChain.getScriptName()); this.protoLogger = new ProtoLogger(this); this.commandStore = new CommandStore(this); this.propertyStore = new PropertyStore(this); this.dependencyStore = new DependencyStore(this); this.properties = new StandardProperties(this); this.dispatchFeature = new DispatchFeature(this); this.resourceFeature = new ResourceFeature(this); this.compileFeature = new CompileFeature(this); this.retrieveFeature = new RetrieveFeature(this); this.infoFeature = new InfoFeature(this, versionInfo); this.verifyTarFeature = new VerifyTarFeature(this); this.archiveFeature = new ArchiveFeature(this); this.commands = new StandardCommands(this); this.scpFeature = new ScpFeature(this); } /** * This method must be called if you wish to be able to publish project * artifacts created with the {@link ArchiveFeature} class. * * @param url */ public void initPublish(String url) { this.publishFeature = new PublishFeature(this, url); } /** * This method must be called if junit tests are required, in order to * specify the amount of memory required. Invoke junit funtionality by first * obtaining the delegate with a call to {@link #getJunitFeature()}. * * @param memory * uses standard java tool notation, e.g. "32m" */ public void initJunit(String memory) { this.junitFeature = new JunitFeature(this, memory); } /** * This method must be called if configuration with properties files from a * mounted directory is to be supported. Pass-thru method to * {@link DirconfFeature#DirconfFeature(StandardProject)}. */ public void initDirConfig() { this.dirconfFeature = new DirconfFeature(this); } /** * This method must be called if configuration with properties files from a * mounted directory is to be supported. Pass-thru method to * {@link DirconfFeature#DirconfFeature(StandardProject, File)}. * * @param home */ public void initDirConfig(File home) { this.dirconfFeature = new DirconfFeature(this, home); } /** * This method must be called if configuration with properties files from a * remotely located directory is to be supported. Pass-thru method to * {@link ScpconfFeature#ScpconfFeature(StandardProject, String)} . * * @param parentUrl */ public void initScpConfig(String parentUrl) { this.scpconfFeature = new ScpconfFeature(this, parentUrl); } /** * This method must be called if the ability to upload the project tar file * to google code is required. This is a pass-through method to * {@link UploadGoogleCodeFeature#UploadGoogleCodeFeature(StandardProject, String)} * , so see that constructor for a description of the parameters. *

* Note that there is no corresponding out of the box command for this * feature. That's because it would be too generic to be useful due to the * many pieces of information that would need to be specified at the command * line. Projects would be best served by writing their own commands with * the information hardcoded, such as the artifact name etc. * * @param googleProjectName */ public void initUploadGoogleCode(String googleProjectName) { uploadGoogleCodeFeature = new UploadGoogleCodeFeature(this, googleProjectName); } /** * Creates a helper that is able to drive the project represented by this * class instance through its command line interface. Very useful for tests * for example that need to go through the script as the user would. * * @return */ public ScriptSession createScriptSession() { return new ScriptSession(getLayout().getShellScript()); } /** * A reference to the delegate object used to extract resources to the * filing system for APIs that can only work in this way and also apply * variable ${var} substitutions. See {@link ResourceFeature}. * * @return */ public ResourceFeature getResourceFeature() { return resourceFeature; } /** * A reference to the delegate object used to dispatch the instructions * usually specified at the command line. See {@link DispatchFeature}. * * @return */ public DispatchFeature getDispatchFeature() { return dispatchFeature; } /** * A reference to the delegate object used to perform in-code compilation . * See {@link CompileFeature}. * * @return */ public CompileFeature getCompileFeature() { return compileFeature; } /** * A reference to the delegate object used to download project dependencies. * See {@link RetrieveFeature}. * * @return */ public RetrieveFeature getRetrieveFeature() { return retrieveFeature; } /** * A reference to the delegate object used to provide configuration * functionality. See {@link JunitFeature}. * * @return */ public JunitFeature getJunitFeature() { return junitFeature; } /** * A reference to the delegate object used to provide archive creation * functionality. See {@link ArchiveFeature}. * * @return */ public ArchiveFeature getArchiveFeature() { return archiveFeature; } /** * A reference to the delegate object used to provide configuration * functionality. See {@link VerifyTarFeature}. * * @return */ public VerifyTarFeature getVerifyTarFeature() { return verifyTarFeature; } /** * A reference to the delegate object used to provide the google code upload * functionality. See {@link UploadGoogleCodeFeature}. * * @return */ public UploadGoogleCodeFeature getUploadGoogleCodeFeature() { return uploadGoogleCodeFeature; } /** * A reference to the delegate object used to provide scp functionality. See * {@link ScpFeature}. * * @return */ public ScpFeature getScpFeature() { return scpFeature; } /** * A reference to the delegate object used to provide configuration * functionality. See {@link DirconfFeature}. * * @return */ public DirconfFeature getDirconfFeature() { return dirconfFeature; } /** * A reference to the delegate object used to provide configuration * functionality. See {@link ScpconfFeature}. * * @return */ public ScpconfFeature getScpconfFeature() { return scpconfFeature; } /** * A reference to the delegate object used to provide project information * functionality. See {@link InfoFeature}. * * @return */ public InfoFeature getInfoFeature() { return infoFeature; } /** * A reference to the delegate object used to publish project artifacts. See * {@link PublishFeature}. * * @return */ public PublishFeature getPublishFeature() { return publishFeature; } /** * Access to the class responsible for containing all the instructions to be * dispatched. * * @return */ public InstructionChain getInstructionChain() { return instructionChain; } /** * Delegated functionality, see {@link CommandStore}. * * @return */ public CommandStore getCommandStore() { return commandStore; } /** * A container of references of those commands belonging to this project * that have been added to the {@link CommandStore}. * * @return */ public StandardCommands getCommands() { return commands; } /** * A container of project dependencies belonging to this project. See * {@link DependencyStore}. * * @return */ public DependencyStore getDependencyStore() { return dependencyStore; } /** * Delegated functionality, see {@link PropertyStore}. * * @return */ public PropertyStore getPropertyStore() { return propertyStore; } /** * A container of references of those properties belonging to this * StandardProject that have been added to the {@link PropertyStore}. * * @return */ public StandardProperties getProperties() { return properties; } /** * Delegated functionality, see {@link ProtoLogger}. * * @return */ public ProtoLogger getProtoLogger() { return protoLogger; } /** * Access to the protoj log4j instance. Convenient short-hand for * getProtoLogger().getProtoLogger(). * * @return */ public Logger getLogger() { return protoLogger.getProtoLogger(); } /** * Delegated functionality, see {@link ProjectLayout}. * * @return */ public ProjectLayout getLayout() { return layout; } /** * True if version 6, otherwise version 5 is assumed. ProtoJ doesn't support * lesser versions. * * @return */ public boolean isJdk6() { String version = System.getProperty("java.specification.version"); return version.contains("6"); } /** * The ProtoJ project version number. * * @return */ public String getProtojVersion() { return "1.9.2"; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy