001: /***************************************************************
002: * This file is part of the [fleXive](R) project.
003: *
004: * Copyright (c) 1999-2007
005: * UCS - unique computing solutions gmbh (http://www.ucs.at)
006: * All rights reserved
007: *
008: * The [fleXive](R) project is free software; you can redistribute
009: * it and/or modify it under the terms of the GNU General Public
010: * License as published by the Free Software Foundation;
011: * either version 2 of the License, or (at your option) any
012: * later version.
013: *
014: * The GNU General Public License can be found at
015: * http://www.gnu.org/copyleft/gpl.html.
016: * A copy is found in the textfile GPL.txt and important notices to the
017: * license from the author are found in LICENSE.txt distributed with
018: * these libraries.
019: *
020: * This library is distributed in the hope that it will be useful,
021: * but WITHOUT ANY WARRANTY; without even the implied warranty of
022: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
023: * GNU General Public License for more details.
024: *
025: * For further information about UCS - unique computing solutions gmbh,
026: * please see the company website: http://www.ucs.at
027: *
028: * For further information about [fleXive](R), please see the
029: * project website: http://www.flexive.org
030: *
031: *
032: * This copyright notice MUST APPEAR in all copies of the file!
033: ***************************************************************/package com.flexive.war.javascript.tree;
034:
035: import com.flexive.faces.RequestRelativeUriMapper;
036: import com.flexive.faces.components.TreeRenderer;
037: import com.flexive.faces.javascript.tree.TreeNodeWriter;
038: import com.flexive.faces.javascript.tree.TreeNodeWriter.Node;
039: import com.flexive.shared.CacheAdmin;
040: import com.flexive.shared.FxSharedUtils;
041: import com.flexive.shared.structure.*;
042: import org.apache.commons.logging.Log;
043: import org.apache.commons.logging.LogFactory;
044:
045: import javax.servlet.http.HttpServletRequest;
046: import java.io.IOException;
047: import java.io.Serializable;
048: import java.io.StringWriter;
049: import java.util.*;
050:
051: /**
052: * Renders the structure tree for the current user.
053: *
054: * @author Daniel Lichtenberger (daniel.lichtenberger@flexive.com), UCS - unique computing solutions gmbh (http://www.ucs.at)
055: * @version $Rev: 205 $
056: */
057: public class StructureTreeWriter implements Serializable {
058: private static final long serialVersionUID = 7930729560359590725L;
059: private static final Log LOG = LogFactory
060: .getLog(StructureTreeWriter.class);
061:
062: public static final String DOC_TYPE_GROUP = "Group";
063: public static final String DOC_TYPE_TYPE = "Type";
064: public static final String DOC_TYPE_TYPE_RELATION = "TypeRelation";
065: public static final String DOC_TYPE_ASSIGNMENT = "Assignment";
066: public static final String DOC_TYPE_ASSIGNMENT_SYSTEMINTERNAL = "AssignmentSystemInternal";
067:
068: /**
069: * Render the structure tree to the node writer set in the current request.
070: * Called through the JSON-RPC wrapper.
071: *
072: * @param request the current request
073: * @param typeId the type to be rendered (or -1 for all structures)
074: * @return nothing
075: */
076: public String renderStructureTree(HttpServletRequest request,
077: long typeId) {
078: StringWriter localWriter = null;
079: try {
080: // if embedded in a tree component, use the component's tree writer
081: TreeNodeWriter writer = (TreeNodeWriter) request
082: .getAttribute(TreeRenderer.PROP_NODEWRITER);
083: if (writer == null) {
084: // otherwise return the tree nodes in the response
085: localWriter = new StringWriter();
086: writer = new TreeNodeWriter(localWriter,
087: new RequestRelativeUriMapper(request),
088: TreeNodeWriter.FORMAT_PLAIN);
089: }
090: writeStructureTree(writer, typeId, request);
091: if (localWriter != null) {
092: writer.finishResponse();
093: }
094: } catch (Throwable e) {
095: LOG.error("Failed to render structure tree: "
096: + e.getMessage(), e);
097: }
098: return localWriter != null ? localWriter.toString() : "";
099: }
100:
101: /**
102: * Render the structure tree from the given start node (use -1 to print
103: * the whole tree.)
104: *
105: * @param writer the tree node writer
106: * @param typeId the start type ID (-1 for all types)
107: * @param request the current servlet request
108: * @throws IOException if the tree could not be written
109: */
110: public void writeStructureTree(TreeNodeWriter writer, long typeId,
111: HttpServletRequest request) throws IOException {
112: final FxEnvironment environment = CacheAdmin
113: .getFilteredEnvironment();
114: Map<String, Object> nodeProperties = new HashMap<String, Object>();
115: if (typeId == -1) {
116: // print whole tree
117:
118: // print root types
119: for (FxType type : environment.getTypes(true, false, true,
120: true)) {
121: writeType(writer, nodeProperties, type);
122: }
123: // print root properties
124:
125: //sort assignments by position
126: List<FxPropertyAssignment> systemInternalprops = new ArrayList<FxPropertyAssignment>();
127: systemInternalprops.addAll(environment
128: .getSystemInternalRootPropertyAssignments());
129: Collections.sort(systemInternalprops,
130: new FxSharedUtils.AssignmentPositionSorter());
131:
132: for (FxPropertyAssignment property : systemInternalprops) {
133: writePropertyAssignment(writer, nodeProperties,
134: property);
135: }
136:
137: } else {
138: // print chosen node
139: writeType(writer, nodeProperties, environment
140: .getType(typeId));
141: }
142: }
143:
144: /**
145: * Render a type including its derived types, assigned groups and properties.
146: *
147: * @param writer the tree node writer
148: * @param type the type to be rendered
149: * @param nodeProperties an existing hashmap for storing additional JS properties (cleared on entry)
150: * @throws IOException if the tree could not be written
151: */
152:
153: private void writeType(TreeNodeWriter writer,
154: Map<String, Object> nodeProperties, FxType type)
155: throws IOException {
156: nodeProperties.clear();
157: nodeProperties.put("propertyId", String.valueOf(type.getId()));
158:
159: writer.startNode(new Node(String.valueOf(type.getId()), type
160: .getDisplayName(),
161: type.isRelation() ? DOC_TYPE_TYPE_RELATION
162: : DOC_TYPE_TYPE, nodeProperties));
163: writer.startChildren();
164: // write derived types
165: for (FxType child : type.getDerivedTypes()) {
166: writeType(writer, nodeProperties, child);
167: }
168:
169: //sort group and property assignments
170: List<FxAssignment> assignments = new ArrayList<FxAssignment>();
171: assignments.addAll(type.getAssignedGroups());
172: assignments.addAll(type.getAssignedProperties());
173: Collections.sort(assignments,
174: new FxSharedUtils.AssignmentPositionSorter());
175:
176: //write group and property assignments
177: for (FxAssignment a : assignments) {
178: if (a instanceof FxPropertyAssignment
179: && !a.isSystemInternal())
180: writePropertyAssignment(writer, nodeProperties,
181: (FxPropertyAssignment) a);
182: else if (a instanceof FxGroupAssignment)
183: writeGroupAssignment(writer, nodeProperties,
184: (FxGroupAssignment) a);
185: }
186:
187: writer.closeChildren();
188: writer.closeNode();
189: }
190:
191: /**
192: * Render an assigned property.
193: *
194: * @param writer the tree node writer
195: * @param nodeProperties an existing hashmap for storing additional JS properties (cleared on entry)
196: * @param property the property to be rendered
197: * @throws IOException if the tree could not be written
198: */
199: private void writePropertyAssignment(TreeNodeWriter writer,
200: Map<String, Object> nodeProperties,
201: FxPropertyAssignment property) throws IOException {
202: nodeProperties.clear();
203: nodeProperties.put("propertyId", String.valueOf(property
204: .getId()));
205: writer
206: .writeNode(new Node(
207: String.valueOf(property.getId()),
208: property.getDisplayName(),
209: property.isSystemInternal() ? DOC_TYPE_ASSIGNMENT_SYSTEMINTERNAL
210: : DOC_TYPE_ASSIGNMENT, nodeProperties));
211: }
212:
213: /**
214: * Render an assigned group, included assigned subgroups and properties.
215: *
216: * @param writer the tree node writer
217: * @param nodeProperties an existing hashmap for storing additional JS properties (cleared on entry)
218: * @param group the group to be rendered
219: * @throws IOException if the tree could not be written
220: */
221:
222: private void writeGroupAssignment(TreeNodeWriter writer,
223: Map<String, Object> nodeProperties, FxGroupAssignment group)
224: throws IOException {
225: nodeProperties.clear();
226: nodeProperties.put("propertyId", String.valueOf(group.getId()));
227: writer.startNode(new Node(String.valueOf(group.getId()), group
228: .getDisplayName(), DOC_TYPE_GROUP, nodeProperties));
229: writer.startChildren();
230:
231: // sort and write nested groups
232: List<FxGroupAssignment> nested = new ArrayList<FxGroupAssignment>();
233: nested.addAll(group.getAssignedGroups());
234: Collections.sort(nested,
235: new FxSharedUtils.AssignmentPositionSorter());
236: for (FxGroupAssignment nestedGroup : nested) {
237: writeGroupAssignment(writer, nodeProperties, nestedGroup);
238: }
239:
240: // sort and write properties
241: List<FxPropertyAssignment> props = new ArrayList<FxPropertyAssignment>();
242: props.addAll(group.getAssignedProperties());
243: Collections.sort(props,
244: new FxSharedUtils.AssignmentPositionSorter());
245: for (FxPropertyAssignment property : props) {
246: if (!property.isSystemInternal()) {
247: writePropertyAssignment(writer, nodeProperties,
248: property);
249: }
250: }
251: // add assigned properties
252: writer.closeChildren();
253: writer.closeNode();
254: }
255: }
|