/***************************************************************************** * All public interface based on Starteam API are a property of Borland, * those interface are reproduced here only for testing purpose. You should * never use those interface to create a competitive product to the Starteam * Server. * * The implementation is given AS-IS and should not be considered a reference * to the API. The behavior on a lots of method and class will not be the * same as the real API. The reproduction only seek to mimic some basic * operation. You will not found anything here that can be deduced by using * the real API. * * Fake-Starteam is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *****************************************************************************/ package com.starbase.starteam; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Properties; import org.ossnoize.fakestarteam.FakeFolder; import org.ossnoize.fakestarteam.FileUtility; import org.ossnoize.fakestarteam.InternalPropertiesProvider; import org.ossnoize.fakestarteam.SimpleTypedResourceIDProvider; import org.ossnoize.fakestarteam.exception.InvalidOperationException; public class Folder extends Item { protected Folder() { } public Folder(Server server) { throw new UnsupportedOperationException("Unknown goal for this constructor"); } public Folder(Folder parent, String name, String workingFolder) { itemProperties = new Properties(); // initialize the basic properties of the folder. itemProperties.setProperty(propertyKeys.OBJECT_ID, Integer.toString(SimpleTypedResourceIDProvider.getProvider().registerNew(parent.getView(), this))); this.parent = parent; view = parent.getView(); setName(name); try { File storage = InternalPropertiesProvider.getInstance().getStorageLocation(); String folder = storage.getCanonicalPath() + File.separator + getObjectID(); holdingPlace = new File(folder); validateHoldingPlace(); loadProperties(); } catch (IOException e) { e.printStackTrace(); } shareTo(parent); } protected void validateHoldingPlace() { if(null == holdingPlace) { throw new InvalidOperationException("Cannot create a folder without an holding place."); } if(holdingPlace.exists()) { if(holdingPlace.isFile()) { holdingPlace.delete(); holdingPlace.mkdirs(); } } else { holdingPlace.mkdirs(); } } public void setName(java.lang.String name) { if(itemProperties == null) { throw new InvalidOperationException("The properties are not initialized"); } itemProperties.setProperty(propertyKeys.FOLDER_NAME, name); } public String getName() { if(itemProperties == null) { throw new InvalidOperationException("The properties are not initialized"); } return itemProperties.getProperty(propertyKeys.FOLDER_NAME); } public Folder[] getSubFolders() { if(itemProperties == null) throw new InvalidOperationException("The properties are not initialized"); String listOfFolder = itemProperties.getProperty(propertyKeys._CHILD_FOLDER); List<Folder> generatedList = new ArrayList<Folder>(); if(listOfFolder != null && listOfFolder.length() > 0) { for(String folderId : listOfFolder.split(";")) { if(null != folderId && 0 < folderId.length()) { try { int id = Integer.parseInt(folderId); Folder child = new FakeFolder(this.view, id, this); generatedList.add(child); } catch (NumberFormatException ne) { throw new InvalidOperationException("Folder child id corrupted."); } } } } Folder[] buffer = new Folder[generatedList.size()]; Collections.shuffle(generatedList); // to cause failures faster return generatedList.toArray(buffer); } private com.starbase.starteam.File[] getFiles() { if(itemProperties == null) throw new InvalidOperationException("The properties are not initialized yet"); String listOfFile = itemProperties.getProperty(propertyKeys._FILES); List<com.starbase.starteam.File> generatedList = new ArrayList<com.starbase.starteam.File>(); if(listOfFile != null && 0 < listOfFile.length()) { for(String fileID : listOfFile.split(";")) { if(null != fileID && 0 < fileID.length()) { try { int id = Integer.parseInt(fileID); com.starbase.starteam.File aFile = new com.starbase.starteam.File(id, this.view); if(this.view instanceof RecycleBin && aFile.isDeleted()) { generatedList.add(aFile); } else if (isFromHistory()) { if (this.view.getConfiguration().isLabelBased()) { Label findTime = new Label(this.view.getID(), this.view.getConfiguration().getLabelID()); if (aFile.isDeleted()) { if (findTime.getTime().getLongValue() < aFile.getDeletedTime().getLongValue()) { generatedList.add(aFile); } } else { generatedList.add(aFile); } } else if (this.view.getConfiguration().isTimeBased()) { if (aFile.isDeleted()) { if (this.view.getConfiguration().getTime().getLongValue() < aFile.getDeletedTime().getLongValue()) { generatedList.add(aFile); } } else { generatedList.add(aFile); } } } else { generatedList.add(aFile); } } catch (NumberFormatException ne) { ne.printStackTrace(); throw new InvalidOperationException("Folder child id corrupted."); } } } } com.starbase.starteam.File[] buffer = new com.starbase.starteam.File[generatedList.size()]; Collections.shuffle(generatedList); // to more rapidly cause some failures. return generatedList.toArray(buffer); } public Item[] getItems(java.lang.String typeName) { if(typeName.equalsIgnoreCase(getTypeNames().FOLDER)) return getSubFolders(); else if (typeName.equalsIgnoreCase(getTypeNames().FILE)) { return getFiles(); } return new Item[0]; } @Override public Folder getParentFolder() { return parent; } @Override public void update() { if(itemProperties == null) { throw new InvalidOperationException("Properties are not initialized yet!!!"); } int version = getRevisionNumber() + 1; setRevisionNumber(version); setModifiedBy(); setModifiedTime(); FileOutputStream fout = null; try { File storageFolder = new File(holdingPlace.getCanonicalPath() + File.separator + version); if(storageFolder.exists()) { throw new Error("Corrupted folder id:" + getObjectID()); } storageFolder.mkdirs(); fout = new FileOutputStream(storageFolder.getCanonicalPath() + File.separator + FOLDER_PROPERTIES); itemProperties.store(fout, "Folders properties"); } catch (IOException e) { e.printStackTrace(); } finally { FileUtility.close(fout); } } @Override protected int getObjectSpecificVersion() { return getRevisionNumber() + 1; } @Override public String toString() { return getName(); } @Override protected void loadProperties() { loadProperties(-1); } protected void loadProperties(int revision) { FileInputStream fin = null; try { int lastRevision; if(revision < 0) { lastRevision = findRightRevision(Integer.parseInt(holdingPlace.getName())); } else { lastRevision = revision; } File folderProperty = new File(holdingPlace.getCanonicalPath() + File.separator + lastRevision + File.separator + FOLDER_PROPERTIES); if(folderProperty.exists()) { fin = new FileInputStream(folderProperty); itemProperties.load(fin); int id = Integer.parseInt(itemProperties.getProperty(propertyKeys.OBJECT_ID)); int viewid = Integer.parseInt(itemProperties.getProperty(propertyKeys._VIEW_ID)); if(viewid != view.getID()) { throw new InvalidOperationException("The object is not registered on this view"); } SimpleTypedResourceIDProvider.getProvider().registerExisting(view, id, this); if(null == parent) { if (getParentObjectID() != 0) { parent = new FakeFolder(this.view, getParentObjectID(), null); } } } else { // initialize the basic properties of the folder. if (null != parent) { itemProperties.setProperty(propertyKeys.PARENT_OBJECT_ID, Integer.toString(parent.getObjectID())); buildParentPath(); } else { itemProperties.setProperty(propertyKeys.FOLDER_PATH, getName()); } itemProperties.setProperty(propertyKeys._VIEW_ID, Integer.toString(view.getID())); update(); } } catch (IOException e) { e.printStackTrace(); } finally { FileUtility.close(fin); } } @Override public Item shareTo(Folder folder) { StringBuffer childIdList = null; if(folder.itemProperties.containsKey(propertyKeys._CHILD_FOLDER)) { childIdList = new StringBuffer(folder.itemProperties.getProperty(propertyKeys._CHILD_FOLDER)).append(";"); } else { childIdList = new StringBuffer(25); } childIdList.append(getObjectID()); folder.itemProperties.setProperty(propertyKeys._CHILD_FOLDER, childIdList.toString()); Item toRet = super.shareTo(folder); folder.update(); return toRet; } @Override public void moveTo(Folder folder) { Folder origin = getParentFolder(); super.moveTo(folder); // Fixup the old parent and the child folder path. String thisStringId = Integer.toString(getObjectID()); if(origin.itemProperties.containsKey(propertyKeys._CHILD_FOLDER)) { StringBuffer idList = new StringBuffer(origin.itemProperties.getProperty(propertyKeys._CHILD_FOLDER)); int start = idList.indexOf(thisStringId); idList.delete(start, start+thisStringId.length()); origin.itemProperties.setProperty(propertyKeys._CHILD_FOLDER, idList.toString()); origin.update(); } buildParentPath(); update(); } @Override public void remove() { String childs = parent.itemProperties.getProperty(propertyKeys._CHILD_FOLDER); String without = childs.replace(Integer.toString(getObjectID()), ""); parent.itemProperties.setProperty(propertyKeys._CHILD_FOLDER, without); parent.update(); for(com.starbase.starteam.File f : getFiles()) { f.remove(); } for(Folder f : getSubFolders()) { f.remove(); } super.remove(); } private void buildParentPath() { itemProperties.setProperty(propertyKeys.FOLDER_PATH, parent.getParentFolderQualifiedName() + File.separatorChar + getName()); for(Folder f : getSubFolders()) { f.buildParentPath(); f.update(); } } public java.lang.String getFolderHierarchy() { if(null != parent) { return parent.getFolderHierarchy() + getName() + File.separator; } return getName() + File.separator; } @Override public Type getType() { return new Type(getTypeNames().FOLDER, view.getServer()); } public void populateNow(String file, String[] populateProps, int i) { // Nothing to do specially as in fake-starteam, most of the stuff are not on a remote server far away. } public void discardItems(String file, int i) { // Nothing special to do unless we have some memory retension issue. } @Override public Item[] getHistory() { ArrayList<Item> history = new ArrayList<Item>(); for (int rev = 1; rev < getRevisionNumber(); rev++) { history.add(new FakeFolder(this.view, this.getObjectID(), this.parent, rev)); } history.add(this); Collections.reverse(history); return history.toArray(new Item[history.size()]); } }