![JAR search and dependency download from the Maven repository](/logo.png)
protoj.lang.ProjectLayout Maven / Gradle / Ivy
Show all versions of protoj-jdk6 Show documentation
/**
* 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.commons.io.FileUtils;
import org.apache.tools.ant.taskdefs.Chmod;
import org.apache.tools.ant.types.DirSet;
import org.apache.tools.ant.types.FileSet;
import org.apache.tools.ant.types.Path;
import protoj.util.AntTarget;
import protoj.util.ArgRunnable;
/**
* Contains the locations of the various project directories. A typical project
* looks something like this:
*
*
*
* ˜/dev/myproj/
* |
* |____bin/ shell scripts should go here
* |
* |____classes/ java source files get compiled into here (auto-created)
* |
* |____conf/ configuration files should go here
* | |
* | |____profile/ configuration profiles should go here
* |
* |____docs/ documentation files should go here
* |
* |____lib/ third party libs should go here
* |
* |____log/ log files should go here
* |
* |____src/
* | |
* | |____java/ .java and .aj source files should go here
* | |
* | |____manifest/ manifest.mf files should go here, one per jar file
* | |
* | |____resources/ additional content for the classes directory and/or jar files should go here
* |
* |____target/ all-purpose project temp directory (auto-created)
* |
* |____archive/ java archives get generated here (auto-created)
* |
* |____junit-reports/ junit test reports get generated here (auto-created)
*
*
* Here is some insight into the directory structure:
*
* - The java and classes directories are used to contain the source code and
* resulting class files on compilation respectively
* - The lib directory is where third party libraries should be placed.
* - Because multiple jar files can be created there is a manifest directory
* that can contain many different manifest files, one for every jar file.
* - Some of the directories are marked 'auto-created' and so will be created
* as needed. All other directories should be created manually.
*
*
* This is an immutable value object that is usually aggregated within a
* StandardProject parent, but can also be created in its own right - especially
* for tests that need to check details about directory structures.
*
* @author Ashley Williams
*
*/
public final class ProjectLayout {
/**
* Configures a classpath that points to the lib
and
* classes
directories. Sources and javadocs archives aren't
* included.
*
* @author Ashley Williams
*
*/
private final class DefaultClasspathConfig implements ArgRunnable {
public void run(Path classpath) {
getClassesDir().mkdirs();
DirSet classes = new DirSet();
classes.setDir(getClassesDir().getParentFile());
classes.setIncludes(getClassesDir().getName());
classpath.addDirset(classes);
FileSet libs = new FileSet();
libs.setDir(getLibDir());
String libExcludesPattern = String.format(
"*%s.jar *%s.jar *%s.jar", getJavadocPostfix(),
getSourcePostfix(), getSrcPostfix());
libs.setExcludes(libExcludesPattern);
classpath.addFileset(libs);
}
}
/**
* See {@link #getShellScript()}.
*/
private final File shellScript;
/**
* See {@link #getRootDir()}.
*/
private final File rootDir;
/**
* See {@link #getBinDir()}.
*/
private final File binDir;
/**
* See {@link #getDocsDir()}.
*/
private final File docsDir;
/**
* See {@link #getArchiveDir()}.
*/
private final File archiveDir;
/**
* See {@link #getSrcDir()}.
*/
private final File srcDir;
/**
* See {@link #getJavaDir()}.
*/
private final File javaDir;
/**
* See {@link #getLibDir()}.
*/
private final File libDir;
/**
* See {@link #getTargetDir()}.
*/
private final File targetDir;
/**
* See {@link #getClassesDir()}.
*/
private final File classesDir;
/**
* See {@link #getResourcesDir()}.
*/
private final File resourcesDir;
/**
* See {@link #getManifestDir()}.
*/
private final File manifestDir;
/**
* See {@link #getLogDir()}.
*/
private final File logDir;
/**
* See {@link #getConfDir()}.
*/
private final File confDir;
/**
* See {@link #getPropertiesFile()}.
*/
private final File propertiesFile;
/**
* See {@link #getLogFile()}.
*/
private final File logFile;
/**
* See {@link #getJunitReportsDir()}.
*/
private final File junitReportsDir;
/**
* See {@link #getClasspathConfig()}.
*/
private final ArgRunnable classpathConfig = new DefaultClasspathConfig();
/**
* See {@link #getScriptName()}.
*/
private String scriptName;
/**
* See {@link #getSourcePostfix()}.
*/
public String sourcePostfix;
/**
* See {@link #getSrcPostfix()}.
*/
public String srcPostfix;
/**
* See {@link #getJavadocPostfix()}.
*/
private String javadocPostfix;
/**
* Calculates all project paths under the given rootDir
. An
* exception is thrown if any of the physical mandatory directories are
* missing.
*
* @param rootDir
* the project root directory
* @param scriptName
* the name of the launch script with optional extension - see
* {@link #createScriptName(String)}.
*/
public ProjectLayout(File rootDir, String scriptName) {
this.rootDir = rootDir;
this.binDir = new File(getRootDir(), "bin");
this.scriptName = createScriptName(scriptName);
this.shellScript = new File(getBinDir(), getScriptName())
.getCanonicalFile();
this.docsDir = new File(getRootDir(), "docs");
this.srcDir = new File(getRootDir(), "src");
this.logDir = new File(getRootDir(), "log");
this.confDir = new File(getRootDir(), "conf");
this.libDir = new File(getRootDir(), "lib");
this.classesDir = new File(getRootDir(), "classes");
this.javaDir = new File(getSrcDir(), "java");
this.resourcesDir = new File(getSrcDir(), "resources");
this.manifestDir = new File(getSrcDir(), "manifest");
this.targetDir = new File(getRootDir(), "target");
this.archiveDir = new File(getTargetDir(), "archive");
this.junitReportsDir = new File(getTargetDir(), "junit-reports");
this.logFile = new File(getLogDir(), "protoj.log");
this.propertiesFile = new File(getConfDir(), "all.project.properties");
this.sourcePostfix = "sources";
this.srcPostfix = "src";
this.javadocPostfix = "javadoc";
}
/**
* If the specified name already has an extension then it is returned.
* Otherwise the name is returned with an extension - ".bat" for windows or
* ".sh" otherwise.
*
* @param name
* @return
*/
private String createScriptName(String name) {
String scriptName;
if (name.contains(".")) {
scriptName = name;
} else {
String osName = System.getProperty("os.name").toUpperCase();
boolean isWindows = osName.indexOf("WINDOWS") >= 0;
scriptName = isWindows ? name + ".bat" : name + ".sh";
}
return scriptName;
}
/**
* Creates the project layout on the filing system.
*/
public void createPhysicalLayout() {
getRootDir().mkdirs();
getBinDir().mkdirs();
getDocsDir().mkdirs();
getSrcDir().mkdirs();
getLogDir().mkdirs();
getConfDir().mkdirs();
getLibDir().mkdirs();
getJavaDir().mkdirs();
getResourcesDir().mkdirs();
getManifestDir().mkdirs();
}
/**
* Apply 777 permissions all the way down the project structure.
*/
public void relaxPermissions() {
AntTarget target = new AntTarget("relax-permissions");
Chmod chmod = new Chmod();
chmod.setTaskName("sample-permissions");
target.addTask(chmod);
chmod.setDir(getRootDir().getParentFile());
chmod.setIncludes(getRootName() + "/**/*.*");
chmod.setPerm("777");
target.execute();
}
/*
* See {@link #getRootDir()}.
*
* @return
*/
public String getRootPath() {
return getRootDir().getAbsolutePath();
}
/**
* The directory where all the project files are located, e.g. ~/dev/myproj
*
* @return
*/
public File getRootDir() {
return rootDir;
}
/**
* Convenience method that returns the name of the root project directory.
*
* @return
*/
public String getRootName() {
return getRootDir().getName();
}
/**
* The directory containing the files such as shell scripts.
*
* @return
*/
public File getBinDir() {
return binDir;
}
/**
* The script responsible for executing the project.
*
* @return
*/
public File getShellScript() {
return shellScript;
}
/**
* Convenience method that returns the name of the shell script.
*
* @return
*/
public String getScriptName() {
return scriptName;
}
/**
* The directory containing documentation
*
* @return
*/
public File getDocsDir() {
return docsDir;
}
/**
* The directory where archives are generated.
*
* @return
*/
public File getArchiveDir() {
return archiveDir;
}
/**
* The directory containing the source files.
*
* @return
*/
public File getSrcDir() {
return srcDir;
}
/**
* The directory containing log files, e.g. ~/dev/myproj/log.
*
* @return
*/
public File getLogDir() {
return logDir;
}
/**
* The file used for logging, e.g. ~/dev/myproj/log/protoj.log
*
* @return
*/
public File getLogFile() {
return logFile;
}
/**
* The file that contains all the application properties when the config
* command is used with interpolation. That is all the properties files in a
* profile are combined into a single file (this one) and all ${} tokens are
* fully resolved.
*
* @return
*/
public File getPropertiesFile() {
return propertiesFile;
}
/**
* The directory containing configuration files, e.g. ~/dev/myproj/conf
*
* @return
*/
public File getConfDir() {
return confDir;
}
/**
* The directory containing compilation sources, e.g. ~/dev/myproj/src/java
*
* @return
*/
public File getJavaDir() {
return javaDir;
}
/**
* The directory containing resources, e.g. ~/dev/myproj/src/resources
*
* @return
*/
public File getResourcesDir() {
return resourcesDir;
}
/**
* The directory containing manifest files, e.g. ~/dev/myproj/src/manifest
*
* @return
*/
public File getManifestDir() {
return manifestDir;
}
/**
* The directory containing java libraries, e.g. ~/dev/myproj/lib
*
* @return
*/
public File getLibDir() {
return libDir;
}
/**
* The directory used for temporary files, e.g. ~/dev/myproj/target
*
* @return
*/
public File getTargetDir() {
return targetDir;
}
/**
* The directory containing .class compilation units, e.g.
* ~/dev/myproj/classes
*
* @return
*/
public File getClassesDir() {
return classesDir;
}
/**
* The directory containing junit reports, e.g.
* ~/dev/myproj/target/junit-reports.
*
* @return
*/
public File getJunitReportsDir() {
return junitReportsDir;
}
/**
* Convenience method that returns the fully qualified jar file given just
* its name.
*
* @param jarName
* @return
*/
public File getJar(String jarName) {
return new File(getLibDir(), jarName + ".jar");
}
/**
* Convenience method that returns the fully qualified manifest file given
* just its name.
*
* @param name
* @return
*/
public File getManifest(String name) {
return new File(getManifestDir(), name + ".MF");
}
/**
* The object used to configure classpaths. Adds the classes and lib
* directories.
*
* @return
*/
public ArgRunnable getClasspathConfig() {
return classpathConfig;
}
/**
* Forms part of the name of each sourceArchive archive.
*
* @return
*/
public String getSourcePostfix() {
return sourcePostfix;
}
/**
* Some archives contain the string "src" to indicate they are jar files
* that contain source.
*
* @return
*/
public String getSrcPostfix() {
return srcPostfix;
}
/**
* Forms part of the name of each javadocArchive archive.
*
* @return
*/
public String getJavadocPostfix() {
return javadocPostfix;
}
/**
* Calculates the relative path string of the child to the layout root dir.
* As an example for a root path of /usr/dev/project and a child path of
* /usr/dev/project/foo/bar, the relative path is foo/bar.
*
* @param child
* @return
*/
public String getRelativePath(File child) {
int relativePathPos = getRootDir().getAbsolutePath().length();
return child.getAbsolutePath().substring(relativePathPos + 1);
}
/**
* Loads the log from disk and reads its content into a string. Useful for
* examining small log files since entire content is pulled into memory.
*
* @return
*/
public String loadLog() {
return FileUtils.readFileToString(getLogFile());
}
}