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.util.bookmark;
0019:
0020: import java.io.IOException;
0021: import java.io.StringReader;
0022: import java.util.ArrayList;
0023: import java.util.Collection;
0024: import java.util.Collections;
0025: import java.util.Iterator;
0026: import java.util.List;
0027: import java.util.logging.Level;
0028: import java.util.logging.Logger;
0029:
0030: import javax.swing.Action;
0031: import javax.xml.parsers.DocumentBuilder;
0032: import javax.xml.parsers.DocumentBuilderFactory;
0033: import javax.xml.parsers.ParserConfigurationException;
0034:
0035: import org.w3c.dom.Document;
0036: import org.w3c.dom.Element;
0037: import org.w3c.dom.NamedNodeMap;
0038: import org.w3c.dom.Node;
0039: import org.w3c.dom.NodeList;
0040: import org.xml.sax.InputSource;
0041: import org.xml.sax.SAXException;
0042:
0043: import de.finix.contelligent.client.base.ComponentFactory;
0044: import de.finix.contelligent.client.base.ComponentNotFoundException;
0045: import de.finix.contelligent.client.base.ComponentPath;
0046: import de.finix.contelligent.client.base.ContelligentComponent;
0047: import de.finix.contelligent.client.base.Session;
0048: import de.finix.contelligent.client.base.resource.ContelligentTextResource;
0049: import de.finix.contelligent.client.event.ComponentEventListener;
0050: import de.finix.contelligent.client.event.ContelligentComponentEvent;
0051: import de.finix.contelligent.client.gui.ContelligentAction;
0052: import de.finix.contelligent.client.gui.explorer.BookmarkFolderAction;
0053: import de.finix.contelligent.client.gui.explorer.ExplorerEditor;
0054: import de.finix.contelligent.client.gui.explorer.GoToBookmarkAction;
0055: import de.finix.contelligent.client.remote.Actions;
0056: import de.finix.contelligent.client.remote.RemoteActionException;
0057: import de.finix.contelligent.client.util.xml.XMLUtil;
0058:
0059: public class BookmarkManager implements ComponentEventListener {
0060:
0061: static Logger log = Logger.getLogger(BookmarkManager.class
0062: .getName());
0063:
0064: /**
0065: * Holds BookmarkManager instance.
0066: */
0067: private static BookmarkManager instance = null; // to realize the singleton pattern
0068:
0069: private Document bookmarksTree = null;
0070:
0071: // shows, if the tree was loaded and checked for missing <type> nodes
0072: private boolean bookmarksTreeLoaded = false;
0073:
0074: /**
0075: *
0076: */
0077: private BookmarkManager() {
0078:
0079: this .bookmarksTree = loadBookmarks();
0080:
0081: // add listener
0082: ComponentFactory.getInstance().addComponentEventListener(this ,
0083: false);
0084: }
0085:
0086: /**
0087: * Returns the BookmarkManager instance.
0088: *
0089: * @return The BookmarkManager instance.
0090: */
0091: public static BookmarkManager getInstance() {
0092:
0093: if (instance == null) {
0094: instance = new BookmarkManager();
0095: }
0096: return instance;
0097: }
0098:
0099: /**
0100: *
0101: *
0102: * @return
0103: */
0104: public Document getBookmarks() {
0105: return this .bookmarksTree;
0106: }
0107:
0108: /**
0109: * If node is a node that represents a bookmark or a bookmarkFolder, this method returns the id of the specified node.
0110: *
0111: * @param node
0112: *
0113: * @return the id of the specified node. -1 if node is null, was not a bookmark or a bookmarkFolder node.
0114: */
0115: public int getId(Node node) {
0116:
0117: if (node == null) {
0118: return -1;
0119: }
0120:
0121: // because we have a different usage of id's in <folder>s and <bookmark>s we have to implement 2 different ways of detecting an id by a node.
0122:
0123: if ("folder".equals(node.getNodeName())) {
0124: // find the id of a bookmarkFolder and return the id.
0125:
0126: NamedNodeMap folderAttributes = node.getAttributes();
0127:
0128: for (int j = 0; j < folderAttributes.getLength(); j++) {
0129:
0130: Node folderAttribute = folderAttributes.item(j);
0131:
0132: if ("id".equals(folderAttribute.getNodeName())) {
0133: return Integer.parseInt(folderAttribute
0134: .getTextContent());
0135: }
0136: }
0137: }
0138:
0139: if ("bookmark".equals(node.getNodeName())) {
0140: // if no folder id was found look for a bookmark id.
0141: // find the id of a bookmark node and return the associated id.
0142:
0143: NodeList idNodes = node.getChildNodes();//("id");
0144:
0145: for (int i = 0; i < idNodes.getLength(); i++) {
0146: Node idNode = idNodes.item(i);
0147:
0148: if ("id".equals(idNode.getNodeName())) {
0149: return Integer.parseInt(idNode.getTextContent());
0150: }
0151: }
0152: }
0153:
0154: return -1;
0155: }
0156:
0157: /**
0158: * Returns the node with the specified id.
0159: *
0160: * @param id
0161: * id of node to return.
0162: *
0163: * @return the node with the specified id or null.
0164: */
0165: public Node getNode(int id) {
0166:
0167: // because we have a different usage of id's in <folder>s and <bookmark>s we have to implement 2 different ways of detecting a node by an id.
0168: // find the attribut of a folder that has the desired id and return the folder.
0169: Node node = getBookmarkFolderNode(id);
0170:
0171: if (node == null) {
0172: // if no folder which the specified id was found look for a bookmark with that id.
0173: // find the node of a bookmark that has desired id and return the associated bookmark.
0174: node = getBookmarkNode(id);
0175: }
0176:
0177: return node;
0178: }
0179:
0180: /**
0181: * Returns the bookmarkFolder with the specified id.
0182: *
0183: * @param id
0184: * id of bookmarkFolder to return.
0185: *
0186: * @return the bookmarkFolder with the specified id or null.
0187: */
0188: public Node getBookmarkFolderNode(int id) {
0189:
0190: String idString = Integer.toString(id);
0191:
0192: Element descriptions = bookmarksTree.getDocumentElement();
0193:
0194: // get a Collection of <folder> nodes
0195: NodeList folderNodes = descriptions
0196: .getElementsByTagName("folder");
0197:
0198: for (int i = 0; i < folderNodes.getLength(); i++) {
0199: Node folderNode = folderNodes.item(i);
0200:
0201: NamedNodeMap folderAttributes = folderNode.getAttributes();
0202:
0203: for (int j = 0; j < folderAttributes.getLength(); j++) {
0204:
0205: Node folderAttribute = folderAttributes.item(j);
0206:
0207: if ("id".equals(folderAttribute.getNodeName())
0208: && idString.equals(folderAttribute
0209: .getTextContent())) {
0210: return folderNode;
0211: }
0212: }
0213: }
0214: return null;
0215: }
0216:
0217: /**
0218: * Returns the bookmark with the specified id.
0219: *
0220: * @param id
0221: * id of bookmark to return.
0222: *
0223: * @return the bookmark with the specified id or null.
0224: */
0225: public Node getBookmarkNode(int id) {
0226:
0227: String idString = Integer.toString(id);
0228:
0229: Element descriptions = bookmarksTree.getDocumentElement();
0230:
0231: // get a Collection of <id> nodes
0232: NodeList idNodes = descriptions.getElementsByTagName("id");
0233:
0234: for (int i = 0; i < idNodes.getLength(); i++) {
0235: Node idNode = idNodes.item(i);
0236:
0237: if (idString.equals(idNode.getTextContent())) {
0238: return idNode.getParentNode();
0239: }
0240: }
0241: return null;
0242: }
0243:
0244: /**
0245: * Returns the bookmarkFolder with the specified id.
0246: *
0247: * @param id
0248: * id of bookmarkFolder to return.
0249: *
0250: * @return the bookmarkFolder with the specified id.
0251: */
0252: public BookmarkFolder getBookmarkFolder(int id) {
0253:
0254: Node node = getBookmarkFolderNode(id);
0255:
0256: return BookmarkUtil
0257: .convertBookmarkFolderDomNodeToBookmarkFolder(node);
0258: }
0259:
0260: /**
0261: * Returns the bookmark with the specified id.
0262: *
0263: * @param id
0264: * id of bookmark to return.
0265: *
0266: * @return the bookmark with the specified id.
0267: */
0268: public Bookmark getBookmark(int id) {
0269:
0270: Node node = getBookmarkNode(id);
0271:
0272: return BookmarkUtil.convertBookmarkDomNodeToBookmark(node);
0273: }
0274:
0275: /**
0276: * Adds bookmark below root node.
0277: *
0278: * @param bookmark
0279: *
0280: * @return
0281: */
0282: public Node add(BookmarkFolder bookmarkFolder) {
0283:
0284: return add(bookmarkFolder, null);
0285: }
0286:
0287: /**
0288: * Adds bookmark folder below a node.
0289: *
0290: * @param bookmark
0291: *
0292: * @return
0293: */
0294: public Node add(BookmarkFolder bookmarkFolder, Node parent) {
0295:
0296: return add(bookmarkFolder, getId(parent));
0297: }
0298:
0299: /**
0300: * Adds bookmark folder below a node.
0301: *
0302: * @param bookmark
0303: *
0304: * @return
0305: */
0306: public Node add(BookmarkFolder bookmarkFolder, int parentNodeId) {
0307:
0308: Node parentNode = null;
0309: Node newNode = null;
0310:
0311: // if < 0, node does not exists. use root instead.
0312: if (parentNodeId < 0) {
0313: // parent = root node
0314: parentNode = bookmarksTree.getDocumentElement();
0315: newNode = parentNode.appendChild(BookmarkUtil
0316: .convertBookmarkFolderToBookmarkFolderDomNode(
0317: bookmarkFolder, bookmarksTree));
0318: } else {
0319: parentNode = getBookmarkFolderNode(parentNodeId);
0320:
0321: if (parentNode == null) {
0322: return null;
0323: }
0324: newNode = parentNode.appendChild(BookmarkUtil
0325: .convertBookmarkFolderToBookmarkFolderDomNode(
0326: bookmarkFolder, bookmarksTree));
0327: }
0328:
0329: // sort child nodes
0330: sort(parentNode);
0331:
0332: saveBookmarks();
0333:
0334: return newNode;
0335: }
0336:
0337: /**
0338: * Adds bookmark below root node.
0339: *
0340: * @param bookmark
0341: *
0342: * @return
0343: */
0344: public Node add(Bookmark bookmark) {
0345:
0346: return add(bookmark, null);
0347: }
0348:
0349: /**
0350: * Adds bookmark below a node.
0351: *
0352: * @param bookmark
0353: *
0354: * @return
0355: */
0356: public Node add(Bookmark bookmark, Node parent) {
0357: return add(bookmark, getId(parent));
0358: }
0359:
0360: /**
0361: * Adds bookmark below a node.
0362: *
0363: * @param bookmark
0364: *
0365: * @param parentNodeId
0366: *
0367: * @return added node.
0368: */
0369: public Node add(Bookmark bookmark, int parentNodeId) {
0370:
0371: Node parentNode = null;
0372: Node newNode = null;
0373:
0374: // if < 0, node does not exists. use root instead.
0375: if (parentNodeId < 0) {
0376: // parent = root node
0377: parentNode = bookmarksTree.getDocumentElement();
0378: } else {
0379: parentNode = getNode(parentNodeId);
0380: }
0381: newNode = parentNode.appendChild(BookmarkUtil
0382: .convertBookmarkToBookmarkDomNode(bookmark,
0383: bookmarksTree));
0384:
0385: // sort nodes of a level
0386: // convert from node to bookmarkfolder or bookmark
0387: NodeList children = parentNode.getChildNodes();
0388:
0389: if (children.getLength() == 0) {
0390:
0391: } else {
0392:
0393: ArrayList list = new ArrayList(children.getLength());
0394: //ArrayList<BookmarkFolder> list = new ArrayList<BookmarkFolder>(children.getLength());
0395:
0396: for (int i = 0; i < children.getLength(); i++) {
0397: Node node = children.item(i);
0398:
0399: if ("bookmark".equals(node.getNodeName())) {
0400: list.add(BookmarkUtil
0401: .convertBookmarkDomNodeToBookmark(node));
0402: } else {
0403: if ("folder".equals(node.getNodeName())) {
0404: list
0405: .add(BookmarkUtil
0406: .convertBookmarkFolderDomNodeToBookmarkFolder(node));
0407: }
0408: }
0409: }
0410: Collections.sort(list);
0411:
0412: // convert from bookmarkfolder or bookmark to node
0413: for (Iterator iter = list.iterator(); iter.hasNext();) {
0414: BookmarkFolder element = (BookmarkFolder) iter.next();
0415:
0416: Node sortedNode = getNode(element.getId());
0417:
0418: Node node = parentNode.removeChild(sortedNode);
0419:
0420: parentNode.appendChild(node);
0421: }
0422: }
0423: saveBookmarks();
0424:
0425: return newNode;
0426: }
0427:
0428: /**
0429: *
0430: *
0431: * @param node The node to remove.
0432: *
0433: * @return removed node.
0434: */
0435: public Node remove(Node node) {
0436:
0437: // TODO warum hier nicht gleich den node löschen? spart das ermittlen der id.
0438:
0439: return remove(getId(node));
0440: }
0441:
0442: /**
0443: * Removes the node with the specified id.
0444: *
0445: * @param id The node id.
0446: *
0447: * @return removed node.
0448: */
0449: public Node remove(int id) {
0450:
0451: Node node = getNode(id);
0452:
0453: if (node != null) {
0454: Node removed = node.getParentNode().removeChild(node);
0455:
0456: saveBookmarks();
0457:
0458: return removed;
0459: }
0460:
0461: return null;
0462: }
0463:
0464: /**
0465: *
0466: *
0467: * @param bookmark
0468: *
0469: * @return
0470: */
0471: public Node remove(BookmarkFolder bookmarkFolder) {
0472:
0473: return remove(bookmarkFolder.getId());
0474: }
0475:
0476: /**
0477: *
0478: *
0479: * @param bookmark
0480: *
0481: * @return
0482: */
0483: public Node remove(Bookmark bookmark) {
0484:
0485: return remove(bookmark.getId());
0486: }
0487:
0488: /**
0489: *
0490: *
0491: * @param bookmarks
0492: *
0493: * @return
0494: */
0495: public void removeAll(Collection<BookmarkFolder> bookmarks) {
0496:
0497: for (Iterator iter = bookmarks.iterator(); iter.hasNext();) {
0498:
0499: BookmarkFolder bookmarkFolder = (BookmarkFolder) iter
0500: .next();
0501: remove(bookmarkFolder);
0502: }
0503: }
0504:
0505: // TODO die folgenden 4 insertBefore() methoden lieber löschen?!
0506: /**
0507: * Inserts the node <code>newChild</code> before the existing child node
0508: * <code>refChild</code>. If <code>refChild</code> is <code>null</code>,
0509: * insert <code>newChild</code> at the end of the list of children.
0510: * <br>If <code>newChild</code> is a <code>DocumentFragment</code> object,
0511: * all of its children are inserted, in the same order, before
0512: * <code>refChild</code>. If the <code>newChild</code> is already in the
0513: * tree, it is first removed.
0514: *
0515: * <p ><b>Note:</b> Inserting a node before itself is implementation
0516: * dependent.
0517: *
0518: * @param newChild The node to insert.
0519: * @param refChild The reference node, i.e., the node before which the
0520: * new node must be inserted.
0521: *
0522: * @return The node being inserted.
0523: */
0524: public Node insertBefore(Node newChild, Node refChild) {
0525:
0526: Node node = bookmarksTree.insertBefore(newChild, refChild);
0527: saveBookmarks();
0528:
0529: return node;
0530: }
0531:
0532: /**
0533: * Inserts the node which has the id <code>newChildId</code> before the existing child node
0534: * with <code>refChildId</code>. If <code>refChild</code> is <code>null</code>,
0535: * insert <code>newChild</code> at the end of the list of children.
0536: * <br>If <code>newChild</code> is a <code>DocumentFragment</code> object,
0537: * all of its children are inserted, in the same order, before
0538: * <code>refChild</code>. If the <code>newChild</code> is already in the
0539: * tree, it is first removed.
0540: *
0541: * <p ><b>Note:</b> Inserting a node before itself is implementation
0542: * dependent.
0543: *
0544: * @param newChild The node to insert.
0545: * @param refChild The reference node, i.e., the node before which the
0546: * new node must be inserted.
0547: *
0548: * @return The node being inserted.
0549: */
0550: public Node insertBefore(int newChildId, int refChildId) {
0551:
0552: Node newChild = getNode(newChildId);
0553: Node refChild = null;
0554: if (refChildId >= 0) {
0555:
0556: // TODO
0557:
0558: refChild = getNode(refChildId);
0559: }
0560:
0561: return this .insertBefore(newChild, refChild);
0562: }
0563:
0564: /**
0565: * @param bookmark
0566: * @param refChildId
0567: * @return
0568: */
0569: public Node insertBefore(Bookmark bookmark, int refChildId) {
0570:
0571: Node newChild = getBookmarkNode(bookmark.getId());
0572: Node refChild = null;
0573: if (refChildId >= 0) {
0574:
0575: // TODO
0576:
0577: refChild = getNode(refChildId);
0578: }
0579:
0580: return this .insertBefore(newChild, refChild);
0581: }
0582:
0583: /**
0584: * @param bookmarkFolder
0585: * @param refChildId
0586: * @return
0587: */
0588: public Node insertBefore(BookmarkFolder bookmarkFolder,
0589: int refChildId) {
0590:
0591: Node newChild = getBookmarkFolderNode(bookmarkFolder.getId());
0592:
0593: // if (newChild == null) {
0594: // System.out.println("newChild ist null");
0595: // }
0596:
0597: Node refChild = null;
0598: if (refChildId >= 0) {
0599:
0600: // TODO
0601:
0602: refChild = getNode(refChildId);
0603:
0604: // if (refChild == null) {
0605: // System.out.println("refChild ist null");
0606: // }
0607: }
0608: //refChild.get
0609:
0610: // HIERARCHY_REQUEST_ERR: An attempt was made to insert a node where it is not permitted.
0611:
0612: return this .insertBefore(newChild, refChild);
0613: }
0614:
0615: /**
0616: *
0617: *
0618: * @param newBookmarkFolder
0619: *
0620: * @param oldBookmarkFolder
0621: */
0622: public void replace(BookmarkFolder newBookmarkFolder,
0623: BookmarkFolder oldBookmarkFolder) {
0624:
0625: Node bookmarkFolderOldNode = getBookmarkFolderNode(oldBookmarkFolder
0626: .getId());
0627:
0628: if (bookmarkFolderOldNode != null) {
0629:
0630: Node parent = bookmarkFolderOldNode.getParentNode();
0631:
0632: if (parent != null) {
0633:
0634: Node removed = remove(oldBookmarkFolder);
0635: Node bookmarkFolderNewNode = add(newBookmarkFolder,
0636: getId(parent));
0637:
0638: // Move all the children to new node
0639: while (removed.hasChildNodes()) {
0640: bookmarkFolderNewNode.appendChild(removed
0641: .getFirstChild());
0642: }
0643:
0644: saveBookmarks();
0645: }
0646: }
0647: }
0648:
0649: /**
0650: *
0651: *
0652: * @param newBookmark
0653: *
0654: * @param oldBookmark
0655: */
0656: public void replace(Bookmark newBookmark, Bookmark oldBookmark) {
0657:
0658: Node bookmarkOldNode = getBookmarkNode(oldBookmark.getId());
0659: Node parent = bookmarkOldNode.getParentNode();
0660:
0661: if (parent != null) {
0662: remove(oldBookmark);
0663: add(newBookmark, getId(parent));
0664: saveBookmarks();
0665: }
0666: }
0667:
0668: /**
0669: * Moves a node below a new parent node.
0670: *
0671: * @param node
0672: *
0673: * @param newParent
0674: */
0675: // public void move(Node node, Node newParent) {
0676: //
0677: // System.out.println("**** MOVE() mthode macht nichts sinnvolles!!!! ****");
0678: //
0679: // Node tmpNode = remove(node);
0680: //
0681: // add(tmpNode, newParent);
0682: //
0683: // // // newParent.appendChild(node);
0684: // //
0685: // // // saveBookmarks(); // da add schon saved
0686: // }
0687: /**
0688: * Moves a bookmark below a new parent node.
0689: *
0690: * @param bookmark
0691: *
0692: * @param newParent
0693: */
0694: public void move(Bookmark bookmark, Node newParent) {
0695:
0696: remove(getBookmarkNode(bookmark.getId()));
0697: add(bookmark, newParent);
0698: }
0699:
0700: /**
0701: * Moves a bookmarkFolder below a new parent node.
0702: *
0703: * @param bookmarkFolder
0704: *
0705: * @param newParent
0706: */
0707: public void move(BookmarkFolder bookmarkFolder, Node newParent) {
0708:
0709: if (newParent == null) {
0710: // if null, than newParent = root node
0711: newParent = bookmarksTree.getOwnerDocument()
0712: .getDocumentElement();
0713: }
0714:
0715: // Move all the children to new node
0716: Node bookmarkFolderNode = getBookmarkFolderNode(bookmarkFolder
0717: .getId());
0718: newParent.appendChild(bookmarkFolderNode);
0719:
0720: // sort child nodes
0721: sort(newParent);
0722:
0723: saveBookmarks();
0724: }
0725:
0726: /**
0727: * Sorts the nodes below parent node. Sort key: BookmarkFolders first then Bookmarks; Alphabetically.
0728: *
0729: * @param parentNode Node whose children will be sorted.
0730: */
0731: public void sort(Node parentNode) {
0732:
0733: // sort nodes of a level
0734: // convert from node to bookmarkfolder or bookmark
0735: NodeList children = parentNode.getChildNodes();
0736: int childCount = children.getLength();
0737:
0738: if (childCount > 0) {
0739: ArrayList list = new ArrayList(childCount);
0740: // ArrayList<BookmarkFolder> list = new ArrayList<BookmarkFolder>(childCount);
0741:
0742: for (int i = 0; i < childCount; i++) {
0743: Node node = children.item(i);
0744:
0745: if ("bookmark".equals(node.getNodeName())) {
0746: list.add(BookmarkUtil
0747: .convertBookmarkDomNodeToBookmark(node));
0748: } else {
0749: if ("folder".equals(node.getNodeName())) {
0750: list
0751: .add(BookmarkUtil
0752: .convertBookmarkFolderDomNodeToBookmarkFolder(node));
0753: }
0754: }
0755: }
0756: Collections.sort(list);
0757:
0758: // convert from bookmarkfolder or bookmark to node
0759: for (Iterator iter = list.iterator(); iter.hasNext();) {
0760: BookmarkFolder element = (BookmarkFolder) iter.next();
0761: Node sortedNode = getNode(element.getId());
0762: Node node = parentNode.removeChild(sortedNode);
0763: parentNode.appendChild(node);
0764: }
0765: }
0766: }
0767:
0768: /**
0769: *
0770: *
0771: * @return
0772: */
0773: public Document loadBookmarks() {
0774:
0775: // call server sided action that delivers the xml content of the bookmark component, which is below the user
0776: // home directory
0777:
0778: // get user bookmark component
0779: String groupID = Session.getInstance().getUser().getPrincipal()
0780: .getGroupId();
0781: String iD = Session.getInstance().getUser().getPrincipal()
0782: .getId();
0783:
0784: ContelligentComponent component = null;
0785: String userBookmarkPath = "/contelligent/home/" + groupID + "/"
0786: + iD + "/bookmarks";
0787:
0788: // unmarshalling xml datastructures (xml to bookmark objects)
0789: DocumentBuilderFactory factory = DocumentBuilderFactory
0790: .newInstance();
0791: factory.setNamespaceAware(true);
0792: Document xmlDocument = null;
0793: DocumentBuilder builder;
0794:
0795: try {
0796: // reading bookmark component out of the client cache!
0797: component = ComponentFactory.getInstance().getComponent(
0798: userBookmarkPath);
0799:
0800: } catch (ComponentNotFoundException e1) {
0801: log.warning("Bookmark component (" + userBookmarkPath
0802: + ") not found. Creating a new one.");
0803:
0804: // if bookmark component doesn't exist, we create a new one
0805: try {
0806: builder = factory.newDocumentBuilder();
0807: } catch (ParserConfigurationException e) {
0808: log.warning("Parser is not configured well.");
0809:
0810: return null;
0811: }
0812: xmlDocument = builder.newDocument();
0813:
0814: // add root node
0815: Node root = xmlDocument.createElement("bookmarks");
0816: xmlDocument.appendChild(root);
0817:
0818: if (this != null) {
0819: this .bookmarksTree = xmlDocument;
0820: }
0821:
0822: saveBookmarks();
0823:
0824: return xmlDocument;
0825: }
0826:
0827: ContelligentTextResource contelligentTextResource = (ContelligentTextResource) component
0828: .getResource("");
0829: String xml = contelligentTextResource.getText();
0830:
0831: // TODO was, wenn mehrere kategorien einer kompo existieren?
0832: // kann passieren, wenn z.B. admin an bookmark kompo rumgefummelt hat
0833: // log.info("---- getContentCategories().size: " + component.getContentCategories().size());
0834:
0835: try {
0836: builder = factory.newDocumentBuilder();
0837:
0838: xmlDocument = builder.parse(new InputSource(
0839: new StringReader(xml)));
0840: } catch (ParserConfigurationException e) {
0841: log.warning("Parser is not configured well.");
0842:
0843: // TODO
0844: return null;
0845:
0846: } catch (SAXException e) {
0847: log.severe("XML content of bookmark component ("
0848: + userBookmarkPath + ") is malformed.");
0849:
0850: // TODO
0851: return null;
0852:
0853: } catch (IOException e) {
0854: log.severe("Could not read bookmark component.");
0855:
0856: // TODO
0857: return null;
0858: }
0859:
0860: // because 'old' bookmarks (Contelligent < 9.1.11) does not have a <type> node, we have to check if <type> nodes already exists:
0861:
0862: // flag that indicates if there were changes. if true we will save the document.
0863: boolean bookmarksTreeUpdated = false;
0864:
0865: // check if <type> nodes exist, should be only done at init time. otherwise it might cost to much performance.
0866: if (bookmarksTreeLoaded == false) {
0867:
0868: NodeList bookmarks = xmlDocument
0869: .getElementsByTagName("bookmark");
0870:
0871: for (int i = 0; i < bookmarks.getLength(); i++) {
0872: Node bookmarkNode = bookmarks.item(i);
0873: NodeList childNodes = bookmarkNode.getChildNodes();
0874:
0875: String componentPath = null;
0876: String type = null;
0877:
0878: for (int j = 0; j < childNodes.getLength(); j++) {
0879: Node childNode = childNodes.item(j);
0880:
0881: if ("componentPath".equals(childNode.getNodeName())) {
0882: componentPath = childNode.getTextContent();
0883: }
0884:
0885: if ("type".equals(childNode.getNodeName())) {
0886: type = childNode.getTextContent();
0887: }
0888: }
0889:
0890: // if <type> node does not exit, create it
0891: if (type == null || type.length() < 1) {
0892: try {
0893: type = ComponentFactory.getInstance()
0894: .getComponent(componentPath)
0895: .getTypeName();
0896:
0897: Node typeNode = bookmarkNode
0898: .appendChild(xmlDocument
0899: .createElement("type"));
0900: typeNode.appendChild(xmlDocument
0901: .createTextNode(type));
0902:
0903: bookmarksTreeUpdated = true;
0904:
0905: } catch (ComponentNotFoundException e) {
0906: log
0907: .log(
0908: Level.WARNING,
0909: "Could not get component '"
0910: + componentPath
0911: + "' to determine its component type.");
0912: }
0913: }
0914: }
0915:
0916: bookmarksTreeLoaded = true;
0917: }
0918:
0919: if (this != null) {
0920: this .bookmarksTree = xmlDocument;
0921: }
0922:
0923: if (bookmarksTreeUpdated) {
0924: saveBookmarks();
0925: }
0926:
0927: return xmlDocument;
0928: }
0929:
0930: /**
0931: * Persist bookmarks in a component named "bookmarks" below the user home directory.
0932: *
0933: * @return
0934: */
0935: protected boolean saveBookmarks() {
0936:
0937: this .bookmarksTree.normalizeDocument(); // TODO drinne lassen?
0938: String stringContent = XMLUtil
0939: .documentToString(this .bookmarksTree);
0940:
0941: // call server sided action that saves the xml representation of the bookmarks, in the bookmark component which
0942: // is below the user home directory
0943: try {
0944: Actions.createUserContent(stringContent, "bookmarks");
0945: } catch (RemoteActionException e1) {
0946: log.severe("Could not perform remote action.");
0947:
0948: return false;
0949: }
0950: return true;
0951: }
0952:
0953: /**
0954: * @return
0955: */
0956: public List<Action> getBookmarksAsActionList(ExplorerEditor editor) {
0957:
0958: List<Action> actions = new ArrayList<Action>();
0959:
0960: Element descriptions = this .bookmarksTree.getDocumentElement();
0961: descriptions.normalize();
0962:
0963: visitChildNodesAndBuildActionList(descriptions, 0, null, 0,
0964: actions, editor);
0965:
0966: return actions;
0967: }
0968:
0969: //
0970: /**
0971: * This method visits all the nodes in a DOM tree, converts them into Swing/Contelligent client -Actions (inclusive information about the hierarchical structure) and add them into a Collection of actions.
0972: *
0973: * @param node
0974: * @param level
0975: * @param parentAction
0976: * @param actions
0977: * @param editor
0978: *
0979: * @return
0980: */
0981: private void visitChildNodesAndBuildActionList(Node node,
0982: int level, BookmarkFolderAction parentAction, int position,
0983: List<Action> actions, ExplorerEditor editor) {
0984:
0985: // If there are any children, visit each one
0986: NodeList list = node.getChildNodes();
0987:
0988: for (int i = 0; i < list.getLength(); i++) {
0989: // Get child node
0990: Node childNode = list.item(i);
0991:
0992: if (childNode.getNodeType() == Node.ELEMENT_NODE) {
0993:
0994: Integer menuTarget = null;
0995: if (level == 0) {
0996: menuTarget = ContelligentAction.MENU;
0997: } else {
0998: menuTarget = ContelligentAction.SUBMENU;
0999: }
1000: position++;
1001:
1002: if ("folder".equals(childNode.getNodeName())) {
1003:
1004: BookmarkFolder bookmarkFolder = BookmarkUtil
1005: .convertBookmarkFolderDomNodeToBookmarkFolder(childNode);
1006: BookmarkFolderAction bookmarkFolderAction = new BookmarkFolderAction(
1007: editor, i, bookmarkFolder, menuTarget,
1008: parentAction);
1009: actions.add(bookmarkFolderAction);
1010:
1011: // Visit child node
1012: visitChildNodesAndBuildActionList(childNode,
1013: level + 1, bookmarkFolderAction, position,
1014: actions, editor);
1015:
1016: continue;
1017: } else {
1018: if ("bookmark".equals(childNode.getNodeName())) {
1019:
1020: Bookmark bookmark = BookmarkUtil
1021: .convertBookmarkDomNodeToBookmark(childNode);
1022: actions.add(new GoToBookmarkAction(editor,
1023: position, bookmark, menuTarget,
1024: parentAction));
1025:
1026: continue;
1027: }
1028: }
1029: }
1030: }
1031: }
1032:
1033: public void onComponentAdded(ContelligentComponentEvent event) {
1034: loadBookmarksAfterComponentEvent(event);
1035: }
1036:
1037: public void onComponentChanged(ContelligentComponentEvent event) {
1038:
1039: loadBookmarksAfterComponentEvent(event);
1040: }
1041:
1042: public void onComponentRemoved(ContelligentComponentEvent event) {
1043:
1044: loadBookmarksAfterComponentEvent(event);
1045: }
1046:
1047: /**
1048: * This method determins if event target was the bookmark component of current user. if so the bookmarks will be reloaded.
1049: *
1050: * @param event
1051: */
1052: private void loadBookmarksAfterComponentEvent(
1053: ContelligentComponentEvent event) {
1054: String targetPath = ComponentPath.toClientComponentPath(event
1055: .getTarget());
1056:
1057: // we have to check if user bookmark component has changed, because the bookmark list in menu has to be always up to date. every bookmark item is a bookmark action.
1058: // get user:
1059: String groupID = Session.getInstance().getUser().getPrincipal()
1060: .getGroupId();
1061: String iD = Session.getInstance().getUser().getPrincipal()
1062: .getId();
1063: // build path to user bookmark component:
1064: String userPath = "/contelligent/home/" + groupID + "/" + iD;
1065: String userBookmarkPath = userPath.concat("/bookmarks");
1066: // check, if user bookmark component has changed:
1067: if (targetPath.equals(userBookmarkPath)
1068: || targetPath.equals(userPath)) {
1069: // update bookmarks
1070: this.bookmarksTree = loadBookmarks();
1071: }
1072: }
1073: }
|