0001: /*
0002: * Copyright 2001-2006 C:1 Financial Services GmbH
0003: *
0004: * This software is free software; you can redistribute it and/or
0005: * modify it under the terms of the GNU Lesser General Public
0006: * License Version 2.1, as published by the Free Software Foundation.
0007: *
0008: * This software is distributed in the hope that it will be useful,
0009: * but WITHOUT ANY WARRANTY; without even the implied warranty of
0010: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
0011: * Lesser General Public License for more details.
0012: *
0013: * You should have received a copy of the GNU Lesser General Public
0014: * License along with this library; if not, write to the Free Software
0015: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
0016: */
0017:
0018: package de.finix.contelligent.client.base;
0019:
0020: import java.awt.datatransfer.DataFlavor;
0021: import java.awt.datatransfer.Transferable;
0022: import java.awt.datatransfer.UnsupportedFlavorException;
0023: import java.io.IOException;
0024: import java.io.Serializable;
0025: import java.util.ArrayList;
0026: import java.util.Collection;
0027: import java.util.HashMap;
0028: import java.util.Iterator;
0029: import java.util.List;
0030: import java.util.Map;
0031: import java.util.Set;
0032: import java.util.Vector;
0033: import java.util.logging.Level;
0034: import java.util.logging.Logger;
0035:
0036: import javax.swing.ImageIcon;
0037:
0038: import com.hexidec.ekit.component.MainPane;
0039:
0040: import de.finix.contelligent.client.base.category.ContelligentCategory;
0041: import de.finix.contelligent.client.base.category.ContelligentCategoryManager;
0042: import de.finix.contelligent.client.base.resource.ContelligentBinaryResource;
0043: import de.finix.contelligent.client.base.resource.ContelligentNumberResource;
0044: import de.finix.contelligent.client.base.resource.ContelligentResource;
0045: import de.finix.contelligent.client.base.resource.ContelligentResourceReference;
0046: import de.finix.contelligent.client.base.resource.ContelligentStringResource;
0047: import de.finix.contelligent.client.base.resource.ContelligentTextResource;
0048: import de.finix.contelligent.client.i18n.Resources;
0049: import de.finix.contelligent.client.security.ComponentAccess;
0050: import de.finix.contelligent.client.security.Principal;
0051:
0052: public class ContelligentComponent implements Editable, Serializable {
0053:
0054: private static Logger logger = Logger
0055: .getLogger(ContelligentComponent.class.getName());
0056:
0057: public static final String BLUEPRINT_PATH = "blueprintPath";
0058:
0059: public static final String LIBRARY_PATH = "libraryPath";
0060:
0061: public static final String TARGET_PATH = "targetPath";
0062:
0063: public static final String RELATIVE_PATH = "relativePath";
0064:
0065: public static final String PRINCIPAL_STRING = "principalString";
0066:
0067: public final static String EXTENSION = "extension";
0068:
0069: public final static String CONTENT_TYPE = "contentType";
0070:
0071: public static final String FORMAT = "format";
0072:
0073: public static final String STYLE = "style";
0074:
0075: public static final String DEFAULT = "default";
0076:
0077: public static final String DELIMITER = "delimiter";
0078:
0079: public static final String REQUIRED = "required";
0080:
0081: public static final String CATEGORY = "category";
0082:
0083: public static final String MODULE_IMPL = "moduleImpl";
0084:
0085: public static final String CONFIGURATION = "configuration";
0086:
0087: public static final String TOOLTIP = "tooltip";
0088:
0089: public static final String CREATE_TAB = "createTab";
0090:
0091: public static final String CREATE_MENU_ENTRY = "createMenuEntry";
0092:
0093: public static final String CREATE_TOOLBAR_ENTRY = "createToolbarEntry";
0094:
0095: public static final String AUTO_OPEN_MODULE = "autoOpenModule";
0096:
0097: public static final String IMPL = "viewImpl";
0098:
0099: public static final String NAME = "viewName";
0100:
0101: public static final String DISPLAY_NAME = "displayName";
0102:
0103: public static final String ROOT_COMPONENT = "viewComponent";
0104:
0105: public static final String ROOT_GUI = "rootGUI";
0106:
0107: public static final String SHORT_DESCRIPTION = "tooltip";
0108:
0109: public static final String SERVER = "server";
0110:
0111: public static final String PREVIEW = "preview";
0112:
0113: public static final String COLSPAN = "colspan";
0114:
0115: public static final String LINKTEXT_SUBCOMPONENT = "data/text";
0116:
0117: public static final String ERROR_ICON = "/contelligent/system/images/common/icons/gui/stop_on.bin";
0118:
0119: public static final int STATIC_CONTENT = 0;
0120:
0121: public static final int DYNAMIC_CONTENT = 1;
0122:
0123: public static final int NO_CONTENT_AVAILABLE = 2;
0124:
0125: // Keep identical with server: ComponentPath.permittedNameCharacters
0126: public final static String getAllowString() {
0127: return ("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ@_-.");
0128: }
0129:
0130: // XXX Olli Z.: droped final to make it visible in debugger
0131: private String name;
0132:
0133: private String dir;
0134:
0135: private Map<String, ComponentProperty> properties = new HashMap<String, ComponentProperty>();
0136:
0137: private List<String> metadataKeys = new Vector<String>();
0138:
0139: private List<String> metadataValues = new Vector<String>();
0140:
0141: private Type type;
0142:
0143: private String typeName;
0144:
0145: private List<ComponentAccess> acl = new ArrayList<ComponentAccess>();
0146:
0147: private List<Principal> owners = new ArrayList<Principal>();
0148:
0149: private List<String> subcomponents = new ArrayList<String>();
0150:
0151: private List<ParameterDescription> parameterDescriptions = new ArrayList<ParameterDescription>();
0152:
0153: private boolean smallIconLoaded = false;
0154:
0155: private boolean modified = false;
0156:
0157: private boolean aclModified = false;
0158:
0159: private boolean resourceModified = false;
0160:
0161: private boolean valid = true;
0162:
0163: private boolean subcomponentsLoaded = false;
0164:
0165: private boolean definesSecureTransfer = false;
0166:
0167: private boolean needsSecureTransfer = false;
0168:
0169: private boolean isFinal = false;
0170:
0171: private long lastModified = -1L;
0172:
0173: private String modifiedBy = "";
0174:
0175: private String renderer = "none";
0176:
0177: private boolean hasContent = false;
0178:
0179: private boolean blueprintComponent = false;
0180:
0181: private String definedBlueprintType;
0182:
0183: private String composedBlueprint = null;
0184:
0185: // needed to determine if this component has children without actually
0186: // loading them
0187: private boolean hasChildren = false;
0188:
0189: // caches whether this component is part of a read only package
0190: private Boolean readOnly = null;
0191:
0192: private Map<String, Object> completeResourceMap = new HashMap<String, Object>();
0193:
0194: private Map<String, Object> completeTemplateMap = new HashMap<String, Object>();
0195:
0196: private Map<String, ContelligentResource> resourceMap = new HashMap<String, ContelligentResource>();
0197:
0198: private Map<String, ContelligentResource> templateMap = new HashMap<String, ContelligentResource>();
0199:
0200: private List<ContelligentCategory> contentCategories = new ArrayList<ContelligentCategory>();
0201:
0202: private List<ContelligentCategory> templateCategories = new ArrayList<ContelligentCategory>();
0203:
0204: private String publisherName = "";
0205:
0206: private String publisherType = "";
0207:
0208: private boolean readPermission = true;
0209:
0210: public ContelligentComponent(String name, String dir) {
0211: this .name = name;
0212: this .dir = dir;
0213: }
0214:
0215: /**
0216: * Resets the component to the initial state before loading.
0217: *
0218: */
0219: public void clear() {
0220: properties.clear();
0221: parameterDescriptions.clear();
0222: acl.clear();
0223: owners.clear();
0224: subcomponentsLoaded = false;
0225: subcomponents.clear();
0226: smallIconLoaded = false;
0227: modified = false;
0228: resourceModified = false;
0229: aclModified = false;
0230: valid = true;
0231: readOnly = null;
0232: resourceMap.clear();
0233: completeResourceMap.clear();
0234: contentCategories.clear();
0235: templateMap.clear();
0236: completeTemplateMap.clear();
0237: templateCategories.clear();
0238: blueprintComponent = false;
0239: metadataKeys.clear();
0240: metadataValues.clear();
0241: }
0242:
0243: public void init() {
0244: inheritPropertiesFromType();
0245: setModified(false);
0246: setResourceModified(false);
0247: setAclModified(false);
0248: completeTemplateMap();
0249: completeResourceMap();
0250: }
0251:
0252: public void completeTemplateMap() {
0253: completeTemplateMap.clear();
0254: completeTemplateMap.putAll(templateMap);
0255: ContelligentCategoryManager.getInstance()
0256: .completeCategoryToResourceMapping(templateCategories,
0257: completeTemplateMap);
0258: }
0259:
0260: public void completeResourceMap() {
0261: completeResourceMap.clear();
0262: completeResourceMap.putAll(resourceMap);
0263: ContelligentCategoryManager.getInstance()
0264: .completeCategoryToResourceMapping(contentCategories,
0265: completeResourceMap);
0266: }
0267:
0268: public boolean allowsSubcomponents() {
0269: return getType().allowsSubcomponents();
0270: }
0271:
0272: // public boolean isBlueprint() {
0273: // return (getType().isBlueprint());
0274: // && getType().getBlueprintPath().equals(getPath()));
0275: // }
0276:
0277: public boolean isBlueprint() {
0278: return blueprintComponent;
0279: }
0280:
0281: public void setBlueprint(boolean blueprintComponent) {
0282: this .blueprintComponent = blueprintComponent;
0283: }
0284:
0285: public String getDefinedBlueprintType() {
0286: return definedBlueprintType;
0287: }
0288:
0289: public void setDefinedBlueprintType(String definedBlueprintType) {
0290: this .definedBlueprintType = definedBlueprintType;
0291: }
0292:
0293: public boolean isBlueprintSubComponent() {
0294: ContelligentComponent parent = getParentComponent();
0295: if (parent == null) {
0296: return false;
0297: } else if (getPath().equals(parent.getPath())) {
0298: return false;
0299: } else if (parent.isBlueprint()) {
0300: return true;
0301: } else {
0302: return parent.isBlueprintSubComponent();
0303: }
0304: }
0305:
0306: public boolean isBlueprintInstance() {
0307: return (getType().isBlueprint() && !getType()
0308: .getBlueprintPath().equals(getPath()));
0309: }
0310:
0311: public boolean isBlueprintInstanceSubComponent() {
0312: ContelligentComponent parent = getParentComponent();
0313: if (parent == null) {
0314: return false;
0315: } else if (getPath().equals(parent.getPath())) {
0316: return false;
0317: } else if (parent.isBlueprintInstance()) {
0318: return true;
0319: } else {
0320: return parent.isBlueprintInstanceSubComponent();
0321: }
0322: }
0323:
0324: public void addContentCategory(ContelligentCategory category) {
0325: contentCategories.add(category);
0326: }
0327:
0328: public List<ContelligentCategory> getContentCategories() {
0329: return contentCategories;
0330: }
0331:
0332: public void setContentCategories(
0333: List<ContelligentCategory> contentCategories) {
0334: if (resourceMap != null) {
0335: refactorResources(resourceMap, contentCategories);
0336: }
0337: this .contentCategories = contentCategories;
0338: completeResourceMap();
0339: }
0340:
0341: public void addTemplateCategory(ContelligentCategory category) {
0342: templateCategories.add(category);
0343: }
0344:
0345: public List<ContelligentCategory> getTemplateCategories() {
0346: return templateCategories;
0347: }
0348:
0349: public void setTemplateCategories(
0350: List<ContelligentCategory> templateCategories) {
0351: // refactor resources
0352: if (templateMap != null) {
0353: refactorResources(templateMap, templateCategories);
0354: }
0355: this .templateCategories = templateCategories;
0356: completeTemplateMap();
0357: }
0358:
0359: public void setTemplate(String identifier,
0360: ContelligentTextResource resource) {
0361: templateMap.put(identifier, resource);
0362: }
0363:
0364: public void setTemplate(ContelligentResource resource) {
0365: String identifier = ContelligentCategoryManager
0366: .createUniqueCategoryIdentifier(templateCategories,
0367: resource.getCategoryMap());
0368: templateMap.put(identifier, resource);
0369: }
0370:
0371: // returns an object of type ContelligentTextResource or
0372: // ContelligentResourceReference
0373: public Object getTemplate(String identifier) {
0374: return completeTemplateMap.get(identifier);
0375: }
0376:
0377: public Collection getTemplates() {
0378: return completeTemplateMap.values();
0379: }
0380:
0381: public Map getTemplateMap() {
0382: return completeTemplateMap;
0383: }
0384:
0385: public void setResource(String identifier,
0386: ContelligentResource resource) {
0387: resourceMap.put(identifier, resource);
0388: }
0389:
0390: public void setResource(ContelligentResource resource) {
0391: String identifier = ContelligentCategoryManager
0392: .createUniqueCategoryIdentifier(contentCategories,
0393: resource.getCategoryMap());
0394: resourceMap.put(identifier, resource);
0395: }
0396:
0397: /**
0398: * Get the resources for this component.
0399: *
0400: * @return a map of key-[String]/resource-[ContelligentResource] pairs.
0401: */
0402: public Map getResourceMap() {
0403: return completeResourceMap;
0404: }
0405:
0406: // returns an object of type ContelligentResource or
0407: // ContelligentResourceReference
0408: public Object getResource(String identifier) {
0409: return completeResourceMap.get(identifier);
0410: }
0411:
0412: public Set getDefinedResourceIdentifiers() {
0413: return completeResourceMap.keySet();
0414: }
0415:
0416: public boolean isFinal() {
0417: return isFinal;
0418: }
0419:
0420: public void setFinal(boolean isFinal) {
0421: this .isFinal = isFinal;
0422: }
0423:
0424: public void addParameterDescription(ParameterDescription parameter) {
0425: parameterDescriptions.add(parameter);
0426: }
0427:
0428: public List getParameterDescriptions() {
0429: return parameterDescriptions;
0430: }
0431:
0432: public String getDescripion() {
0433: String lang = Resources.getLocale().getLanguage();
0434: if (type != null) {
0435: String text = type.getDescriptionText(lang);
0436: return text;
0437: } else {
0438: return "";
0439: }
0440: }
0441:
0442: public void setComposedBlueprint(String composedBlueprint) {
0443: this .composedBlueprint = composedBlueprint;
0444: }
0445:
0446: public String getComposedBlueprint() {
0447: return composedBlueprint;
0448: }
0449:
0450: public long lastModified() {
0451: return lastModified;
0452: }
0453:
0454: public boolean setLastModified(long lastModified) {
0455: this .lastModified = lastModified;
0456: return true;
0457: }
0458:
0459: public long getLastModified() {
0460: return lastModified;
0461: }
0462:
0463: public void setLastModified(String lastModified) {
0464: try {
0465: this .lastModified = Long.valueOf(lastModified).longValue();
0466: } catch (NumberFormatException nfe) {
0467: logger.log(Level.WARNING,
0468: "Got invalid number format for lastModified", nfe);
0469: this .lastModified = -1;
0470: }
0471: }
0472:
0473: public String getModifiedBy() {
0474: return modifiedBy;
0475: }
0476:
0477: public void setModifiedBy(String modifiedBy) {
0478: this .modifiedBy = modifiedBy;
0479: }
0480:
0481: public String getName() {
0482: return name;
0483: }
0484:
0485: public String getDir() {
0486: return dir;
0487: }
0488:
0489: public void setDir(String dir) {
0490: this .dir = dir;
0491: }
0492:
0493: public void setDefinesSecureTransfer(boolean definesSecureTransfer) {
0494: this .definesSecureTransfer = definesSecureTransfer;
0495: }
0496:
0497: public boolean getDefinesSecureTransfer() {
0498: return definesSecureTransfer;
0499: }
0500:
0501: public void setNeedsSecureTransfer(boolean needsSecureTransfer) {
0502: this .needsSecureTransfer = needsSecureTransfer;
0503: }
0504:
0505: public boolean getNeedsSecureTransfer() {
0506: return needsSecureTransfer;
0507: }
0508:
0509: // XXX this is so ugly!
0510: public String getPathNullIsSlash() {
0511: String path = dir + name;
0512: return path;
0513: }
0514:
0515: public String getPath() {
0516: String path = dir + name;
0517: if (path.equals("/")) {
0518: // return empty path if this is the root component
0519: return "";
0520: }
0521: return path;
0522: }
0523:
0524: public boolean hasParent() {
0525: if (dir.equals("")) {
0526: return false;
0527: }
0528: return true;
0529: }
0530:
0531: public String getParentPath() {
0532: if (!hasParent()) {
0533: return "";
0534: }
0535: String path = dir;
0536: if (path.equals("/")) {
0537: return "/";
0538: }
0539: path = path.substring(0, path.length() - 1);
0540: return path;
0541: }
0542:
0543: /**
0544: * Answer the parent or null, if not found.
0545: */
0546: public ContelligentComponent getParentComponent() {
0547: if (!hasParent()) {
0548: return null;
0549: }
0550: try {
0551: return ComponentFactory.getInstance().getComponent(
0552: getParentPath());
0553: } catch (ComponentNotFoundException e) {
0554: return null;
0555: }
0556: }
0557:
0558: public void invalidateSubcomponents() {
0559: subcomponentsLoaded = false;
0560: subcomponents.clear();
0561: }
0562:
0563: public void addSubcomponent(String name) {
0564: // add only if subcomponent is not already added...
0565: if (!hasSubcomponent(name)) {
0566: hasChildren = true;
0567: subcomponents.add(name);
0568: }
0569: }
0570:
0571: public void moveUpSubcomponent(String name) {
0572: int index = subcomponents.indexOf(name);
0573: subcomponents.remove(index);
0574: subcomponents.add(index - 1, name);
0575: }
0576:
0577: public void moveDownSubcomponent(String name) {
0578: int index = subcomponents.indexOf(name);
0579: subcomponents.remove(index);
0580: subcomponents.add(index + 1, name);
0581: }
0582:
0583: public void deleteFromParent() throws NoParentException,
0584: ChildNotFoundException, NodeNotEmptyException,
0585: ComponentNotFoundException, TypeNotFoundException {
0586: if (dir == null)
0587: throw new NoParentException(Resources
0588: .getLocalString("no_root_delete"));
0589: // remove only if parent is in cache...
0590: if (ComponentFactory.getInstance().isCached(getParentPath())) {
0591: ComponentFactory.getInstance()
0592: .getComponent(getParentPath()).deleteSubcomponent(
0593: name);
0594: }
0595: }
0596:
0597: public void deleteSubcomponent(String name)
0598: throws ChildNotFoundException {
0599: if (!subcomponents.remove(name)) {
0600: throw new ChildNotFoundException(Resources.getLocalString(
0601: "component_not_found", new String[] { name,
0602: getPath() }));
0603: }
0604: }
0605:
0606: public boolean hasSubcomponents() {
0607: return hasChildren;
0608: }
0609:
0610: public void setHasSubcomponents(boolean hasChildren) {
0611: this .hasChildren = hasChildren;
0612: }
0613:
0614: public boolean hasSubcomponent(String name) {
0615: return subcomponents.contains(name);
0616: }
0617:
0618: public void setSubcomponentsLoaded(boolean loaded) {
0619: logger.log(Level.FINE, "'" + getPath()
0620: + "' - set subcomponentsLoaded to '" + loaded + "'");
0621: subcomponentsLoaded = loaded;
0622: }
0623:
0624: public boolean isSubcomponentsLoaded() {
0625: logger.log(Level.FINE, "'" + getPath()
0626: + "' - get subcomponentsLoaded: '"
0627: + subcomponentsLoaded + "'");
0628: return subcomponentsLoaded;
0629: }
0630:
0631: public ContelligentComponent getSubcomponent(String name)
0632: throws ComponentNotFoundException {
0633: return ComponentFactory.getInstance().getComponent(
0634: getPath() + "/" + name);
0635: }
0636:
0637: /**
0638: * Careful, this returns a List of subcomponent names, not Components.
0639: */
0640: public List<String> getSubcomponents() {
0641: if (!subcomponentsLoaded) {
0642: try {
0643: ComponentFactory.getInstance().assureChildrenLoaded(
0644: this );
0645: logger.log(Level.FINE, "'" + getPath()
0646: + "' - set subcomponentsLoaded: 'true'");
0647: subcomponentsLoaded = true;
0648: } catch (ComponentNotFoundException e) {
0649: logger.log(Level.SEVERE,
0650: "Subcomponent(s) could not be loaded: ", e);
0651: }
0652: }
0653: return subcomponents;
0654: }
0655:
0656: public int indexOfSubcomponent(String name) {
0657: List subcomponents = getSubcomponents();
0658: int index = 0;
0659: for (Iterator i = subcomponents.iterator(); i.hasNext();) {
0660: if (i.next().equals(name)) {
0661: return index;
0662: }
0663: index++;
0664: }
0665: return -1;
0666: }
0667:
0668: /**
0669: * Checks if a given component is part of a given collection of componentpaths.
0670: *
0671: * @param component
0672: * The component to be checked.
0673: * @param components
0674: * A collection of componentpaths.
0675: * @return <code>true</code> if the give component is included. <code>false</code> else.
0676: */
0677: private static boolean isIncluded(ContelligentComponent component,
0678: List componentPaths) {
0679:
0680: String elementPath = "";
0681:
0682: // check if a given component is already in a collection of visited components
0683: for (Iterator iter = componentPaths.iterator(); iter.hasNext();) {
0684: elementPath = (String) iter.next();
0685:
0686: if (elementPath.equals(component.getPath())) {
0687: return true;
0688: }
0689: }
0690: return false;
0691: }
0692:
0693: /**
0694: * This method is used to return a links target component. Therefore it will be checked if the component is a link
0695: * and if it is part of an infinite loop created by linked links.
0696: *
0697: * @return The component itself if it was not a link. Otherwise the linked component or <code>null</code> if the
0698: * link is part of an infinite loop.
0699: */
0700: public ContelligentComponent followLink() {
0701:
0702: if (this .getType().getName().equals(Type.LINK)) {
0703:
0704: // to avoid an infinite loop, we have to store the paths of the visited components
0705: Vector<String> visitedComponents = new Vector<String>();
0706: visitedComponents.add(this .getPath());
0707:
0708: ContelligentComponent linkTarget = null;
0709:
0710: try {
0711: linkTarget = ContelligentComponent.followLink(this ,
0712: visitedComponents);
0713: } catch (InfiniteLinkException ile) {
0714:
0715: logger
0716: .log(
0717: Level.WARNING,
0718: "Link: '"
0719: + this .getPath()
0720: + "' is part of an infinite loop created by linked links",
0721: ile);
0722:
0723: linkTarget = null;
0724: }
0725: return linkTarget;
0726: }
0727: return this ;
0728: }
0729:
0730: protected static ContelligentComponent followLink(
0731: ContelligentComponent link, Vector<String> visitedComponents)
0732: throws InfiniteLinkException {
0733:
0734: try {
0735: // get linked Component
0736: ContelligentComponent linkedComponent = ComponentFactory
0737: .getInstance()
0738: .getComponent(
0739: link.getPath(),
0740: link
0741: .getPropertyValue(ContelligentComponent.TARGET_PATH));
0742:
0743: // check if it is a link and if it is already in the collection (to avoid an infinite loop)
0744: if (linkedComponent.getType().getName().equals(Type.LINK) == true
0745: && !ContelligentComponent.isIncluded(
0746: linkedComponent, visitedComponents)) {
0747:
0748: // add actual path
0749: visitedComponents.add(linkedComponent.getPath());
0750:
0751: // recursive method call
0752: linkedComponent = ContelligentComponent.followLink(
0753: linkedComponent, visitedComponents);
0754:
0755: } else {
0756: // if not a link, do nothing here
0757: // if included in the collection, we have a infinite loop
0758: if (ContelligentComponent.isIncluded(linkedComponent,
0759: visitedComponents)) {
0760:
0761: // mark link component as erroneous
0762: throw new InfiniteLinkException();
0763: }
0764: }
0765: return linkedComponent;
0766:
0767: } catch (ComponentNotFoundException e) {
0768: logger
0769: .log(
0770: Level.WARNING,
0771: "Link target: '"
0772: + link
0773: .getPropertyValue(ContelligentComponent.TARGET_PATH)
0774: + "' not found", e);
0775: return null;
0776: }
0777: }
0778:
0779: /**
0780: * @return <code>ImageIcon</code> that represents the type of the component
0781: */
0782: public ImageIcon getSmallIcon() {
0783:
0784: ImageIcon smallIcon = null;
0785:
0786: if (isBlueprint()) {
0787: try {
0788: smallIcon = TypeFactory.getInstance().getType(
0789: getDefinedBlueprintType()).getIcon();
0790: } catch (TypeNotFoundException tne) {
0791: logger.log(Level.FINE, "Unable to resolve type "
0792: + getDefinedBlueprintType());
0793: }
0794: } else {
0795: smallIcon = type.getIcon();
0796: }
0797: // is link?
0798: if (type.getName().equals(Type.LINK)) {
0799:
0800: ContelligentComponent tmpComp = this .followLink();
0801:
0802: // if null the link is part of an infinite loop
0803: if (tmpComp == null) {
0804: smallIcon = Resources.getIcon("error");
0805: smallIcon = Resources.mergeIcons(smallIcon,
0806: Resources.linkAlias);
0807: } else {
0808: smallIcon = tmpComp.getSmallIcon();
0809: smallIcon = Resources.mergeIcons(smallIcon,
0810: Resources.linkAlias);
0811: }
0812: }
0813: if (isBlueprint()) {
0814: smallIcon = Resources.mergeIcons(smallIcon,
0815: Resources.blueprintMasterIcon);
0816: } else if (isBlueprintInstance()) {
0817: smallIcon = Resources.mergeIcons(smallIcon,
0818: Resources.blueprintInstanceIcon);
0819: } else if (isBlueprintSubComponent()) {
0820: smallIcon = Resources.mergeIcons(smallIcon,
0821: Resources.composedBlueprintMasterIcon);
0822: } else if (isBlueprintInstanceSubComponent()) {
0823: smallIcon = Resources.mergeIcons(smallIcon,
0824: Resources.composedBlueprintInstanceIcon);
0825: }
0826: if (isFinal()) {
0827: smallIcon = Resources.mergeIcons(smallIcon,
0828: Resources.finalAlias);
0829: }
0830: smallIconLoaded = true;
0831:
0832: return smallIcon;
0833: }
0834:
0835: public String toString() {
0836: // return component as finix tag for external applications
0837: return "<" + ContelligentConstants.NAMESPACE + ":"
0838: + ContelligentConstants.RENDER_TAG + " name=\""
0839: + getPath() + "\" />";
0840: }
0841:
0842: public void addProperty(ComponentProperty property) {
0843: String name = property.getName();
0844: properties.put(name, property);
0845: }
0846:
0847: public void inheritPropertiesFromType() {
0848: if (getType() != null) {
0849: // copy properties from type that are not yet property types...
0850: Map typeProperties = getType().getEffectivePropertyMap();
0851: for (Iterator i = typeProperties.values().iterator(); i
0852: .hasNext();) {
0853: TypeProperty typeProperty = (TypeProperty) i.next();
0854: if (!getProperties()
0855: .containsKey(typeProperty.getName())) {
0856: // add property as inherited property
0857: String name = typeProperty.getName();
0858: properties.put(name,
0859: new ComponentProperty(this , name,
0860: typeProperty.getValue(),
0861: typeProperty));
0862: }
0863: }
0864: }
0865: }
0866:
0867: public Map<String, ComponentProperty> getProperties() {
0868: return properties;
0869: }
0870:
0871: public synchronized List<String> getMetadataKeys() {
0872: return new Vector<String>(metadataKeys);
0873: }
0874:
0875: public synchronized List<String> getMetadataValues() {
0876: return new Vector<String>(metadataValues);
0877: }
0878:
0879: public synchronized void setMetadataKeys(List<String> keys) {
0880: metadataKeys = keys;
0881: }
0882:
0883: public synchronized void setMetadataValues(List<String> values) {
0884: metadataValues = values;
0885: }
0886:
0887: public List<String> getMetadata(String searchKey) {
0888: List<String> mKeys = getMetadataKeys();
0889: List<String> mValues = getMetadataValues();
0890: Vector<String> results = new Vector<String>();
0891: for (int i = 0; i < mKeys.size(); i++) {
0892: String key = (String) mKeys.get(i);
0893: if (key.equals(searchKey)) {
0894: results.add(mValues.get(i));
0895: }
0896: }
0897: return results;
0898: }
0899:
0900: public synchronized void setMetadataKey(String key,
0901: List<String> values) {
0902: // Remove old values of the key
0903: for (int i = 0; i < metadataKeys.size(); i++) {
0904: String foundKey = (String) metadataKeys.get(i);
0905: if (foundKey.equals(key)) {
0906: metadataKeys.remove(i);
0907: metadataValues.remove(i);
0908: i--;
0909: }
0910: }
0911: // Add the new values
0912: Iterator it = values.iterator();
0913: while (it.hasNext()) {
0914: String value = (String) it.next();
0915: if (value != null) {
0916: metadataKeys.add(key);
0917: metadataValues.add(value);
0918: }
0919: }
0920: }
0921:
0922: /**
0923: * @deprecated use {@link #hasProperty} instead
0924: */
0925: public boolean propertyExists(String name) {
0926: return properties.containsKey(name);
0927: }
0928:
0929: public boolean hasProperty(String name) {
0930: return properties.containsKey(name);
0931: }
0932:
0933: public ComponentProperty getProperty(String name) {
0934: return (ComponentProperty) properties.get(name);
0935: }
0936:
0937: public String getPropertyValue(String name) {
0938: ComponentProperty property = (ComponentProperty) properties
0939: .get(name);
0940: if (property == null) {
0941: logger
0942: .log(
0943: Level.SEVERE,
0944: "'"
0945: + getPath()
0946: + "':getPropertyValue() - Could not get value for property '"
0947: + name + "' in component '"
0948: + getName() + "'");
0949: return null;
0950: } else {
0951: return ((ComponentProperty) properties.get(name))
0952: .getValue();
0953: }
0954: }
0955:
0956: public void setPropertyValue(String name, String value) {
0957: ComponentProperty property = (ComponentProperty) properties
0958: .get(name);
0959: if (property == null) {
0960: logger.log(Level.SEVERE, "'" + getPath()
0961: + "':setPropertyValue() - Property '" + name
0962: + "' in component '" + getName() + "' not found!");
0963: return;
0964: }
0965: if (property.getValue() == null
0966: || !property.getValue().equals(value)) {
0967: modified = true;
0968: property.setValue(value);
0969: }
0970: }
0971:
0972: public boolean isResourceModified() {
0973: return resourceModified;
0974: }
0975:
0976: public void setResourceModified(boolean resourceModified) {
0977: this .resourceModified = resourceModified;
0978: }
0979:
0980: public boolean isModified() {
0981: return modified;
0982: }
0983:
0984: public void setModified(boolean modified) {
0985: this .modified = modified;
0986: }
0987:
0988: public boolean isAclModified() {
0989: return aclModified;
0990: }
0991:
0992: public void setAclModified(boolean aclModified) {
0993: this .aclModified = aclModified;
0994: }
0995:
0996: public void addAclEntry(ComponentAccess entry) {
0997: Principal principal = entry.getPrincipal();
0998: String permission = entry.getPermission();
0999: String mode = entry.getMode();
1000:
1001: setAclModified(true);
1002:
1003: for (Iterator i = acl.iterator(); i.hasNext();) {
1004: ComponentAccess aclEntry = (ComponentAccess) i.next();
1005: if (aclEntry.getPrincipal().equals(principal)
1006: && aclEntry.getPermission().equals(permission)) {
1007: aclEntry.setMode(mode);
1008: return;
1009: }
1010: }
1011: acl.add(entry);
1012: }
1013:
1014: public void removeAclEntry(ComponentAccess entry) {
1015:
1016: setAclModified(true);
1017:
1018: for (int k = 0; k < acl.size(); k++) {
1019: ComponentAccess aclEntry = (ComponentAccess) acl.get(k);
1020: if (entry == aclEntry) {
1021: acl.remove(k);
1022: }
1023: }
1024: }
1025:
1026: public List<ComponentAccess> getACL() {
1027: return acl;
1028: }
1029:
1030: public String getTypeName() {
1031: return typeName;
1032: }
1033:
1034: public void setTypeName(String typeName) {
1035: this .typeName = typeName;
1036: try {
1037: Type type = TypeFactory.getInstance().getType(typeName);
1038: setType(type);
1039: } catch (TypeNotFoundException tnfe) {
1040: // bad luck, so do not set it!
1041: logger.log(Level.SEVERE,
1042: "Could not set type for component " + getPath(),
1043: tnfe);
1044: }
1045: }
1046:
1047: public void setType(Type type) {
1048: this .type = type;
1049: }
1050:
1051: public Type getType() {
1052: if (type == null) {
1053: logger.log(Level.SEVERE, "'" + getPath()
1054: + "':getType() - has null type");
1055: }
1056: return type;
1057: }
1058:
1059: public void addOwner(Principal principal) {
1060: if (!isOwner(principal)) {
1061: setAclModified(true);
1062: owners.add(principal);
1063: }
1064: }
1065:
1066: public void removeOwner(Principal principal) {
1067: setAclModified(true);
1068: owners.remove(principal);
1069: }
1070:
1071: public List<Principal> getOwners() {
1072: return owners;
1073: }
1074:
1075: public boolean isOwner(Principal principal) {
1076: for (Iterator i = owners.iterator(); i.hasNext();) {
1077: if ((i.next()).equals(principal)) {
1078: return true;
1079: }
1080: }
1081: return false;
1082: }
1083:
1084: public boolean hasNoPremissions() {
1085: return (acl.size() == 0);
1086: }
1087:
1088: public boolean canRead() {
1089: return Session.getInstance().hasPermission(getACL(),
1090: ComponentAccess.READ);
1091: }
1092:
1093: public boolean canExecute() {
1094: return Session.getInstance().hasPermission(getACL(),
1095: ComponentAccess.EXECUTE);
1096: }
1097:
1098: /**
1099: * Determines whether the current user has write access to this component. Global administrative privileges are
1100: * respected by this method and will always cause the result to be true. This method checks the effective ACL
1101: * restrictions only; even if this method returns true the method will still not be writable if it is part of a read
1102: * only package; see the isReadOnly() method for that.
1103: */
1104: public boolean canWrite() {
1105: return Session.getInstance().hasPermission(getACL(),
1106: ComponentAccess.WRITE);
1107: }
1108:
1109: public boolean canDelete() {
1110: return Session.getInstance().hasPermission(getACL(),
1111: ComponentAccess.DELETE);
1112: }
1113:
1114: public boolean instanceOf(String typeName) {
1115: if (type.getName().equals(typeName)) {
1116: return true;
1117: } else {
1118: return type.instanceOf(typeName);
1119: }
1120: }
1121:
1122: public boolean instanceOf(Type type) {
1123: return instanceOf(type.getName());
1124: }
1125:
1126: protected void finalize() {
1127: valid = false;
1128: }
1129:
1130: public void invalidate() {
1131: valid = false;
1132: }
1133:
1134: public boolean isValid() {
1135: return valid;
1136: }
1137:
1138: public boolean equals(Object o) {
1139: if (o instanceof ContelligentComponent) {
1140: return equals((ContelligentComponent) o);
1141: } else if (o instanceof String) {
1142: return equals((String) o);
1143: } else {
1144: return super .equals(o);
1145: }
1146: }
1147:
1148: public boolean equals(ContelligentComponent c) {
1149: return (this == c || (c != null
1150: && c instanceof ContelligentComponent && ((ContelligentComponent) c)
1151: .getPath().equals(getPath())));
1152: }
1153:
1154: public boolean equals(String path) {
1155: return (getPath().equals(path));
1156: }
1157:
1158: public int hashCode() {
1159: return -1;
1160: }
1161:
1162: /**
1163: * Converts this component to its XML representation.
1164: *
1165: * @return the XML representation of this component.
1166: */
1167: public String toXmlString() {
1168: StringBuffer buffer = new StringBuffer();
1169: Collection owners = getOwners();
1170: Collection acl = getACL();
1171: Collection properties = getProperties().values();
1172: Collection resources = getResourceMap().values();
1173: Collection templates = getTemplates();
1174: List metaKeys = getMetadataKeys();
1175: List metaValues = getMetadataValues();
1176:
1177: buffer.append("<component name=\"");
1178: buffer.append(getName());
1179: buffer.append("\" dir=\"");
1180: buffer.append(getDir());
1181: buffer.append("\" type=\"");
1182: buffer.append(getType());
1183: buffer.append("\">\n");
1184:
1185: buffer.append("<meta-info lastModified=\"");
1186: buffer.append(getLastModified());
1187: buffer.append("\" isFinal=\"");
1188: buffer.append(isFinal());
1189: if (getComposedBlueprint() != null) {
1190: buffer.append("\" composedBlueprint=\"");
1191: buffer.append(getComposedBlueprint());
1192: }
1193: buffer.append("\">\n");
1194:
1195: buffer.append("<security definesSecureTransfer=\"");
1196: buffer.append(getDefinesSecureTransfer());
1197: buffer.append("\">\n");
1198:
1199: for (Iterator i = owners.iterator(); i.hasNext();) {
1200: Principal principal = (Principal) i.next();
1201:
1202: buffer.append("<owner principalGroupId=\"");
1203: buffer.append(principal.getGroupId());
1204: buffer.append("\" principalId=\"");
1205: buffer.append(principal.getId());
1206: buffer.append("\"/>\n");
1207: }
1208: for (Iterator i = acl.iterator(); i.hasNext();) {
1209: ComponentAccess access = (ComponentAccess) i.next();
1210:
1211: buffer.append("<access principalGroupId=\"");
1212: buffer.append(access.getPrincipal().getGroupId());
1213: buffer.append("\" principalId=\"");
1214: buffer.append(access.getPrincipal().getId());
1215: buffer.append("\" accessType=\"");
1216: buffer.append(access.getPermission());
1217: buffer.append("\" mode=\"");
1218: buffer.append(access.getMode());
1219: buffer.append("\" parentMode=\"");
1220: buffer.append(access.getParentMode());
1221: buffer.append("\" validFrom=\"");
1222: buffer.append(access.getValidFrom());
1223: buffer.append("\" validTo=\"");
1224: buffer.append(access.getValidTo());
1225: buffer.append("\" period=\"");
1226: buffer.append(access.getPeriod());
1227: buffer.append("\" duration=\"");
1228: buffer.append(access.getDuration());
1229: buffer.append("\"/>\n");
1230: }
1231: buffer.append("</security>\n");
1232:
1233: buffer.append("</meta-info>\n");
1234:
1235: for (Iterator i = properties.iterator(); i.hasNext();) {
1236: ComponentProperty property = (ComponentProperty) i.next();
1237: String propertyName = property.getName();
1238: String propertyValue = property.getValue();
1239:
1240: buffer.append("<component-property name=\"");
1241: buffer.append(propertyName);
1242: buffer.append("\">");
1243: buffer.append("<![CDATA[");
1244: buffer.append(propertyValue);
1245: buffer.append("]]>");
1246: buffer.append("</component-property>\n");
1247: }
1248:
1249: for (int i = 0; i < metaKeys.size(); i++) {
1250: buffer.append("<metadata><key><![CDATA[");
1251: buffer.append(metaKeys.get(i));
1252: buffer.append("]]></key><value><![CDATA[");
1253: buffer.append(metaValues.get(i));
1254: buffer.append("]]></value></metadata>\n");
1255: }
1256:
1257: buffer.append("<content>\n");
1258:
1259: sensitiveCategoriesToXmlString(buffer, getContentCategories());
1260:
1261: for (Iterator i = resources.iterator(); i.hasNext();) {
1262: Object object = i.next();
1263: ContelligentResource resource;
1264: if (object instanceof ContelligentResourceReference) {
1265: resource = ((ContelligentResourceReference) object)
1266: .getResource();
1267: } else {
1268: resource = (ContelligentResource) object;
1269: }
1270: if (resource.isModified()) {
1271: resourceToXmlString(buffer, resource);
1272: }
1273: }
1274: buffer.append("</content>\n");
1275:
1276: buffer.append("<template>\n");
1277: sensitiveCategoriesToXmlString(buffer, getTemplateCategories());
1278: for (Iterator i = templates.iterator(); i.hasNext();) {
1279: Object object = i.next();
1280: ContelligentResource resource;
1281: if (object instanceof ContelligentResourceReference) {
1282: resource = ((ContelligentResourceReference) object)
1283: .getResource();
1284: } else {
1285: resource = (ContelligentResource) object;
1286: }
1287: resourceToXmlString(buffer, resource);
1288: }
1289: buffer.append("</template>\n");
1290:
1291: // To do: handle subcomponents.
1292:
1293: buffer.append("</component>\n");
1294:
1295: return buffer.toString();
1296: }
1297:
1298: private void refactorResources(
1299: Map<String, ContelligentResource> resourceMap,
1300: List<ContelligentCategory> categories) {
1301: Map<String, ContelligentResource> newResourceMap = new HashMap<String, ContelligentResource>();
1302: Iterator i = resourceMap.values().iterator();
1303: while (i.hasNext()) {
1304: ContelligentResource resource = (ContelligentResource) i
1305: .next();
1306: String identifier = ContelligentCategoryManager
1307: .createUniqueCategoryIdentifier(categories,
1308: resource.getCategoryMap());
1309: // update resource category map
1310: Map<String, String> categoryMap = resource.getCategoryMap();
1311: Map<String, String> newCategoryMap = new HashMap<String, String>();
1312: for (Iterator ci = categories.iterator(); ci.hasNext();) {
1313: ContelligentCategory category = (ContelligentCategory) ci
1314: .next();
1315: String categoryValue = ContelligentCategoryManager
1316: .getInstance().getCategoryByName(
1317: category.getName()).getDefaultValue();
1318: if (categoryMap != null
1319: && categoryMap.containsKey(category.getName())) {
1320: categoryValue = (String) categoryMap.get(category
1321: .getName());
1322: }
1323: newCategoryMap.put(category.getName(), categoryValue);
1324: }
1325: if (categoryMap != null) {
1326: categoryMap.clear();
1327: categoryMap.putAll(newCategoryMap);
1328: } else {
1329: resource.setCategoryMap(newCategoryMap);
1330: }
1331: resource.setModified(true);
1332: newResourceMap.put(identifier, resource);
1333: }
1334: resourceMap.clear();
1335: resourceMap.putAll(newResourceMap);
1336: }
1337:
1338: /**
1339: * Converts sensitive categories to XML.
1340: *
1341: * @param buffer
1342: * the buffer to which the XML representation is appended.
1343: * @param sensitiveCategories
1344: * the sensitive categories to be converted.
1345: */
1346: private void sensitiveCategoriesToXmlString(StringBuffer buffer,
1347: Collection sensitiveCategories) {
1348: synchronized (sensitiveCategories) {
1349: for (Iterator i = sensitiveCategories.iterator(); i
1350: .hasNext();) {
1351: ContelligentCategory category = (ContelligentCategory) i
1352: .next();
1353: String name = category.getName();
1354: String[] values = category.getSupportedValues();
1355:
1356: buffer.append("<sensitive-category name=\"");
1357: buffer.append(name);
1358: buffer.append("\" supportedValues=\"");
1359: buffer.append(values[0]);
1360: for (int j = 1; j < values.length; j++) {
1361: buffer.append(",");
1362: buffer.append(values[j]);
1363: }
1364: buffer.append("\"/>\n");
1365: }
1366: }
1367: }
1368:
1369: /**
1370: * Converts a resource to XML.
1371: *
1372: * @param buffer
1373: * the buffer to which the XML representation is appended.
1374: * @param resource
1375: * the resource to be converted.
1376: */
1377: private void resourceToXmlString(StringBuffer buffer,
1378: ContelligentResource resource) {
1379: Set categoryEntries = resource.getCategoryMap().entrySet();
1380: buffer.append("<resource>");
1381: for (Iterator i = categoryEntries.iterator(); i.hasNext();) {
1382: Map.Entry categoryEntry = (Map.Entry) i.next();
1383:
1384: buffer.append("<supported-category name=\"");
1385: buffer.append(categoryEntry.getKey());
1386: buffer.append("\" value=\"");
1387: buffer.append(categoryEntry.getValue());
1388: buffer.append("\"/>\n");
1389: }
1390:
1391: if (resource instanceof ContelligentBinaryResource) {
1392: ContelligentBinaryResource binaryResource = (ContelligentBinaryResource) resource;
1393: String contentType = binaryResource.getContentType();
1394: String extension = binaryResource.getExtension();
1395: String source = binaryResource.getSource();
1396:
1397: buffer.append("<binary contentType=\">\n");
1398: buffer.append(contentType);
1399: buffer.append("\" extension=\"");
1400: buffer.append(extension);
1401: buffer.append("\" src=\"");
1402: buffer.append(source);
1403: buffer.append("\"/>\n");
1404: } else if (resource instanceof ContelligentNumberResource) {
1405: // To do: handle number resource.
1406: } else if (resource instanceof ContelligentStringResource) {
1407: // To do: handle string resource.
1408: } else if (resource instanceof ContelligentTextResource) {
1409: ContelligentTextResource textResource = (ContelligentTextResource) resource;
1410:
1411: buffer.append("<text><![CDATA[");
1412: buffer.append(textResource.getText());
1413: buffer.append("]]></text>\n");
1414: } else {
1415: // Resource type is unknown.
1416: }
1417: buffer.append("</resource>\n");
1418: }
1419:
1420: public void setRenderer(String renderer) {
1421: this .renderer = renderer;
1422: }
1423:
1424: public String getRenderer() {
1425: return renderer;
1426: }
1427:
1428: public boolean hasContent() {
1429: return hasContent;
1430: }
1431:
1432: public void hasContent(boolean hasContent) {
1433: this .hasContent = hasContent;
1434: }
1435:
1436: public boolean hasRenderer() {
1437: return (getRenderer() != null && (getRenderer().equals(
1438: "transformer") || getRenderer().equals("template")));
1439: }
1440:
1441: /**
1442: * Returns whether this component is part of a read-only package. If this is the case, the component can never be
1443: * modified, not even with global administrative privileges. This will always return true if the server has been
1444: * globally set to read only mode, for instance if used in a cluster environment.
1445: */
1446: public boolean isReadOnly() {
1447: if (readOnly == null) {
1448: if (ServerInfo.getInstance().isServerReadOnly()) {
1449: readOnly = new Boolean(true);
1450: } else {
1451: try {
1452: PackageManager.Package pkg = PackageManager
1453: .getInstance().getPackage(getPath());
1454: readOnly = new Boolean(pkg.isReadOnly());
1455: } catch (PackageNotFoundException pne) {
1456: readOnly = new Boolean(false);
1457: }
1458: }
1459: }
1460: return readOnly.booleanValue();
1461: }
1462:
1463: public void setPublisherName(String publisherName) {
1464: this .publisherName = publisherName;
1465: }
1466:
1467: public void setPublisherType(String publisherType) {
1468: this .publisherType = publisherType;
1469: }
1470:
1471: public String getPublisherName() {
1472: return publisherName;
1473: }
1474:
1475: public String getPublisherType() {
1476: return publisherType;
1477: }
1478:
1479: public void setReadPermission(boolean readPermission) {
1480: this .readPermission = readPermission;
1481: }
1482:
1483: public boolean hasReadPermission() {
1484: return readPermission;
1485: }
1486: }
|