001: /*
002: * Copyright 2006 Luca Garulli (luca.garulli@assetdata.it)
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUTreeNodeMap WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016:
017: package org.romaframework.core.domain.type;
018:
019: import java.util.Collection;
020: import java.util.Map;
021:
022: import org.romaframework.aspect.core.annotation.AnnotationConstants;
023: import org.romaframework.aspect.view.annotation.ViewField;
024:
025: /**
026: * Generic TreeNode implementation that uses Map type for children. Children property is lazy instantiated: first time a child is
027: * added a Map implementation is created in background. This class is abstract, so use implementations.
028: *
029: * @author Luca Garulli (luca.garulli@assetdata.it)
030: * @see org.romaframework.module.admin.domain.tree.TreeNodeList
031: */
032: public abstract class TreeNodeMap extends TreeNodeBase {
033: protected Map<String, TreeNodeMap> children;
034:
035: public TreeNodeMap(String iName) {
036: name = iName;
037: }
038:
039: public TreeNodeMap(TreeNodeMap iParent, String iName) {
040: parent = iParent;
041: name = iName;
042: }
043:
044: protected abstract Map<String, TreeNodeMap> createMap();
045:
046: /**
047: * Destroy children recursively
048: */
049: @ViewField(visible=AnnotationConstants.FALSE)
050: public void destroy() {
051: if (children != null) {
052: // CALL DESTROY RECURSIVELY
053: for (TreeNodeMap v : children.values()) {
054: v.destroy();
055: }
056: children.clear();
057: }
058: children = null;
059: parent = null;
060: }
061:
062: @Override
063: public Object clone() throws CloneNotSupportedException {
064: TreeNodeMap cloned = (TreeNodeMap) super .clone();
065:
066: cloned.parent = (TreeNodeMap) ((TreeNodeMap) parent).clone();
067:
068: // CLONE CHILDREN RECURSIVELY
069: cloned.children = createMap();
070: for (Map.Entry<String, TreeNodeMap> entry : children.entrySet()) {
071: cloned.children.put(entry.getKey(), (TreeNodeMap) entry
072: .getValue().clone());
073: }
074: return cloned;
075: }
076:
077: public TreeNodeMap getChild(String iName) {
078: if (children == null)
079: return null;
080:
081: return children.get(iName);
082: }
083:
084: @ViewField(visible=AnnotationConstants.FALSE)
085: public Collection<? extends TreeNode> getChildren() {
086: if (children == null)
087: return null;
088:
089: return children.values();
090: }
091:
092: public synchronized TreeNodeMap addChild(TreeNodeMap iChild) {
093: return addChild(iChild.toString(), iChild);
094: }
095:
096: public synchronized TreeNodeMap addChild(String iName,
097: TreeNodeMap iChild) {
098: if (children == null)
099: synchronized (getClass()) {
100: if (children == null) {
101: children = createMap();
102: }
103: }
104:
105: children.put(iName, iChild);
106: iChild.setParent(this);
107:
108: return iChild;
109: }
110: }
|