Package org.objectstyle.woenvironment.pb

Source Code of org.objectstyle.woenvironment.pb.PBXProject

/* ====================================================================
*
* The ObjectStyle Group Software License, Version 1.0
*
* Copyright (c) 2002 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.woenvironment.pb;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

import org.objectstyle.woenvironment.pb.PBXProject.ObjectsTable.ID;
import org.objectstyle.woenvironment.plist.PropertyListParserException;
import org.objectstyle.woenvironment.plist.WOLPropertyListSerialization;

/**
* A <b>PBXProject</b> represents a Project Builder X project package (<code>*.pbproj</code>).
*
* @author Jonathan 'Wolf' Rentzsch
* @author Anjo Krank
*/
@SuppressWarnings("unchecked")
public class PBXProject {
  public void addSourceReference(String path) {
    if (!_sourceRefs.contains(path))
      _sourceRefs.add(path);
  }

  public void removeSourceReference(String path) {
      _sourceRefs.remove(path);
  }

  public void addResourceFileReference(String path) {
    if (!_resourceFileRefs.contains(path))
      _resourceFileRefs.add(path);
  }

  public void removeResourceFileReference(String path) {
      _resourceFileRefs.remove(path);
  }

  public void addResourceFolderReference(String path) {
    if (!_resourceFolderRefs.contains(path))
      _resourceFolderRefs.add(path);
  }

  public void removeResourceFolderReference(String path) {
      _resourceFolderRefs.remove(path);
  }

  public void addWSResourceFileReference(String path) {
    if (!_wsresourceFileRefs.contains(path))
      _wsresourceFileRefs.add(path);
  }

  public void removeWSResourceFileReference(String path) {
      _wsresourceFileRefs.remove(path);
  }

  public void addWSResourceFolderReference(String path) {
    if (!_wsresourceFolderRefs.contains(path))
      _wsresourceFolderRefs.add(path);
  }

  public void removeWSResourceFolderReference(String path) {
      _wsresourceFolderRefs.remove(path);
  }

  public void addFrameworkReference(String path) {
    if (!_frameworkRefs.contains(path))
      _frameworkRefs.add(path);
  }

  public void removeFrameworkReference(String path) {
      _frameworkRefs.remove(path);
  }

  public void save(File projectFile) throws PropertyListParserException, IOException {
    ObjectsTable objectsTable = new ObjectsTable();
    String projectPath;
    try {
      projectPath = projectFile.getCanonicalPath();
    } catch (IOException ex) {
      throw new RuntimeException("Can't get path of project file: " + projectFile);
    }
    int last = projectPath.lastIndexOf(File.separator);
    if (last != -1) {
      projectPath = projectPath.substring(0, last);
    }
    last = projectPath.lastIndexOf(File.separator);
    if (last != -1) {
      projectPath = projectPath.substring(0, last);
    }

    ArrayList sourceFileIDs = new ArrayList();
    ArrayList resourceFileIDs = new ArrayList();
    ArrayList wsresourceFileIDs = new ArrayList();
    ArrayList frameworkFileIDs = new ArrayList();

    // Walk refs, creating the appropriate reference type and an associated
    // build file for each and adding it to the objects table and group
    // children list.
    String path;
    Iterator it;

    it = _sourceRefs.iterator();
    while (it.hasNext()) {
      path = (String) it.next();
      if (path.indexOf(projectPath) == 0) {
        path = path.substring(projectPath.length() + 1);
      }
      File file = new File(path);
      Map reference = newFileReference(file.getName(), path);
      ObjectsTable.ID refID = objectsTable.insert(reference);
      sourceFileIDs.add(refID);
    }

    it = _resourceFileRefs.iterator();
    while (it.hasNext()) {
      path = (String) it.next();
      if (path.indexOf(projectPath) == 0) {
        path = path.substring(projectPath.length() + 1);
      }
      File file = new File(path);
      if (!_resourceFolderRefs.contains(projectPath + "/" + file.getParent())) {
        Map reference = newFileReference(file.getName(), path);
        ObjectsTable.ID refID = objectsTable.insert(reference);
        resourceFileIDs.add(refID);
      }
    }

    it = _resourceFolderRefs.iterator();
    while (it.hasNext()) {
      path = (String) it.next();
      if (path.indexOf(projectPath) == 0) {
        path = path.substring(projectPath.length() + 1);
      }
      File file = new File(path);
      Map reference = newFolderReference(file.getName(), path);
      ObjectsTable.ID refID = objectsTable.insert(reference);
      resourceFileIDs.add(refID);
    }

    it = _wsresourceFileRefs.iterator();
    while (it.hasNext()) {
      path = (String) it.next();
      if (path.indexOf(projectPath) == 0) {
        path = path.substring(projectPath.length() + 1);
      }
      File file = new File(path);
      if (!_wsresourceFolderRefs.contains(projectPath + "/" + file.getParent())) {
        Map reference = newFileReference(file.getName(), path);
        ObjectsTable.ID refID = objectsTable.insert(reference);
        wsresourceFileIDs.add(refID);
      }
    }

    it = _wsresourceFolderRefs.iterator();
    while (it.hasNext()) {
      path = (String) it.next();
      if (path.indexOf(projectPath) == 0) {
        path = path.substring(projectPath.length() + 1);
      }
      File file = new File(path);
      Map reference = newFolderReference(file.getName(), path);
      ObjectsTable.ID refID = objectsTable.insert(reference);
      wsresourceFileIDs.add(refID);
    }

    it = _frameworkRefs.iterator();
    while (it.hasNext()) {
      path = (String) it.next();
      Map reference = newFrameworkReference((new File(path)).getName(), path);
      ObjectsTable.ID refID = objectsTable.insert(reference);
      frameworkFileIDs.add(refID);
    }

    ArrayList childrenIDs = new ArrayList();
    childrenIDs.add(objectsTable.insert(newGroup("Sources", sourceFileIDs)));
    childrenIDs.add(objectsTable.insert(newGroup("Resources", resourceFileIDs)));
    childrenIDs.add(objectsTable.insert(newGroup("Web Server", wsresourceFileIDs)));
    childrenIDs.add(objectsTable.insert(newGroup("Frameworks", frameworkFileIDs)));

    // Create the PBXGroup and add it to the objects table.
    ObjectsTable.ID mainGroupID = objectsTable.insert(newGroup("Root", childrenIDs));

    // Create the PBXToolTarget and add it to the objects table and
    // the targets list.
    ArrayList targetIDs = new ArrayList(2);
    List phases;

    phases = newBuildPhaseList(sourceFileIDs, resourceFileIDs, wsresourceFileIDs, frameworkFileIDs, objectsTable);
    Map appServerTarget = newAppServerTarget(phases, objectsTable);

    phases = newBuildPhaseList(Collections.EMPTY_LIST, Collections.EMPTY_LIST, Collections.EMPTY_LIST, Collections.EMPTY_LIST, objectsTable);
    Map antTarget = newAntTarget(phases, objectsTable);

    phases = newBuildPhaseList(Collections.EMPTY_LIST, Collections.EMPTY_LIST, wsresourceFileIDs, Collections.EMPTY_LIST, objectsTable);
    Map webServerTarget = newWebServerTarget(phases, objectsTable);

    targetIDs.add(objectsTable.insert(appServerTarget));
    targetIDs.add(objectsTable.insert(antTarget));
    targetIDs.add(objectsTable.insert(webServerTarget));

    // Create the PBXProject and add it to the objects table.
    ObjectsTable.ID projectID = objectsTable.insert(newProject(mainGroupID, targetIDs, objectsTable));

    // Create the root dictionary.
    Map pbxproj = newPBXProj(objectsTable, projectID);

    WOLPropertyListSerialization.propertyListToFile("", projectFile, pbxproj);
  }

  protected List newBuildFileList(List fileIDs, ObjectsTable objectsTable) {
    List result = new ArrayList(fileIDs.size());
    for (Iterator iter = fileIDs.iterator(); iter.hasNext();) {
      ObjectsTable.ID refID = (ObjectsTable.ID) iter.next();
      result.add(objectsTable.insert(newBuildFile(refID)));
    }
    return result;
  }

  protected List newBuildPhaseList(List sourceFileIDs, List resourceFileIDs, List wsresourceFileIDs, List frameworkFileIDs, ObjectsTable objectsTable) {
    ArrayList buildPhaseIDs = new ArrayList(4);
    if (hasBuildPhases()) {
      buildPhaseIDs.add(objectsTable.insert(newSourcesBuildPhase(newBuildFileList(sourceFileIDs, objectsTable))));
      buildPhaseIDs.add(objectsTable.insert(newResourcesBuildPhase(newBuildFileList(resourceFileIDs, objectsTable))));
      buildPhaseIDs.add(objectsTable.insert(newWSResourcesBuildPhase(newBuildFileList(wsresourceFileIDs, objectsTable))));
      buildPhaseIDs.add(objectsTable.insert(newFrameworkBuildPhase(newBuildFileList(frameworkFileIDs, objectsTable))));
    }
    return buildPhaseIDs;
  }

  // ---------------------------------------------------------------
  // Implementation stuff.

  protected ArrayList _resourceFolderRefs = new ArrayList();

  protected ArrayList _resourceFileRefs = new ArrayList();

  protected ArrayList _wsresourceFolderRefs = new ArrayList();

  protected ArrayList _wsresourceFileRefs = new ArrayList();

  protected ArrayList _frameworkRefs = new ArrayList();

  protected ArrayList _sourceRefs = new ArrayList();

  protected Map map(Object[] keyValues) {
    Map result = new TreeMap();
    for (int i = 0; i < keyValues.length; i += 2) {
      result.put(keyValues[i], keyValues[i + 1]);
    }
    return result;
  }

  protected Map newFileReference(String name, String path) {
    return map(new Object[] { "isa", "PBXFileReference", "refType", (new File(path)).isAbsolute() ? "0" : "2", "name", name, "path", path });
  }

  protected Map newFolderReference(String name, String path) {
    return map(new Object[] { "isa", "PBXFolderReference", "refType", (new File(path)).isAbsolute() ? "0" : "2", "name", name, "path", path });
  }

  protected Map newFrameworkReference(String name, String path) {
    return map(new Object[] { "isa", "PBXFrameworkReference", "refType", "0", "name", name, "path", path });
  }

  protected Map newBuildFile(ObjectsTable.ID fileRefID) {
    return map(new Object[] { "isa", "PBXBuildFile", "fileRef", fileRefID });
  }

  protected Map newFrameworkBuildPhase(List buildFileIDs) {
    return map(new Object[] { "isa", "PBXFrameworksBuildPhase", "files", buildFileIDs });
  }

  protected Map newResourcesBuildPhase(List buildFileIDs) {
    return map(new Object[] { "isa", "PBXResourcesBuildPhase", "files", buildFileIDs });
  }

  protected Map newWSResourcesBuildPhase(List buildFileIDs) {
    return map(new Object[] { "isa", "PBXResourcesBuildPhase", "files", buildFileIDs });
  }

  protected Map newSourcesBuildPhase(List buildFileIDs) {
    return map(new Object[] { "isa", "PBXSourcesBuildPhase", "files", buildFileIDs });
  }

  protected Map newGroup(String name, List childrenIDs) {
    return map(new Object[] { "isa", "PBXGroup", "refType", "4", "name", name, "children", childrenIDs });
  }

  protected Map newAppServerTarget(List buildPhaseIDs, ObjectsTable objectsTable) {
    return map(new Object[] { "isa", "PBXToolTarget", "buildSettings", new HashMap(), "name", "Application Server", "buildPhases", buildPhaseIDs });
  }

  protected Map newWebServerTarget(List buildPhaseIDs, ObjectsTable objectsTable) {
    return map(new Object[] { "isa", "PBXToolTarget", "buildSettings", new HashMap(), "name", "Web Server", "buildPhases", buildPhaseIDs });
  }

  protected Map newAntTarget(List buildPhaseIDs, ObjectsTable objectsTable) {
    Map result = map(new Object[] { "isa", "PBXLegacyTarget", "buildArgumentsString", "-emacs $(ACTION)", "buildSettings", new HashMap(), "buildToolPath", "/Developer/Java/Ant/bin/ant", "passBuildSettingsInEnvironment", "1", "name", "Ant", "buildPhases", buildPhaseIDs });
    List<ID> buildConfigurations = new LinkedList<ID>();
    buildConfigurations.add(objectsTable.insert(newBuildConfiguration(map(new Object[] { "COPY_PHASE_STRIP", "NO" }), "Debug")));
    buildConfigurations.add(objectsTable.insert(newBuildConfiguration(map(new Object[] { "COPY_PHASE_STRIP", "YES" }), "Release")));
    buildConfigurations.add(objectsTable.insert(newBuildConfiguration(new HashMap(), "Default")));
    result.put("buildConfigurationList", objectsTable.insert(newBuildConfigurationList(buildConfigurations, false, "Default")));
    result.put("productName", "Ant");
    return result;
  }

  protected Map newBuildConfigurationList(List _buildConfigurations, boolean _defaultConfigurationIsVisible, String _defaultConfigurationName) {
    Map buildConfigurationList = map(new Object[] { "buildConfigurations", _buildConfigurations, "defaultConfigurationIsVisible", (_defaultConfigurationIsVisible) ? "1" : "0", "defaultConfigurationName", _defaultConfigurationName, "isa", "XCConfigurationList" });
    return buildConfigurationList;
  }

  protected Map newBuildStyle(Map _buildSettings, String _name) {
    return newBuildStyleOrConfiguration(_buildSettings, "PBXBuildStyle", _name);
  }

  // AK: this might be only for XCode and up
  protected Map newBuildConfiguration(Map _buildSettings, String _name) {
    return newBuildStyleOrConfiguration(_buildSettings, "XCBuildConfiguration", _name);
  }

  protected Map newBuildStyleOrConfiguration(Map _buildSettings, String _isa, String _name) {
    return map(new Object[] { "buildSettings", _buildSettings, "isa", _isa, "name", _name });
  }

  protected Map newProject(ObjectsTable.ID groupID, List targetIDs, ObjectsTable objectsTable) {
    return map(new Object[] { "isa", "PBXProject", "hasScannedForEncodings", "1", "projectDirPath", ".", "mainGroup", groupID, "targets", targetIDs });
  }

  protected Map newPBXProj(Map objectsTable, ObjectsTable.ID rootObject) {
    return map(new Object[] { "archiveVersion", "1", "objectVersion", "38", "rootObject", rootObject, "objects", objectsTable });
  }

  protected boolean hasBuildPhases() {
    return true;
  }

  protected static class ObjectsTable extends TreeMap {
    public static class ID extends Number {
      int _value;

      protected ID(int value) {
        _value = value;
      }

      @Override
      public String toString() {
        String hexValue = Integer.toHexString(_value);
        StringBuffer result = new StringBuffer(24);
        for (int i = 24 - hexValue.length(); i > 0; i--) {
          result.append('0');
        }
        result.append(hexValue);
        return result.toString();
      }

      // Bogus Number abstract class implementation requirements
      // follow. We have to be a Number since
      // PropertyListSerialization wouldn't otherwise stream a custom
      // class -- it only knows Lists, Maps, Strings and Numbers.
      // Strings are final, so that pretty much leaves us with Number,
      // as with the container classes PropertyListSerialization
      // would attempt to look into us, which isn't the right thing
      // to do.
      @Override
      public double doubleValue() {
        return 0;
      }

      @Override
      public float floatValue() {
        return 0;
      }

      @Override
      public int intValue() {
        return 0;
      }

      @Override
      public long longValue() {
        return 0;
      }

      @Override
      public short shortValue() {
        return 0;
      }
    }

    public ObjectsTable() {
      super(new Comparator() {
        public int compare(Object a, Object b) {
          if (a == b)
            return 0;
          if (a == null)
            return -1;
          if (b == null)
            return 1;
          return a.toString().compareTo(b.toString());
        }
      });
    }

    public ID insert(Object object) {
      ID id = new ID(_unique++);
      put(id, object);
      return id;
    }

    protected int _unique = 1;
  }
}
TOP

Related Classes of org.objectstyle.woenvironment.pb.PBXProject

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.