// -*- mode: java; c-basic-offset: 2; -*- // Copyright 2009-2011 Google, All Rights reserved // Copyright 2011-2012 MIT, All rights reserved // Released under the Apache License, Version 2.0 // http://www.apache.org/licenses/LICENSE-2.0 package com.google.appinventor.buildserver; import com.google.common.base.Preconditions; import com.google.common.collect.Lists; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.util.List; import java.util.Properties; import java.util.logging.Logger; /** * This class gives access to Young Android project files. * * <p>A Young Android project file is essentially a Java properties file. * * @author markf@google.com (Mark Friedman) */ public final class Project { /** * Representation of a source file containing its name and file location. */ public static class SourceDescriptor { // Qualified name of the class defined by the source file private final String qualifiedName; // File descriptor for the source private final File file; private SourceDescriptor(String qualifiedName, File file) { this.qualifiedName = qualifiedName; this.file = file; } /** * Returns the qualified name of the class defined by the source file. * * @return class name of source file */ public String getQualifiedName() { return qualifiedName; } /** * Returns a file descriptor for the source file * * @return file descriptor */ public File getFile() { return file; } } /* * Property tags defined in the project file: * * main - qualified name of main form class * name - application name * icon - application icon * versioncode - version code * versionname - version name * source - comma separated list of source root directories * assets - assets directory (for image and data files bundled with the application) * build - output directory for the compiler */ private static final String MAINTAG = "main"; private static final String NAMETAG = "name"; private static final String ICONTAG = "icon"; private static final String SOURCETAG = "source"; private static final String VCODETAG = "versioncode"; private static final String VNAMETAG = "versionname"; private static final String ASSETSTAG = "assets"; private static final String BUILDTAG = "build"; private static final String USESLOCATIONTAG = "useslocation"; private static final String ANAMETAG = "aname"; // Table containing project properties private Properties properties; // Project directory. This directory contains the project.properties file. private String projectDir; // Build output directory override, or null. private String buildDirOverride; // List of source files private List<SourceDescriptor> sources; // Logging support private static final Logger LOG = Logger.getLogger(Project.class.getName()); /** * Creates a new Young Android project descriptor. * * @param projectFile path to project file */ public Project(String projectFile) { this(new File(projectFile)); } /** * Creates a new Young Android project descriptor. * * @param projectFile path to project file * @param buildDirOverride build output directory override, or null */ public Project(String projectFile, String buildDirOverride) { this(new File(projectFile)); this.buildDirOverride = buildDirOverride; } /** * Creates a new Young Android project descriptor. * * @param file project file */ public Project(File file) { try { File parentFile = Preconditions.checkNotNull(file.getParentFile()); projectDir = parentFile.getAbsolutePath(); // Load project file properties = new Properties(); FileInputStream in = new FileInputStream(file); try { properties.load(in); } finally { in.close(); } } catch (IOException e) { e.printStackTrace(); } } /** * Returns the name of the main form class * * @return main form class name */ public String getMainClass() { return properties.getProperty(MAINTAG); } /** * Sets the name of the main form class. * * @param main main form class name */ public void setMainClass(String main) { properties.setProperty(MAINTAG, main); } /** * Returns the name of the project (application). * * @return project name */ public String getProjectName() { return properties.getProperty(NAMETAG); } /** * Sets the name of the project (application) * * @param name project name */ public void setProjectName(String name) { properties.setProperty(NAMETAG, name); } /** * Returns the name of the icon * * @return icon name */ public String getIcon() { return properties.getProperty(ICONTAG); } /** * Sets the name of the icon * * @param icon icon name */ public void setIcon(String icon) { properties.setProperty(ICONTAG, icon); } /** * Returns the version code. * * @return version code */ public String getVCode() { return properties.getProperty(VCODETAG); } /** * Sets the version code. * * @param vcode version code */ public void setVCode(String vcode) { properties.setProperty(VCODETAG, vcode); } /** * Returns the version name. * * @return version name */ public String getVName() { return properties.getProperty(VNAMETAG); } /** * Sets the version name. * * @param vname version name */ public void setVName(String vname) { properties.setProperty(VNAMETAG, vname); } /** * gets the useslocation property * * @return useslocation property */ public String getUsesLocation() { String retval = properties.getProperty(USESLOCATIONTAG); if (retval == null) // Older Projects won't have this retval = "False"; return retval; } /** * Returns the app name. * * @return app name */ public String getAName() { //The non-English character set can't be shown properly and need special encoding. String appName = properties.getProperty(ANAMETAG); try { appName = new String(appName.getBytes("ISO-8859-1"), "UTF-8"); } catch (UnsupportedEncodingException e) { } catch (NullPointerException e) { } return appName; } /** * Sets the app name. * * @param aname app name */ public void setAName(String aname) { properties.setProperty(ANAMETAG, aname); } /** * Returns the project directory. This directory contains the project.properties file. * * @return project directory */ public String getProjectDir() { return projectDir; } /** * Returns the location of the assets directory. * * @return assets directory */ public File getAssetsDirectory() { return new File(projectDir, properties.getProperty(ASSETSTAG)); } /** * Returns the location of the build output directory. * * @return build output directory */ public File getBuildDirectory() { if (buildDirOverride != null) { return new File(buildDirOverride); } return new File(projectDir, properties.getProperty(BUILDTAG)); } /* * Recursively visits source directories and adds found Young Android source files to the list of * source files. */ private void visitSourceDirectories(String root, File file) { if (file.isDirectory()) { // Recursively visit nested directories. for (String child : file.list()) { visitSourceDirectories(root, new File(file, child)); } } else { // Add Young Android source files to the source file list if (file.getName().endsWith(YoungAndroidConstants.YAIL_EXTENSION)) { String absName = file.getAbsolutePath(); String name = absName.substring(root.length() + 1, absName.length() - YoungAndroidConstants.YAIL_EXTENSION.length()); sources.add(new SourceDescriptor(name.replace(File.separatorChar, '.'), file)); } } } /** * Returns a list of Yail files in the project. * * @return list of source files */ public List<SourceDescriptor> getSources() { // Lazily discover source files if (sources == null) { sources = Lists.newArrayList(); String sourceTag = properties.getProperty(SOURCETAG); for (String sourceDir : sourceTag.split(",")) { File dir = new File(projectDir + File.separatorChar + sourceDir); visitSourceDirectories(dir.getAbsolutePath(), dir); } } return sources; } }