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.Container;
0021: import java.math.BigDecimal;
0022: import java.util.Collections;
0023: import java.util.HashMap;
0024: import java.util.HashSet;
0025: import java.util.Iterator;
0026: import java.util.List;
0027: import java.util.Map;
0028: import java.util.Set;
0029: import java.util.Stack;
0030: import java.util.Vector;
0031: import java.util.logging.Level;
0032: import java.util.logging.Logger;
0033:
0034: import javax.swing.JOptionPane;
0035:
0036: import org.apache.commons.collections.LRUMap;
0037: import org.xml.sax.helpers.AttributesImpl;
0038:
0039: import de.finix.contelligent.client.ContelligentClient;
0040: import de.finix.contelligent.client.base.category.DefaultContelligentCategory;
0041: import de.finix.contelligent.client.base.resource.ContelligentBinaryResource;
0042: import de.finix.contelligent.client.base.resource.ContelligentBooleanResource;
0043: import de.finix.contelligent.client.base.resource.ContelligentNumberResource;
0044: import de.finix.contelligent.client.base.resource.ContelligentStringResource;
0045: import de.finix.contelligent.client.base.resource.ContelligentTextResource;
0046: import de.finix.contelligent.client.event.ComponentDisplayEventListener;
0047: import de.finix.contelligent.client.event.ComponentEventListener;
0048: import de.finix.contelligent.client.event.ContelligentComponentDisplayEvent;
0049: import de.finix.contelligent.client.event.ContelligentComponentEvent;
0050: import de.finix.contelligent.client.event.ContelligentEvent;
0051: import de.finix.contelligent.client.event.ContelligentEventDispatcher;
0052: import de.finix.contelligent.client.event.ContelligentEventListener;
0053: import de.finix.contelligent.client.event.ContelligentLockEvent;
0054: import de.finix.contelligent.client.event.ContextEvent;
0055: import de.finix.contelligent.client.event.ContextEventListener;
0056: import de.finix.contelligent.client.event.LockEventListener;
0057: import de.finix.contelligent.client.event.ResourceEventListener;
0058: import de.finix.contelligent.client.event.ResourceModifiedEvent;
0059: import de.finix.contelligent.client.i18n.Resources;
0060: import de.finix.contelligent.client.modules.preferences.PreferencesModule;
0061: import de.finix.contelligent.client.remote.ActionResult;
0062: import de.finix.contelligent.client.remote.Actions;
0063: import de.finix.contelligent.client.remote.RemoteActionException;
0064: import de.finix.contelligent.client.security.ComponentAccess;
0065: import de.finix.contelligent.client.security.Principal;
0066: import de.finix.contelligent.client.util.ExceptionDialog;
0067: import de.zeigermann.xml.simpleImporter.ConversionHelpers;
0068: import de.zeigermann.xml.simpleImporter.SimpleImportHandler;
0069: import de.zeigermann.xml.simpleImporter.SimplePath;
0070:
0071: public class ComponentFactory extends ContelligentEventDispatcher {
0072:
0073: private static Logger logger = Logger
0074: .getLogger(ComponentFactory.class.getName());
0075:
0076: private final static Object[] YES_CANCEL_OPTIONS = {
0077: Resources.getLocalString("yes"),
0078: Resources.getLocalString("cancel") };
0079:
0080: private static ComponentFactory componentFactory = null;
0081:
0082: private Context currentContext, parentContext;
0083:
0084: private List<Lock> locks = new Vector<Lock>();
0085:
0086: private List<Lock> sharedLocks = new Vector<Lock>();
0087:
0088: private Set<String> editedComponentPaths = new HashSet<String>();
0089:
0090: private int LOAD_SUBCOMPONENTS = 0;
0091:
0092: private int RELOAD_COMPONENT = 1;
0093:
0094: /**
0095: * caches is a map that contains key = component path value = component
0096: */
0097: private int MAX_SIZE = PreferencesModule.getPreferences().getInt(
0098: PreferencesModule.CACHED_COMPONENTS,
0099: PreferencesModule.DEFAULT_CACHED_COMPONENTS);
0100:
0101: private Map<String, ContelligentComponent> cache = new LRUMap(
0102: MAX_SIZE);
0103:
0104: /**
0105: * transactionCaches is a map that contains key = componentPath value =
0106: * component
0107: */
0108: private List<ContelligentComponent> transactionCache = new Vector<ContelligentComponent>();
0109:
0110: /**
0111: * Constructor registers the created component factory instance as event
0112: * queue listener at the event queue.
0113: */
0114: private ComponentFactory() {
0115: }
0116:
0117: /**
0118: * This method creates a component factory instance if there is none and
0119: * returns it. - singleton -
0120: */
0121: public static ComponentFactory getInstance() {
0122: if (ComponentFactory.componentFactory == null) {
0123: ComponentFactory.componentFactory = new ComponentFactory();
0124: }
0125: return ComponentFactory.componentFactory;
0126: }
0127:
0128: public void clear() {
0129: cache = new LRUMap(MAX_SIZE);
0130: transactionCache = new Vector<ContelligentComponent>();
0131: locks = new Vector<Lock>();
0132: sharedLocks = new Vector<Lock>();
0133: }
0134:
0135: public synchronized boolean isCached(String path) {
0136: if (path == null) {
0137: return false;
0138: }
0139: path = ComponentPath.toComponentPath(path);
0140: synchronized (cache) {
0141: return (cache != null && cache.containsKey(path));
0142: }
0143: }
0144:
0145: private void lock(String target, String owner, String principal,
0146: long timestamp, String context, String wfId, boolean shared) {
0147: Lock lock = getLock(target, shared);
0148: if (lock == null) {
0149: lock = new Lock(target, owner, principal, timestamp,
0150: context, wfId, shared);
0151: if (shared) {
0152: sharedLocks.add(lock);
0153: } else {
0154: locks.add(lock);
0155: }
0156: } else {
0157: lock.setTimestamp(timestamp);
0158: lock.setOwner(owner);
0159: lock.setPrincipal(principal);
0160: lock.setWfId(wfId);
0161: lock.setContext(context);
0162: }
0163: }
0164:
0165: private void unlock(String path, boolean shared) {
0166: if (shared) {
0167: for (int i = 0; i < sharedLocks.size(); i++) {
0168: Lock lock = (Lock) sharedLocks.get(i);
0169: if (lock.getPath().equals(path)) {
0170: sharedLocks.remove(i);
0171: }
0172: }
0173: } else {
0174: for (int i = 0; i < locks.size(); i++) {
0175: Lock lock = (Lock) locks.get(i);
0176: if (lock.getPath().equals(path)) {
0177: locks.remove(i);
0178: }
0179: }
0180: }
0181: }
0182:
0183: /**
0184: * This method can be used to check if a path is the root of a lock.
0185: *
0186: * @param path
0187: * The path to check
0188: * @return
0189: */
0190: public boolean isLock(String path, boolean shared) {
0191: if (path.length() == 0) {
0192: path = "/";
0193: }
0194: if (shared) {
0195: for (int i = 0; i < sharedLocks.size(); i++) {
0196: Lock lock = (Lock) sharedLocks.get(i);
0197: if (path.equals(lock.getPath())) {
0198: return true;
0199: }
0200: }
0201: } else {
0202: for (int i = 0; i < locks.size(); i++) {
0203: Lock lock = (Lock) locks.get(i);
0204: if (path.equals(lock.getPath())) {
0205: return true;
0206: }
0207: }
0208: }
0209: return false;
0210: }
0211:
0212: public boolean isLocked(ContelligentComponent component) {
0213: return isLocked(component.getPathNullIsSlash());
0214: }
0215:
0216: public boolean isLockedPrivate(ContelligentComponent component) {
0217: return isLockedPrivate(component.getPathNullIsSlash());
0218: }
0219:
0220: /**
0221: * Checks whether a path is part of a locked subtree or not.
0222: *
0223: * @param path
0224: * @return
0225: */
0226: public boolean isLocked(String path) {
0227: // XXX should not...
0228: if (path.length() == 0) {
0229: path = "/";
0230: }
0231: return ((getLock(path, false) != null) || (getLock(path, true) != null));
0232: }
0233:
0234: public boolean isLockedPrivate(String path) {
0235: // XXX should not...
0236: if (path.length() == 0) {
0237: path = "/";
0238: }
0239: return (getLock(path, false) != null);
0240: }
0241:
0242: public boolean isLockedByMe(ContelligentComponent component) {
0243: return isLockedByMe(component.getPathNullIsSlash());
0244: }
0245:
0246: public boolean isLockedByMe(String path) {
0247: if (path.length() == 0) {
0248: logger
0249: .log(Level.WARNING,
0250: "The given path has length 0! Setting it to root path [/]");
0251: path = "/";
0252: }
0253: Lock lock = getLock(path, false);
0254: if (lock != null) {
0255: if (isMyLock(lock)) {
0256: return true;
0257: } else {
0258: return false;
0259: }
0260: }
0261: lock = getLock(path, true);
0262: if (lock != null && isMyLock(lock)) {
0263: return true;
0264: }
0265: return false;
0266: }
0267:
0268: public boolean isMyLock(Lock lock) {
0269: if (!isLockInCurrentContext(lock)) {
0270: return false;
0271: }
0272: return lock.getPrincipal().equals(
0273: Session.getInstance().getUser().getPrincipal()
0274: .getDisplayName());
0275: }
0276:
0277: public boolean isLockedInWf(ContelligentComponent component) {
0278: return isLockedInWf(component.getPathNullIsSlash());
0279: }
0280:
0281: public boolean isLockendInCurrentContext(
0282: ContelligentComponent component) {
0283: return isLockendInCurrentContext(component.getPathNullIsSlash());
0284: }
0285:
0286: public boolean isLockendInCurrentContext(String path) {
0287: Lock lock = getLock(path, false);
0288: if (lock == null) {
0289: return false;
0290: }
0291: return isLockInCurrentContext(lock) && !lock.isShared();
0292: }
0293:
0294: public boolean isLockInCurrentContext(Lock lock) {
0295: return lock.getContext().equals(currentContext.getName());
0296: }
0297:
0298: public boolean isLockedInWf(String path) {
0299: Lock lock = getLock(path, true);
0300: if (lock != null && isLockInWf(lock)) {
0301: return true;
0302: }
0303: return false;
0304: }
0305:
0306: /**
0307: * Used to determine whether a global lock created by someone else should
0308: * appear yellow (context-locked) instead of the usual red (user- and
0309: * context-locked).
0310: *
0311: * @param lock
0312: * @return boolean
0313: */
0314: public boolean isLockInWf(Lock lock) {
0315: return (isLockInCurrentContext(lock)
0316: && !lock.getContext().equals(
0317: ServerInfo.getInstance().getMainContextName()) && lock
0318: .isShared());
0319: }
0320:
0321: public Lock getLock(ContelligentComponent component, boolean shared) {
0322: return getLock(component.getPathNullIsSlash(), shared);
0323: }
0324:
0325: public synchronized Lock getLock(String path, boolean shared) {
0326: if (shared) {
0327: for (int i = 0; i < sharedLocks.size(); i++) {
0328: Lock lock = (Lock) sharedLocks.get(i);
0329: String dir = ComponentPath.getServerComponentDir(path);
0330: if (path.equals(lock.getPath())
0331: || dir.startsWith(ComponentPath
0332: .toServerComponentPath(lock.getPath()))) {
0333: return lock;
0334: }
0335: }
0336: } else {
0337: for (int i = 0; i < locks.size(); i++) {
0338: Lock lock = (Lock) locks.get(i);
0339: String dir = ComponentPath.getServerComponentDir(path);
0340: if (path.equals(lock.getPath())
0341: || dir.startsWith(ComponentPath
0342: .toServerComponentPath(lock.getPath()))) {
0343: return lock;
0344: }
0345: }
0346: }
0347: return null;
0348: }
0349:
0350: public Vector<Lock> getLocks() {
0351: return new Vector<Lock>(locks);
0352: }
0353:
0354: public Vector<Lock> getSharedLocks() {
0355: return new Vector<Lock>(sharedLocks);
0356: }
0357:
0358: public boolean lockSubtree(ContelligentComponent component) {
0359: if (component != null) {
0360: if (isLockedPrivate(component.getPathNullIsSlash())) {
0361: logger.log(Level.FINEST, "ContelligentComponent '"
0362: + component.getPath() + "' is locked!");
0363: if (isLockedByMe(component)) {
0364: return true;
0365: }
0366: } else {
0367: // lock subtree
0368: try {
0369: String componentPath = component
0370: .getPathNullIsSlash();
0371: ActionResult response = Actions.lock(componentPath);
0372: response.showErrors();
0373: if (response.getState().equals(ActionResult.OK)) {
0374: // create unlock event
0375: final ContelligentLockEvent lockEvent = new ContelligentLockEvent(
0376: this , componentPath, Session
0377: .getInstance().getUser()
0378: .getPrincipal()
0379: .getDisplayName(), Session
0380: .getInstance().getUser()
0381: .getPrincipal()
0382: .getDisplayName(), System
0383: .currentTimeMillis(),
0384: ComponentFactory.getInstance()
0385: .getCurrentContext().getName(),
0386: "", false,
0387: ContelligentLockEvent.COMPONENT_LOCKED);
0388: fireComponentLockEvent(lockEvent);
0389: return true;
0390: }
0391: } catch (RemoteActionException rae) {
0392: ExceptionDialog.show(rae);
0393: }
0394: }
0395: }
0396: return false;
0397: }
0398:
0399: // Tracking of edited components
0400:
0401: public void addEditedComponent(String path) {
0402: editedComponentPaths.add(path);
0403: }
0404:
0405: public void removeEditedComponent(String path) {
0406: editedComponentPaths.remove(path);
0407: }
0408:
0409: public boolean isComponentEdited(String path) {
0410: return editedComponentPaths.contains(path);
0411: }
0412:
0413: public int countEditedComponents() {
0414: return editedComponentPaths.size();
0415: }
0416:
0417: public void clearEditedComponents() {
0418: editedComponentPaths = new HashSet();
0419: }
0420:
0421: /**
0422: * Retrieves a component. If possible, this uses a client side cache to minimize calls to the server.
0423: *
0424: * @param path The absolute component path for the component to be retrieved.
0425: * @return
0426: * @throws ComponentNotFoundException
0427: */
0428: public synchronized ContelligentComponent getComponent(String path)
0429: throws ComponentNotFoundException {
0430: synchronized (cache) {
0431: if (path == null) {
0432: throw new ComponentNotFoundException(
0433: Resources
0434: .getLocalString("component_not_found_path_is_null"));
0435: }
0436: path = ComponentPath.toComponentPath(path);
0437:
0438: // check whether component can be taken from cache
0439: if (cache.containsKey(path)) {
0440: // get component from map
0441: ContelligentComponent component = (ContelligentComponent) cache
0442: .get(path);
0443: if (component.isValid())
0444: return component;
0445: }
0446: // load component from server
0447: ContelligentComponent component = load(path);
0448: cache.put(path, component);
0449: return component;
0450: }
0451: }
0452:
0453: /**
0454: * Resolves a relative path from a base component. Note that this should only be used for complex
0455: * relative paths, as used for instance in Links. To simply retrieve a known subcomponent, this
0456: * method must not be used, as it incurs a significant performance overhead. This is due to the
0457: * relative path being resolved by the server.
0458: *
0459: * @param root The absolute base component path for the operation.
0460: * @param path The relative path to the resolved.
0461: * @return
0462: * @throws ComponentNotFoundException
0463: */
0464: public synchronized ContelligentComponent getComponent(String root,
0465: String path) throws ComponentNotFoundException {
0466: if (path.startsWith("/")) {
0467: return getComponent(path);
0468: }
0469: root = ComponentPath.toComponentPath(root);
0470: // check for this root:path combination in the component cache
0471: String key = root + ":" + path;
0472: synchronized (cache) {
0473: if (cache.containsKey(key)) {
0474: // get component from map
0475: ContelligentComponent component = (ContelligentComponent) cache
0476: .get(key);
0477: if (component.isValid())
0478: return component;
0479: }
0480: // load component from server
0481: ContelligentComponent component = load(root, path);
0482: // check if component exists already in cache under the original
0483: // path
0484: if (cache.containsKey(component.getPath())) {
0485: component = (ContelligentComponent) cache.get(component
0486: .getPath());
0487: } else {
0488: cache.put(component.getPath(), component);
0489: }
0490: // insert the pseudo-key into the cache
0491: cache.put(key, component);
0492: return component;
0493: }
0494: }
0495:
0496: public void assureChildrenLoaded(ContelligentComponent component)
0497: throws ComponentNotFoundException {
0498: if (component.hasSubcomponents()
0499: && !component.isSubcomponentsLoaded()) {
0500: load(component, LOAD_SUBCOMPONENTS);
0501: }
0502: }
0503:
0504: public synchronized int getCacheSize() {
0505: synchronized (cache) {
0506: return cache.size();
0507: }
0508: }
0509:
0510: public int getMaxCacheSize() {
0511: return MAX_SIZE;
0512: }
0513:
0514: // //////////////////////////////////////////////////////
0515: // EVENT DISPACHTING MASTER PART
0516:
0517: public void addContextEventListener(ContextEventListener listener,
0518: boolean usesSwing) {
0519: addListener(listener, ContextEventListener.class, usesSwing);
0520: }
0521:
0522: public void removeContextEventListener(ContextEventListener listener) {
0523: removeListener(listener, ContextEventListener.class);
0524: }
0525:
0526: public void addComponentEventListener(
0527: ComponentEventListener listener, boolean usesSwing) {
0528: addListener(listener, ComponentEventListener.class, usesSwing);
0529: }
0530:
0531: public void removeComponentEventListener(
0532: ComponentEventListener listener) {
0533: removeListener(listener, ComponentEventListener.class);
0534: }
0535:
0536: public void addLockEventListener(LockEventListener listener,
0537: boolean usesSwing) {
0538: addListener(listener, LockEventListener.class, usesSwing);
0539: }
0540:
0541: public void removeLockEventListener(LockEventListener listener) {
0542: removeListener(listener, LockEventListener.class);
0543: }
0544:
0545: public void addComponentDisplayEventListener(
0546: ComponentDisplayEventListener listener, boolean usesSwing) {
0547: addListener(listener, ComponentDisplayEventListener.class,
0548: usesSwing);
0549: }
0550:
0551: public void removeComponentDisplayEventListener(
0552: ComponentDisplayEventListener listener) {
0553: removeListener(listener, ComponentDisplayEventListener.class);
0554: }
0555:
0556: public void addResourceEventListener(
0557: ResourceEventListener listener, boolean usesSwing) {
0558: addListener(listener, ResourceEventListener.class, usesSwing);
0559: }
0560:
0561: public void removeResourceEventListener(
0562: ResourceEventListener listener) {
0563: removeListener(listener, ResourceEventListener.class);
0564: }
0565:
0566: public void fireResourceModifyEvent(ResourceModifiedEvent event) {
0567: // simply inform listeners
0568: addEvent(event);
0569: }
0570:
0571: public void fireComponentAddInProgressEvent(
0572: ContelligentComponentDisplayEvent event) {
0573: // simply inform listeners
0574: addEvent(event);
0575: }
0576:
0577: public void fireComponentAddAbortedEvent(
0578: ContelligentComponentDisplayEvent event) {
0579: // simply inform listeners
0580: addEvent(event);
0581: }
0582:
0583: public void fireComponentRemoveInProgressEvent(
0584: ContelligentComponentDisplayEvent event) {
0585: // simply inform listeners
0586: addEvent(event);
0587: }
0588:
0589: public void fireComponentRemoveAbortedEvent(
0590: ContelligentComponentDisplayEvent event) {
0591: // simply inform listeners
0592: addEvent(event);
0593: }
0594:
0595: public void fireComponentSelectEvent(
0596: ContelligentComponentDisplayEvent event) {
0597: // simply inform listeners
0598: addEvent(event);
0599: }
0600:
0601: public void fireComponentEditEvent(
0602: ContelligentComponentDisplayEvent event) {
0603: // simply inform listeners
0604: addEvent(event);
0605: }
0606:
0607: public synchronized void fireComponentAddEvent(
0608: ContelligentComponentEvent event) {
0609: logger.log(Level.FINER, "received event: " + event.toString());
0610: try {
0611: String componentDir = ComponentPath.getComponentDir(event
0612: .getTarget());
0613: logger.log(Level.FINEST, "componentDir: " + componentDir);
0614:
0615: String componentName = ComponentPath.getComponentName(event
0616: .getTarget());
0617: logger.log(Level.FINEST, "componentName: " + componentName);
0618:
0619: synchronized (cache) {
0620: if (isCached(componentDir)) {
0621: ContelligentComponent component = getComponent(componentDir);
0622: component.addSubcomponent(componentName);
0623: if (!component.instanceOf(Type.SORTED_FOLDER)) {
0624: Collections.sort(component.getSubcomponents());
0625: }
0626: }
0627: }
0628: } catch (ComponentNotFoundException cnfe) {
0629: logger.log(Level.SEVERE, "Could not dispatch event!", cnfe);
0630: }
0631: // finally inform listeners
0632: addEvent(event);
0633: }
0634:
0635: public synchronized void fireComponentChangeEvent(
0636: ContelligentComponentEvent event) {
0637: logger.log(Level.FINER, "received event: " + event.toString());
0638: try {
0639: String componentPath = ComponentPath.toComponentPath(event
0640: .getTarget());
0641:
0642: if (isCached(componentPath)) {
0643: ContelligentComponent component = getComponent(componentPath);
0644: reload(component);
0645: // finally inform listeners
0646: addEvent(event);
0647: }
0648: } catch (ComponentNotFoundException cnfe) {
0649: logger.log(Level.SEVERE, "Could not dispatch event!", cnfe);
0650: }
0651:
0652: }
0653:
0654: public synchronized void fireComponentRemoveEvent(
0655: ContelligentComponentEvent event) {
0656: logger.log(Level.FINER, "received event: " + event.toString());
0657: try {
0658: String componentDir = ComponentPath.getComponentDir(event
0659: .getTarget());
0660: String componentName = ComponentPath.getComponentName(event
0661: .getTarget());
0662: String componentPath = ComponentPath.toComponentPath(event
0663: .getTarget());
0664:
0665: synchronized (cache) {
0666: if (isCached(componentDir)) {
0667: ContelligentComponent component = getComponent(componentDir);
0668: // it might be that this component has been deleted directly
0669: // on the user-driven delete action, if so skip this...
0670: if (component.hasSubcomponent(componentName)) {
0671: try {
0672: component.deleteSubcomponent(componentName);
0673: } catch (ChildNotFoundException cnfe) {
0674: logger.log(Level.WARNING, "exception: "
0675: + cnfe);
0676: }
0677: }
0678: if (isCached(componentPath)) {
0679: invalidateSubtreeIncluding(componentPath);
0680: }
0681: // finally inform listeners
0682: addEvent(event);
0683: }
0684: }
0685: } catch (ComponentNotFoundException cnfe) {
0686: logger.log(Level.SEVERE, "Could not dispatch event!", cnfe);
0687: }
0688: }
0689:
0690: public void fireComponentLockEvent(ContelligentLockEvent event) {
0691: logger.log(Level.FINE, "Creating lock for component: "
0692: + event.getTarget());
0693: lock(event.getTarget(), event.getOwner(), event.getPrincipal(),
0694: event.getTimestamp(), event.getContext(), event
0695: .getWfId(), event.isShared());
0696:
0697: if (isCached(ComponentPath.toComponentPath(event.getTarget()))) {
0698: // finally inform listeners
0699: addEvent(event);
0700: }
0701: }
0702:
0703: public void fireComponentUnlockEvent(ContelligentLockEvent event) {
0704: logger.log(Level.FINE, "Removing lock for component: "
0705: + event.getTarget());
0706: unlock(event.getTarget(), event.isShared());
0707:
0708: if (isCached(ComponentPath.toComponentPath(event.getTarget()))) {
0709: // finally inform listeners
0710: addEvent(event);
0711: }
0712: }
0713:
0714: public void fireContextCreateEvent(ContextEvent event) {
0715: // simply inform listeners
0716: addEvent(event);
0717: }
0718:
0719: public void fireContextDiscardEvent(ContextEvent event) {
0720: // simply inform listeners
0721: addEvent(event);
0722: }
0723:
0724: public void fireContextSwitchEvent(ContextEvent event) {
0725: setCurrentContext(event.getContext());
0726: // clear cache:
0727: cache = new LRUMap(MAX_SIZE);
0728:
0729: // finally inform listeners
0730: addEvent(event);
0731: }
0732:
0733: // implements abstract method in ContelligentEventDispatcher
0734: protected void notifyListener(ContelligentEvent event,
0735: ContelligentEventListener listener, Class listenerType) {
0736:
0737: if (listenerType == ContextEventListener.class) {
0738: ContextEventListener l = (ContextEventListener) listener;
0739: if (event instanceof ContextEvent) {
0740: ContextEvent e = (ContextEvent) event;
0741: if (e.getType() == ContextEvent.CONTEXT_DISCARDED) {
0742: l.onContextDiscarded(e);
0743: } else if (e.getType() == ContextEvent.CONTEXT_CREATED) {
0744: l.onContextCreated(e);
0745: } else if (e.getType() == ContextEvent.CONTEXT_SWITCHED) {
0746: l.onContextSwitched(e);
0747: }
0748: }
0749:
0750: } else if (listenerType == ResourceEventListener.class) {
0751: ResourceEventListener l = (ResourceEventListener) listener;
0752: if (event instanceof ResourceModifiedEvent) {
0753: l.onResourceModified((ResourceModifiedEvent) event);
0754: }
0755:
0756: } else if (listenerType == ComponentDisplayEventListener.class) {
0757: ComponentDisplayEventListener l = (ComponentDisplayEventListener) listener;
0758: if (event instanceof ContelligentComponentDisplayEvent) {
0759: ContelligentComponentDisplayEvent e = (ContelligentComponentDisplayEvent) event;
0760:
0761: if (e.getType() == ContelligentComponentDisplayEvent.COMPONENT_ADD_IN_PROGRESS) {
0762: l.onComponentAddInProgress(e);
0763: } else if (e.getType() == ContelligentComponentDisplayEvent.COMPONENT_ADD_ABORTED) {
0764: l.onComponentAddAborted(e);
0765: } else if (e.getType() == ContelligentComponentDisplayEvent.COMPONENT_REMOVE_IN_PROGRESS) {
0766: l.onComponentRemoveInProgress(e);
0767: } else if (e.getType() == ContelligentComponentDisplayEvent.COMPONENT_REMOVE_ABORTED) {
0768: l.onComponentRemoveAborted(e);
0769: } else if (e.getType() == ContelligentComponentDisplayEvent.COMPONENT_SELECTED) {
0770: l.onComponentSelected(e);
0771: } else if (e.getType() == ContelligentComponentDisplayEvent.COMPONENT_FOLLOW_SERVER) {
0772: l.onComponentSelected(e);
0773: } else if (e.getType() == ContelligentComponentDisplayEvent.COMPONENT_EDIT) {
0774: l.onComponentEdit(e);
0775: }
0776: }
0777:
0778: } else if (listenerType == ComponentEventListener.class) {
0779: ComponentEventListener l = (ComponentEventListener) listener;
0780: if (event instanceof ContelligentComponentEvent) {
0781: ContelligentComponentEvent e = (ContelligentComponentEvent) event;
0782: if (e.getType() == ContelligentComponentEvent.COMPONENT_ADDED) {
0783: l.onComponentAdded(e);
0784: } else if (e.getType() == ContelligentComponentEvent.COMPONENT_REMOVED) {
0785: l.onComponentRemoved(e);
0786: } else if (e.getType() == ContelligentComponentEvent.COMPONENT_CHANGED) {
0787: l.onComponentChanged(e);
0788: }
0789: }
0790:
0791: } else if (listenerType == LockEventListener.class) {
0792: LockEventListener l = (LockEventListener) listener;
0793: if (event instanceof ContelligentLockEvent) {
0794: ContelligentLockEvent e = (ContelligentLockEvent) event;
0795: if (e.getType() == ContelligentLockEvent.COMPONENT_LOCKED) {
0796: l.onComponentLocked(e);
0797: } else if (e.getType() == ContelligentLockEvent.COMPONENT_UNLOCKED) {
0798: l.onComponentUnlocked(e);
0799: }
0800: }
0801:
0802: }
0803: }
0804:
0805: // //////////////////////////////////////////////////////
0806:
0807: /**
0808: * Invalidates a single component.
0809: */
0810: public void invalidate(ContelligentComponent component) {
0811: invalidate(component.getPath());
0812: }
0813:
0814: /**
0815: * Invalidates a single component.
0816: */
0817: public synchronized void invalidate(String path) {
0818: synchronized (cache) {
0819: if (cache.containsKey(path)) {
0820: ContelligentComponent component = ((ContelligentComponent) cache
0821: .get(path));
0822: if (component != null) {
0823: component.invalidate();
0824: }
0825: cache.remove(path);
0826: }
0827: }
0828: }
0829:
0830: /**
0831: * Invalidates a subtree including its root component.
0832: */
0833: public void invalidateSubtreeIncluding(
0834: ContelligentComponent component) {
0835: invalidateSubtreeIncluding(component.getPath());
0836: }
0837:
0838: /**
0839: * Invalidates a subtree including its root component.
0840: */
0841: public void invalidateSubtreeIncluding(String path) {
0842: invalidateSubtreeExcluding(path);
0843: invalidate(path);
0844: }
0845:
0846: /**
0847: * Invalidates a subtree excluding its root component.
0848: */
0849: public void invalidateSubtreeExcluding(
0850: ContelligentComponent component) {
0851: invalidateSubtreeExcluding(component.getPath());
0852: }
0853:
0854: /**
0855: * Invalidates a subtree excluding its root component.
0856: */
0857: public synchronized void invalidateSubtreeExcluding(String path) {
0858: synchronized (cache) {
0859: for (Iterator i = cache.entrySet().iterator(); i.hasNext();) {
0860: Map.Entry entry = (Map.Entry) i.next();
0861: String key = (String) entry.getKey();
0862: if (entry.getValue() == null) {
0863: i.remove();
0864: } else if (key.indexOf(path) == 0 && !key.equals(path)) {
0865: ContelligentComponent component = ((ContelligentComponent) entry
0866: .getValue());
0867: if (component != null) {
0868: component.invalidate();
0869: }
0870: i.remove();
0871: }
0872: }
0873: }
0874: }
0875:
0876: private synchronized ContelligentComponent load(String path)
0877: throws ComponentNotFoundException {
0878: return load(null, null, path, LOAD_SUBCOMPONENTS);
0879: }
0880:
0881: private synchronized ContelligentComponent load(String root,
0882: String path) throws ComponentNotFoundException {
0883: return load(null, root, path, LOAD_SUBCOMPONENTS);
0884: }
0885:
0886: private synchronized ContelligentComponent load(
0887: ContelligentComponent component, int mode)
0888: throws ComponentNotFoundException {
0889: synchronized (component) {
0890: return load(component, null, component.getPath(), mode);
0891: }
0892: }
0893:
0894: /**
0895: * The load method invokes the detailedComponentView-action on the
0896: * contelligent server and gets the component specified by path and root.
0897: *
0898: * @param root
0899: * the absolute path to the component that should be loaded
0900: * @param path
0901: * an optional relative path that can be used to resolve some
0902: * links or finix tags
0903: * @return the loaded component
0904: */
0905: private synchronized ContelligentComponent load(
0906: ContelligentComponent rootComponent, String root,
0907: String path, int mode) throws ComponentNotFoundException {
0908: try {
0909:
0910: ComponentImportHandler handler = new ComponentImportHandler(
0911: rootComponent, mode);
0912: ActionResult actionResult = Actions.load(handler, root,
0913: path, 1, false, false);
0914: // FIXME this should be displayed to user, but there are too many
0915: // error messages...
0916: // actionResult.showErrors();
0917: if (!actionResult.getState().equals("ok")) {
0918: throw new ComponentNotFoundException(Resources
0919: .getLocalString("component_not_found",
0920: new String[] { root, path }));
0921: }
0922: return handler.getRootComponent();
0923: } catch (RemoteActionException e) {
0924: ExceptionDialog.show(e);
0925: throw new ComponentNotFoundException(Resources
0926: .getLocalString("component_not_found",
0927: new String[] { root, path }), e);
0928: }
0929: }
0930:
0931: public synchronized void reload(ContelligentComponent component)
0932: throws ComponentNotFoundException {
0933: // load component from server
0934: component.clear();
0935: load(component, RELOAD_COMPONENT);
0936: }
0937:
0938: public synchronized void save(ContelligentComponent component) {
0939: // Apply new values to contelligent server
0940: if (component.isModified() || component.isAclModified()
0941: || component.isResourceModified()) {
0942: if (transactionCache.contains(component)) {
0943: transactionCache.remove(component);
0944: }
0945: transactionCache.add(component);
0946: }
0947: }
0948:
0949: /**
0950: * Commit to the server the changes made to component on the client.
0951: */
0952: public synchronized boolean commit(String environment) {
0953: for (int c = 0; c < transactionCache.size(); c++) {
0954: ContelligentComponent component = (ContelligentComponent) transactionCache
0955: .get(c);
0956: try {
0957: ActionResult result = Actions.updateComponent(
0958: environment, component);
0959: if (result.getState().equals(ActionResult.FAILED)) {
0960: String errorMessage = null;
0961: if (result.hasError(Errors.TRANSFORMER_INVALID)) {
0962: errorMessage = "error_transformer_invalid";
0963: } else if (result.hasError(Errors.COMPONENT_UPDATE)) {
0964: errorMessage = "error_component_update";
0965: } else if (result
0966: .hasError(Errors.UNCLOSED_RENDER_TAG)) {
0967: errorMessage = "error_component_update";
0968: } else if (result
0969: .hasError(Errors.INVALID_RENDER_TAG)) {
0970: errorMessage = "error_component_update";
0971: } else if (result.hasError(Errors.STRING_TOO_LONG)) {
0972: errorMessage = "error_component_update";
0973: } else if (result.hasError(Errors.DEAD_RELATIONS)) {
0974: errorMessage = "error_component_update";
0975: } else if (result
0976: .hasError(Errors.PERSISTENCE_GENERIC)) {
0977: errorMessage = "error_component_update";
0978: } else if (result.hasError(Errors.NO_PERMISSION)) {
0979: errorMessage = "error_no_permission";
0980: } else if (result
0981: .hasError(Errors.COMPONENT_LOCKED_IN_OTHER_CM)) {
0982: errorMessage = "error_component_update";
0983: } else if (result.hasError(Errors.LOCK_BLOCKING)) {
0984: errorMessage = "error_component_update";
0985: } else if (result
0986: .hasError(Errors.INVALID_PROPERTY_VALUE)) {
0987: errorMessage = "error_component_update";
0988: } else {
0989: errorMessage = "error_unknown";
0990: }
0991: JOptionPane.showMessageDialog(ContelligentClient
0992: .getActiveFrame(), Resources
0993: .getLocalString(errorMessage), Resources
0994: .getLocalString("component_update_title"),
0995: JOptionPane.ERROR_MESSAGE);
0996: result.showErrors();
0997: transactionCache.clear();
0998: return false;
0999: }
1000: } catch (RemoteActionException e) {
1001: ExceptionDialog.show(e);
1002: transactionCache.clear();
1003: return false;
1004: }
1005: }
1006: transactionCache.clear();
1007: return true;
1008: }
1009:
1010: /**
1011: * Gets parent context of current one.
1012: *
1013: * @return parent conext or null if current one is production context and
1014: * thus has no parent
1015: */
1016: public Context getParentContext() {
1017: return parentContext;
1018: }
1019:
1020: /**
1021: * Sets parent context of current one.
1022: *
1023: * @throws RemoteActionException
1024: */
1025: public void setParentContext() throws RemoteActionException {
1026: String currentName = getCurrentContext().getName();
1027: int lastDot = currentName.lastIndexOf('.');
1028: if (lastDot != -1) {
1029: String parentName = currentName.substring(0, lastDot);
1030: parentContext = Context.get(parentName);
1031: } else {
1032: parentContext = null;
1033: }
1034: }
1035:
1036: public Context getCurrentContext() {
1037: if (currentContext == null) {
1038: setCurrentContext(ServerInfo.getInstance()
1039: .getMainContextName());
1040: }
1041: return currentContext;
1042: }
1043:
1044: public void setCurrentContext(String currentContextName) {
1045: try {
1046: this .currentContext = Context.get(currentContextName);
1047: currentContext.loadACL();
1048: setParentContext();
1049: } catch (RemoteActionException rae) {
1050: logger.log(Level.SEVERE, "Failed to set current context "
1051: + currentContextName, rae);
1052: ExceptionDialog.show(rae);
1053: }
1054: }
1055:
1056: public boolean isRootContext() {
1057: return currentContext.isRootContext();
1058: }
1059:
1060: public boolean switchToMainContext() {
1061: return switchCurrentContext(ServerInfo.getInstance()
1062: .getMainContextName());
1063: }
1064:
1065: public boolean switchCurrentContext(String contextName) {
1066: // try to acquire context...
1067: try {
1068: ActionResult response = Actions.acquireContext(contextName);
1069: response.showErrors();
1070: if (response.getState().equals(ActionResult.OK)) {
1071: final ContextEvent contextSwitchedEvent = new ContextEvent(
1072: this , contextName,
1073: ContextEvent.CONTEXT_SWITCHED);
1074: fireContextSwitchEvent(contextSwitchedEvent);
1075: return true;
1076: } else {
1077: logger.log(Level.SEVERE, "Could not switch to context "
1078: + contextName);
1079: return false;
1080: }
1081: } catch (RemoteActionException rae) {
1082: ExceptionDialog.show(rae);
1083: }
1084: return false;
1085: }
1086:
1087: public boolean createContext(String context, String xml) {
1088: // try to create context...
1089: try {
1090: ActionResult response = Actions.createContext(context, xml);
1091: response.showErrors();
1092: if (response.getState().equals(ActionResult.OK)) {
1093: cache = new LRUMap(MAX_SIZE);
1094: return true;
1095: }
1096: } catch (RemoteActionException rae) {
1097: ExceptionDialog.show(rae);
1098: }
1099: return false;
1100: }
1101:
1102: public boolean discardCurrentContext(String environment) {
1103: // try to discard context...
1104: try {
1105: ActionResult response = Actions.discardContext(environment,
1106: currentContext.getName());
1107: response.showErrors();
1108: if (response.getState().equals(ActionResult.OK)) {
1109: cache = new LRUMap(MAX_SIZE);
1110: return true;
1111: }
1112: } catch (RemoteActionException rae) {
1113: ExceptionDialog.show(rae);
1114: }
1115: return false;
1116: }
1117:
1118: public boolean commitCurrentContext(String environment,
1119: Container parent) {
1120: // try to commit context...
1121: try {
1122: ActionResult response = Actions.commitContext(environment,
1123: currentContext.getName());
1124:
1125: response.showErrors();
1126: if (response.getState().equals(ActionResult.OK)) {
1127: cache = new LRUMap(MAX_SIZE);
1128: return true;
1129: }
1130: } catch (RemoteActionException rae) {
1131: ExceptionDialog.show(rae);
1132: }
1133: return false;
1134: }
1135:
1136: public final static class Lock {
1137: private String path;
1138:
1139: private String owner;
1140:
1141: private String principal;
1142:
1143: private String context;
1144:
1145: private long timestamp;
1146:
1147: private String wfId;
1148:
1149: private boolean shared;
1150:
1151: public Lock(String path, String owner, String principal,
1152: long timestamp, String context, String wfId,
1153: boolean shared) {
1154: this .path = path;
1155: this .owner = owner;
1156: this .principal = principal;
1157: this .timestamp = timestamp;
1158: this .context = context;
1159: this .wfId = wfId;
1160: this .shared = shared;
1161: }
1162:
1163: public String getPath() {
1164: return path;
1165: }
1166:
1167: public String getContext() {
1168: return context;
1169: }
1170:
1171: public void setContext(String context) {
1172: this .context = context;
1173: }
1174:
1175: public void setOwner(String owner) {
1176: this .owner = owner;
1177: }
1178:
1179: public String getOwner() {
1180: return owner;
1181: }
1182:
1183: public void setPrincipal(String principal) {
1184: this .principal = principal;
1185: }
1186:
1187: public String getPrincipal() {
1188: return principal;
1189: }
1190:
1191: public void setTimestamp(long timestamp) {
1192: this .timestamp = timestamp;
1193: }
1194:
1195: public long getTimestamp() {
1196: return timestamp;
1197: }
1198:
1199: public String getWfId() {
1200: return wfId;
1201: }
1202:
1203: public void setWfId(String wfId) {
1204: this .wfId = wfId;
1205: }
1206:
1207: public boolean isShared() {
1208: return shared;
1209: }
1210: }
1211:
1212: private final class ComponentImportHandler implements
1213: SimpleImportHandler {
1214:
1215: private ContelligentComponent rootComponent = null;
1216:
1217: private ContelligentComponent currentComponent = null;
1218:
1219: private Stack<ContelligentComponent> componentStack = new Stack<ContelligentComponent>();
1220:
1221: private Principal currentPrincipal = null;
1222:
1223: private ComponentAccess currentAccess = null;
1224:
1225: private DefaultContelligentCategory currentCategory = null;
1226:
1227: private Map<String, String> categoryMap;
1228:
1229: private ParameterDescription parameterDescription;
1230:
1231: private int mode;
1232:
1233: public ComponentImportHandler(
1234: ContelligentComponent rootComponent, int mode) {
1235: this .rootComponent = rootComponent;
1236: this .mode = mode;
1237: }
1238:
1239: public ContelligentComponent getRootComponent() {
1240: return currentComponent;
1241: }
1242:
1243: public void startDocument() {
1244: }
1245:
1246: public void endDocument() {
1247: }
1248:
1249: public void cData(SimplePath path, String cdata) {
1250: }
1251:
1252: public void startElement(SimplePath path, String name,
1253: AttributesImpl attrs, String leadingCData) {
1254:
1255: try {
1256:
1257: // **** COMPONENT
1258:
1259: if (path.matches("component")) {
1260: if (currentComponent == null
1261: && rootComponent != null) {
1262: currentComponent = rootComponent;
1263: } else {
1264: currentComponent = new ContelligentComponent(
1265: attrs.getValue("name"),
1266: ConversionHelpers.getString(attrs
1267: .getValue("dir"), ""));
1268: }
1269: componentStack.push(currentComponent);
1270: currentComponent
1271: .setTypeName(attrs.getValue("type"));
1272: currentComponent.setBlueprint(Boolean.valueOf(
1273: attrs.getValue("isBlueprint"))
1274: .booleanValue());
1275: currentComponent.setDefinedBlueprintType(attrs
1276: .getValue("definesBlueprintType"));
1277: currentComponent.setModifiedBy(attrs
1278: .getValue("modifiedBy"));
1279: }
1280:
1281: // do not overwrite component when loading subcomponents
1282: if (mode == LOAD_SUBCOMPONENTS
1283: && currentComponent != null
1284: && currentComponent == rootComponent)
1285: return;
1286:
1287: // **** META-INFO
1288:
1289: if (path.matches("component/meta-info")) {
1290:
1291: currentComponent.setComposedBlueprint(attrs
1292: .getValue("composedBlueprint"));
1293: currentComponent.setFinal(Boolean.valueOf(
1294: attrs.getValue("isFinal")).booleanValue());
1295: currentComponent.setLastModified(ConversionHelpers
1296: .getLong(attrs.getValue("lastModified")));
1297: currentComponent.setHasSubcomponents(Boolean
1298: .valueOf(attrs.getValue("hasChildren"))
1299: .booleanValue());
1300: currentComponent.setPublisherType("");
1301: currentComponent.setPublisherName("");
1302: } else if (path.matches("component/noreadpermission")) {
1303: currentComponent.setReadPermission(false);
1304: } else if (path.matches("component/meta-info/security")) {
1305: currentComponent
1306: .setDefinesSecureTransfer(Boolean
1307: .valueOf(
1308: attrs
1309: .getValue("definesSecureTransfer"))
1310: .booleanValue());
1311: currentComponent
1312: .setNeedsSecureTransfer(Boolean
1313: .valueOf(
1314: attrs
1315: .getValue("needsSecureTransfer"))
1316: .booleanValue());
1317:
1318: } else if (path
1319: .matches("component/meta-info/security/owner")) {
1320: currentPrincipal = new Principal(attrs
1321: .getValue("principalGroupId"), attrs
1322: .getValue("principalId"));
1323: currentComponent.addOwner(currentPrincipal);
1324:
1325: } else if (path
1326: .matches("component/meta-info/security/access")) {
1327: currentAccess = new ComponentAccess(new Principal(
1328: attrs.getValue("principalGroupId"), attrs
1329: .getValue("principalId")), attrs
1330: .getValue("accessType"), attrs
1331: .getValue("mode"), attrs
1332: .getValue("parentMode"), Long
1333: .parseLong(attrs.getValue("validFrom")),
1334: Long.parseLong(attrs.getValue("validTo")),
1335: Long.parseLong(attrs.getValue("period")),
1336: Long.parseLong(attrs.getValue("duration")));
1337: currentComponent.addAclEntry(currentAccess);
1338:
1339: } else if (path
1340: .matches("component/meta-info/publisher/basic")) {
1341: // Do not verify the information client side; we trust the
1342: // server here.
1343: currentComponent.setPublisherType("basic");
1344: currentComponent.setPublisherName(attrs
1345: .getValue("name"));
1346:
1347: // **** PROPERTIES
1348:
1349: } else if (path
1350: .matches("component/meta-info/publisher/user")) {
1351:
1352: currentComponent.setPublisherType("user");
1353: currentComponent.setPublisherName(attrs
1354: .getValue("name"));
1355:
1356: } else if (path.matches("component/component-property")) {
1357: String propertyName = attrs.getValue("name");
1358: Type type = currentComponent.getType();
1359: TypeProperty typeProperty = null;
1360: if (type == null) {
1361: logger
1362: .log(
1363: Level.WARNING,
1364: "Can not load properties from type, because type is null! ContelligentComponent: ["
1365: + currentComponent
1366: .getPath()
1367: + "]");
1368: } else {
1369: try {
1370: typeProperty = type
1371: .getProperty(propertyName);
1372: } catch (TypePropertyNotFoundException e) {
1373: // * should never be called, only in case of wrong
1374: // system configuration *
1375: logger.log(Level.WARNING,
1376: "Trying to add property '" + name
1377: + "' not defined in type",
1378: e);
1379: }
1380: }
1381: ComponentProperty property = new ComponentProperty(
1382: currentComponent, propertyName,
1383: leadingCData, typeProperty);
1384: currentComponent.addProperty(property);
1385:
1386: // **** METADATA
1387: } else if (path.matches("component/metadata/key")) {
1388: String key = leadingCData;
1389: List<String> l = currentComponent.getMetadataKeys();
1390: l.add(key);
1391: currentComponent.setMetadataKeys(l);
1392: } else if (path.matches("component/metadata/value")) {
1393: String value = leadingCData;
1394: List<String> l = currentComponent
1395: .getMetadataValues();
1396: l.add(value);
1397: currentComponent.setMetadataValues(l);
1398:
1399: // **** SENSITIVE CATEGORY
1400: } else if (path.matches("sensitive-category")) {
1401: currentCategory = new DefaultContelligentCategory(
1402: attrs.getValue("name"));
1403: currentCategory.setSupportedValuesList(attrs
1404: .getValue("supportedValues"));
1405: if (path
1406: .matches("component/content/sensitive-category")) {
1407: currentComponent
1408: .addContentCategory(currentCategory);
1409: } else if (path
1410: .matches("component/renderer/sensitive-category")) {
1411: currentComponent
1412: .addTemplateCategory(currentCategory);
1413: } else {
1414: logger.log(Level.WARNING,
1415: "Unexpected context for category: neither content nor template! Path: "
1416: + path.toString());
1417: }
1418:
1419: // **** CONTENT
1420: } else if (path.matches("component/content")) {
1421: currentComponent.hasContent(true);
1422:
1423: } else if (path.matches("content/resource")) {
1424: categoryMap = new HashMap<String, String>();
1425:
1426: } else if (path
1427: .matches("content/resource/supported-category")) {
1428: if (categoryMap != null) {
1429: categoryMap.put(attrs.getValue("name"), attrs
1430: .getValue("value"));
1431: }
1432:
1433: } else if (path.matches("content/resource/text")) {
1434: ContelligentTextResource resource = new ContelligentTextResource(
1435: categoryMap, leadingCData);
1436: currentComponent.setResource(resource);
1437:
1438: } else if (path.matches("content/resource/binary")) {
1439: String source = attrs.getValue("src");
1440: String contentType = attrs.getValue("contentType");
1441: String extension = attrs.getValue("extension");
1442: ContelligentBinaryResource resource = new ContelligentBinaryResource(
1443: categoryMap, source, contentType, extension);
1444: currentComponent.setResource(resource);
1445:
1446: } else if (path.matches("content/resource/string")) {
1447: String constraints = attrs.getValue("constraints");
1448: ContelligentStringResource resource = new ContelligentStringResource(
1449: categoryMap, leadingCData, constraints);
1450: currentComponent.setResource(resource);
1451:
1452: } else if (path.matches("content/resource/number")) {
1453: String constraints = attrs.getValue("constraints");
1454: ContelligentNumberResource resource = new ContelligentNumberResource(
1455: categoryMap, new BigDecimal(leadingCData),
1456: constraints);
1457: currentComponent.setResource(resource);
1458:
1459: } else if (path.matches("content/resource/boolean")) {
1460: boolean value = Boolean.valueOf(
1461: attrs.getValue("value")).booleanValue();
1462: ContelligentBooleanResource resource = new ContelligentBooleanResource(
1463: categoryMap, value);
1464: currentComponent.setResource(resource);
1465:
1466: // **** RENDERER
1467: } else if (path.matches("renderer")) {
1468: currentComponent
1469: .setRenderer(attrs.getValue("type"));
1470: } else if (path
1471: .matches("renderer/parameter-description")) {
1472: parameterDescription = new ParameterDescription(
1473: attrs.getValue("name"), attrs
1474: .getValue("description"),
1475: Boolean.valueOf(attrs.getValue("required"))
1476: .booleanValue());
1477: currentComponent
1478: .addParameterDescription(parameterDescription);
1479:
1480: } else if (path
1481: .matches("renderer/parameter-description/allowed-value")) {
1482: parameterDescription.setConstrained(true);
1483: parameterDescription.addAllowedValue(leadingCData);
1484:
1485: } else if (path.matches("renderer/resource")) {
1486: categoryMap = new HashMap<String, String>();
1487:
1488: } else if (path
1489: .matches("renderer/resource/supported-category")) {
1490: if (categoryMap != null) {
1491: categoryMap.put(attrs.getValue("name"), attrs
1492: .getValue("value"));
1493: }
1494:
1495: } else if (path.matches("renderer/resource/text")) {
1496: ContelligentTextResource resource = new ContelligentTextResource(
1497: categoryMap, (leadingCData == null ? ""
1498: : leadingCData));
1499: currentComponent.setTemplate(resource);
1500:
1501: }
1502: } catch (Throwable t) {
1503: logger.log(Level.SEVERE,
1504: "Caught exception while component import", t);
1505: }
1506: }
1507:
1508: public void endElement(SimplePath path, String name) {
1509: try {
1510:
1511: if (currentComponent != null)
1512: currentComponent.init();
1513:
1514: // do not overwrite component when loading subcomponents
1515: if (mode == LOAD_SUBCOMPONENTS
1516: && currentComponent != null
1517: && currentComponent == rootComponent)
1518: return;
1519:
1520: if (path.matches("component")) {
1521:
1522: ContelligentComponent subComponent = currentComponent;
1523: ContelligentComponent parentComponent = null;
1524:
1525: if (!componentStack.empty())
1526: componentStack.pop();
1527: if (!componentStack.empty()) {
1528: parentComponent = (ContelligentComponent) componentStack
1529: .peek();
1530: if (parentComponent != null) {
1531: // add the name of this subcomponent to its parent
1532: parentComponent
1533: .addSubcomponent(subComponent
1534: .getName());
1535: parentComponent
1536: .setSubcomponentsLoaded(true);
1537: currentComponent = parentComponent;
1538: }
1539: }
1540:
1541: if (parentComponent != null) {
1542: String parentPath = parentComponent.getPath();
1543: subComponent.setDir(parentPath + "/");
1544: }
1545:
1546: // check if this component already is in component cache...
1547: if (!cache.containsKey(subComponent.getPath())) {
1548: // ...and put it into cache
1549: cache.put(subComponent.getPath(), subComponent);
1550: }
1551: }
1552: } catch (Throwable t) {
1553: logger.log(Level.SEVERE,
1554: "Caught exception while component import", t);
1555: }
1556: }
1557: }
1558:
1559: }
|