/* * (c) Copyright 2010-2011 AgileBirds * * This file is part of OpenFlexo. * * OpenFlexo is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * OpenFlexo 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. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with OpenFlexo. If not, see <http://www.gnu.org/licenses/>. * */ package org.openflexo.drm; import java.io.File; import java.util.Collections; import java.util.Comparator; import java.util.Enumeration; import java.util.HashMap; import java.util.Vector; import java.util.logging.Logger; import org.openflexo.drm.dm.DocItemAdded; import org.openflexo.drm.dm.DocItemFolderAdded; import org.openflexo.drm.dm.StructureModified; import org.openflexo.drm.helpset.HelpSetConfiguration; import org.openflexo.foundation.Inspectors; import org.openflexo.foundation.param.ParameterDefinition; import org.openflexo.foundation.validation.FixProposal; import org.openflexo.foundation.validation.ParameteredFixProposal; import org.openflexo.foundation.validation.ProblemIssue; import org.openflexo.foundation.validation.Validable; import org.openflexo.foundation.validation.ValidationError; import org.openflexo.foundation.validation.ValidationIssue; import org.openflexo.foundation.validation.ValidationRule; import org.openflexo.inspector.InspectableObject; import org.openflexo.localization.FlexoLocalization; public class DocItemFolder extends DRMObject implements InspectableObject { private static final Logger logger = Logger.getLogger(DocItemFolder.class.getPackage().getName()); // String identifier for this folder: name will be used as folder name in FS private String identifier; // Description for this folder private String description; // Parent DocItemFolder private DocItemFolder parentFolder; // Vector of DocItemFolder: childs private Vector<DocItemFolder> childFolders; // Vector of DocItem: childs private Vector<DocItem> items; private HashMap<String, DocItem> itemCache; private DocItem _primaryDocItem; public DocItemFolder(DRMBuilder builder) { this(builder.docResourceCenter); initializeDeserialization(builder); } public DocItemFolder(DocResourceCenter docResourceCenter) { super(docResourceCenter); identifier = null; description = null; parentFolder = null; childFolders = new Vector<DocItemFolder>(); items = new Vector<DocItem>(); itemCache = new HashMap<String, DocItem>(); } public static DocItemFolder createDocItemFolder(String anIdentifier, String aDescription, DocItemFolder parent, DocResourceCenter docResourceCenter) { logger.info("Create DocItemFolder " + anIdentifier + " in " + parent); DocItemFolder returned = new DocItemFolder(docResourceCenter); returned.identifier = anIdentifier; returned.description = aDescription; if (parent != null) { parent.addToChildFolders(returned); } returned.createDefaultPrimaryDocItem(); return returned; } @Override public String getInspectorName() { return Inspectors.DRE.DOC_ITEM_FOLDER_INSPECTOR; } @Override public String toString() { return "folder:" + getIdentifier(); } /** * Overrides delete * * @see org.openflexo.foundation.FlexoModelObject#delete() */ @Override public void delete() { Enumeration en = ((Vector) childFolders.clone()).elements(); while (en.hasMoreElements()) { DocItemFolder f = (DocItemFolder) en.nextElement(); f.delete(); } en = ((Vector) items.clone()).elements(); while (en.hasMoreElements()) { DocItem it = (DocItem) en.nextElement(); it.delete(); } if (parentFolder != null) { parentFolder.removeFromChildFolders(this); } itemCache = null; super.delete(); } private File directory; public File getDirectory() { if (directory == null) { File parent; if (getParentFolder() != null) { parent = getParentFolder().getDirectory(); } else { parent = DocResourceManager.getDocResourceCenterDirectory(); } directory = new File(parent, identifier); } return directory; } @Override public String getDescription() { return description; } @Override public void setDescription(String description) { this.description = description; setChanged(); } @Override public String getIdentifier() { return identifier; } public void setIdentifier(String identifier) { this.identifier = identifier; setChanged(); } public DocItem getPrimaryDocItem() { if (_primaryDocItem == null) { // Try to lookup if (primaryDocItemId != null) { setPrimaryDocItemId(primaryDocItemId); } } return _primaryDocItem; } public void setPrimaryDocItem(DocItem primaryDocItem) { if (primaryDocItem.getFolder() == this) { _primaryDocItem = primaryDocItem; if (primaryDocItem != null) { primaryDocItemId = primaryDocItem.getIdentifier(); } setChanged(); } } public boolean isPublished() { return getPrimaryDocItem() != null && getPrimaryDocItem().isPublished(); } /** * Overrides getSerializationIdentifier * * @see org.openflexo.drm.DRMObject#getSerializationIdentifier() */ @Override public String getSerializationIdentifier() { return (getParentFolder() != null ? getParentFolder().getSerializationIdentifier() : "Folder: ") + getIdentifier(); } public String getPrimaryDocItemId() { if (getPrimaryDocItem() != null) { return getPrimaryDocItem().getIdentifier(); } return primaryDocItemId; } private String primaryDocItemId; public void setPrimaryDocItemId(String primaryDocItemId) { this.primaryDocItemId = primaryDocItemId; DocItem item = getItemNamed(primaryDocItemId); if (item == null) { this.primaryDocItemId = primaryDocItemId; } else if (item.getFolder() == this) { _primaryDocItem = item; } } public void createDefaultPrimaryDocItem() { _primaryDocItem = DocItem.createDocItem(getIdentifier(), FlexoLocalization.localizedForKey("no_description"), this, getDocResourceCenter(), false); } @Override public String getFullyQualifiedName() { return getIdentifier(); } public DocItemFolder getParentFolder() { return parentFolder; } public void setParentFolder(DocItemFolder parentFolder) { this.parentFolder = parentFolder; setChanged(); } private boolean itemsNeedsReordering = true; private Vector<DocItem> orderedItems; public Vector getOrderedItems() { if (itemsNeedsReordering) { orderedItems = new Vector<DocItem>(); orderedItems.addAll(items); Collections.sort(orderedItems, DocItem.COMPARATOR); itemsNeedsReordering = false; } return orderedItems; } public Vector<DocItem> getItems() { if (isSerializing()) { return getOrderedItems(); } return items; } public void setItems(Vector<DocItem> items) { this.items = items; setChanged(); itemsNeedsReordering = true; } public void addToItems(DocItem item) { items.add(item); itemCache.put(item.getIdentifier(), item); item.setFolder(this); itemsNeedsReordering = true; setChanged(); notifyObservers(new DocItemAdded(item)); } public void removeFromItems(DocItem item) { items.remove(item); itemCache.remove(item.getIdentifier()); itemsNeedsReordering = true; setChanged(); } protected void reorderItems() { itemsNeedsReordering = true; setChanged(); notifyObservers(new StructureModified()); } public static DocItemFolderComparator COMPARATOR = new DocItemFolderComparator(); public static class DocItemFolderComparator implements Comparator<DocItemFolder> { @Override public int compare(DocItemFolder o1, DocItemFolder o2) { return o1.getIdentifier().compareTo(o2.getIdentifier()); } } private boolean childFolderNeedsReordering = true; private Vector<DocItemFolder> orderedChildFolders; public Vector<DocItemFolder> getOrderedChildFolders() { if (childFolderNeedsReordering) { orderedChildFolders = new Vector<DocItemFolder>(); orderedChildFolders.addAll(childFolders); Collections.sort(orderedChildFolders, COMPARATOR); childFolderNeedsReordering = false; } return orderedChildFolders; } public Vector<DocItemFolder> getChildFolders() { if (isSerializing()) { return getOrderedChildFolders(); } return childFolders; } public void setChildFolders(Vector<DocItemFolder> childFolders) { this.childFolders = childFolders; setChanged(); childFolderNeedsReordering = true; } public void addToChildFolders(DocItemFolder itemFolder) { childFolders.add(itemFolder); itemFolder.setParentFolder(this); childFolderNeedsReordering = true; setChanged(); notifyObservers(new DocItemFolderAdded(itemFolder)); } public void removeFromChildFolders(DocItemFolder item) { childFolders.remove(item); childFolderNeedsReordering = true; setChanged(); } public void notifyStructureChanged() { setChanged(); notifyObservers(new StructureModified()); } public boolean isRootFolder() { return getDocResourceCenter().getRootFolder() == this; } public String getNextDefautItemName() { String baseName = "item"; String testMe = baseName; int test = 0; while (getItemNamed(testMe) != null) { test++; testMe = baseName + test; } return testMe; } public String getNextDefautItemFolderName() { String baseName = "Folder"; String testMe = baseName; int test = 0; while (getItemFolderNamed(testMe) != null) { test++; testMe = baseName + test; } return testMe; } public DocItem getItemNamed(String itemIdentifier) { DocItem returned = itemCache.get(itemIdentifier); if (returned != null) { return returned; } for (Enumeration en = getChildFolders().elements(); en.hasMoreElements();) { DocItemFolder nextFolder = (DocItemFolder) en.nextElement(); returned = nextFolder.getItemNamed(itemIdentifier); if (returned != null) { return returned; } } return null; } public DocItemFolder getItemFolderNamed(String itemFolderIdentifier) { for (Enumeration en = getChildFolders().elements(); en.hasMoreElements();) { DocItemFolder next = (DocItemFolder) en.nextElement(); if (next.getIdentifier().equals(itemFolderIdentifier)) { return next; } } return null; } /** * Return a vector of all embedded objects at this level does NOT include itself * * @return a Vector of Validable objects */ @Override public Vector<Validable> getEmbeddedValidableObjects() { Vector<Validable> returned = new Vector<Validable>(); returned.addAll(getChildFolders()); returned.addAll(getItems()); return returned; } public String getRelativePath() { return (getParentFolder() != null ? getParentFolder().getRelativePath() + "/" : "") + getIdentifier(); } public boolean isAncestorOf(DocItem anItem) { if (anItem.getFolder() == this) { return true; } for (Enumeration en = getChildFolders().elements(); en.hasMoreElements();) { DocItemFolder next = (DocItemFolder) en.nextElement(); if (next.isAncestorOf(anItem)) { return true; } } return false; } @Override public String getClassNameKey() { return "doc_item_folder"; } // ========================================================================== // ============================= Validation ================================= // ========================================================================== public static class DocItemFolderMustHavePrimaryItem extends ValidationRule { public DocItemFolderMustHavePrimaryItem() { super(DocItemFolder.class, "documentation_folder_must_have_primary_doc_item"); } @Override public ValidationIssue applyValidation(final Validable object) { final DocItemFolder folder = (DocItemFolder) object; ProblemIssue issue = null; if (folder.getPrimaryDocItem() == null) { issue = new ValidationError(this, object, "doc_item_folder_($object.identifier)_has_no_primary_doc_item"); issue.addToFixProposals(new CreateDefaultPrimaryDocItem(folder)); issue.addToFixProposals(new SetPrimaryDocItem(folder)); } return issue; } public static class CreateDefaultPrimaryDocItem extends FixProposal { public DocItemFolder folder; public CreateDefaultPrimaryDocItem(DocItemFolder aFolder) { super("create_default_primary_doc_item"); folder = aFolder; } @Override protected void fixAction() { folder.createDefaultPrimaryDocItem(); } } public static class SetPrimaryDocItem extends ParameteredFixProposal { public DocItemFolder folder; public SetPrimaryDocItem(DocItemFolder aFolder) { super("set_primary_doc_item", buildParameters(aFolder)); folder = aFolder; } private static ParameterDefinition[] buildParameters(DocItemFolder aFolder) { ParameterDefinition[] returned = new ParameterDefinition[1]; returned[0] = new DocItemParameter("docItem", "doc_item_to_choose", null); return returned; } @Override protected void fixAction() { DocItem newPrimaryDocItem = (DocItem) getValueForParameter("docItem"); folder.setPrimaryDocItem(newPrimaryDocItem); } } } public boolean isIncluded(HelpSetConfiguration configuration) { if (isDirectelyIncluded(configuration)) { return true; } if (isPartiallyIncluded(configuration)) { return true; } return false; } protected boolean isDirectelyIncluded(HelpSetConfiguration configuration) { if (configuration.getDocItemFolders().contains(this)) { return true; } if (getParentFolder() != null) { return getParentFolder().isDirectelyIncluded(configuration); } return false; } protected boolean isPartiallyIncluded(HelpSetConfiguration configuration) { for (DocItemFolder folder : getChildFolders()) { if (folder.isDirectelyIncluded(configuration)) { return true; } if (folder.isPartiallyIncluded(configuration)) { return true; } } return false; } /** * @param docItem * @param old * @param identifier2 */ public void notifyItemHasBeenRenamedTo(DocItem docItem, String old, String identifier2) { if (old != null) { itemCache.remove(old); } itemCache.put(identifier2, docItem); } }