001: package org.jasig.portal.channels.jsp.tree;
002:
003: import java.util.ArrayList;
004: import java.util.Collections;
005: import java.util.HashMap;
006: import java.util.List;
007: import java.util.Map;
008: import org.apache.commons.logging.Log;
009: import org.apache.commons.logging.LogFactory;
010: import org.jasig.portal.channels.jsp.Deployer;
011: import org.jasig.portal.properties.PropertiesManager;
012:
013: /**
014: * Represents configuration of the JSP Tree control.
015: *
016: * @author Mark Boyd
017: *
018: */
019: public class Config {
020: private static final Log LOG = LogFactory.getLog(Config.class);
021: private static final List DEFAULT_SURROGATES = getDefaultSurrogates();
022: private static final String TREE_RENDERER = getTreeRendererPath();
023:
024: private boolean includeUnresolveables = false;
025: private boolean lazilyLoad = true;
026: private boolean showBranches = true;
027: private boolean viewContainment = false;
028:
029: private IDomainActionSet actionSet = null;
030: private Map treeUrlResolvers = null;
031: private Map images;
032: private List surrogates = null;
033: private String labelRenderer = null;
034:
035: /**
036: * Returns an instance of Config with suitable defaults for rendering a
037: * very limited view of the tree hierarchy. Most default settings will be
038: * overridden for all implementations. By default there are no supported
039: * domain actions. The default surrogate uses hash codes for identifiers
040: * and returns the value of toString() for labels. Default label rendering
041: * treats the value returned from getlabelData and any registered
042: * implementations of ISurrogate or IDomainActionSet as a String and embeds
043: * that value as-is in the generated tree. The default image set will most
044: * likely not be accessible since its image paths are relative to these
045: * classes and do not take into consideration the web application
046: * architecture in which the tree is being rendered. By default branches are
047: * shown from parents to children, unresolveable domain objects are not
048: * show in the tree, containment is not portrayed, and domain objects are
049: * resolved through lazy loading.
050: */
051: public Config() {
052: // set up default utilities
053: String path = Images.class.getName();
054: path = path.replace('.', '/');
055: path = path.substring(0, path.lastIndexOf('/'));
056: labelRenderer = "/WEB-INF/" + path + "defaultLabelRenderer.jsp";
057: actionSet = new DefaultDomainActionSet();
058: surrogates = DEFAULT_SURROGATES;
059: includeUnresolveables = false;
060: lazilyLoad = true;
061: viewContainment = false;
062: showBranches = true;
063: }
064:
065: /**
066: * Determines the path to the tree renderer JSP based upon the value of the
067: * configured deployment location for jsp channel JSPs in portal.properties.
068: *
069: * @return
070: */
071: private static String getTreeRendererPath() {
072: String ctxRelativePath = PropertiesManager.getProperty(
073: Deployer.JSP_DEPLOY_DIR_PROP, "/WEB-INF/classes");
074: if (ctxRelativePath.endsWith("/")
075: || ctxRelativePath.endsWith("\\"))
076: ctxRelativePath = ctxRelativePath.substring(0,
077: ctxRelativePath.length() - 1);
078:
079: String cls = Config.class.getName();
080: String pkg = cls.substring(0, cls.lastIndexOf('.'));
081: String jspPath = pkg.replace('.', '/') + "/renderer.jsp";
082: return ctxRelativePath + '/' + jspPath;
083: }
084:
085: /**
086: * Returns the web application context relative path to the tree renderer
087: * JSP that knows how to render a tree using the classes in this package.
088: *
089: * @return
090: */
091: public String getRenderer() {
092: if (LOG.isDebugEnabled()) {
093: LOG.debug("getRenderer() --> " + TREE_RENDERER);
094: }
095: return TREE_RENDERER;
096: }
097:
098: /**
099: * Creates a default surrogates list for very simplistic resolution of
100: * domain objects. See DefaultSurrogate.
101: *
102: * @return
103: */
104: private static final List getDefaultSurrogates() {
105: List l = new ArrayList();
106: l.add(new DefaultSurrogate());
107: return Collections.unmodifiableList(l);
108: }
109:
110: /**
111: * Returns the set of supported domain action identifiers.
112: *
113: * @return Returns the actions.
114: */
115: public String[] getDomainActions() {
116: if (LOG.isDebugEnabled()) {
117: if (actionSet == null)
118: LOG.debug("getDomainActions() --> null");
119: else
120: LOG.debug("getDomainActions() --> length="
121: + actionSet.getSupportedActions().length);
122: }
123: return actionSet.getSupportedActions();
124: }
125:
126: /**
127: * Sets the required, web application context relative path to a JSP for
128: * rendering action, node, and aspect labels. To this JSP will be passed the
129: * TreeModel, the current TreeNode, the type of label being rendered, and
130: * for actions the current action. These are accessible in the called JSP
131: * via:
132: *
133: * <pre>
134: * TreeModel = ${requestScope.model}
135: * Current TreeNode = ${requestScope.model.node}
136: * Label Type = ${requestScope.model.labelType} = ['action'|'node'|'aspect']
137: * Current Action = ${requestScope.model.action}
138: * </pre>
139: *
140: * @param labelRenderer
141: */
142: public void setLabelRenderer(String labelRenderer) {
143: if (LOG.isDebugEnabled()) {
144: LOG.debug("setLabelRenderer(" + labelRenderer + ")");
145: }
146: this .labelRenderer = labelRenderer;
147: }
148:
149: /**
150: * Returns the web application context relative path to a JSP for rendering
151: * node and action labels for the tree. Called by the tree renderer JSP to
152: * include the contents of the rendered label.
153: *
154: * @return
155: */
156: public String getLabelRenderer() {
157: if (LOG.isDebugEnabled()) {
158: LOG.debug("getLabelRenderer() --> " + labelRenderer);
159: }
160: return labelRenderer;
161: }
162:
163: /**
164: * Adds a surrogate suitable for handling translation of tree semantics to
165: * calls to a domain object of specific types.
166: *
167: * @param surrogate
168: */
169: public void addSurrogate(ISurrogate surrogate) {
170: if (surrogates == DEFAULT_SURROGATES)
171: surrogates = new ArrayList();
172: if (LOG.isDebugEnabled()) {
173: if (surrogate == null)
174: LOG.debug("addSurrogate(null)");
175: else
176: LOG.debug("addSurrogate("
177: + surrogate.getClass().getName() + ")");
178: }
179: surrogates.add(surrogate);
180: }
181:
182: List getSurrogates() {
183: if (LOG.isDebugEnabled()) {
184: if (surrogates == DEFAULT_SURROGATES)
185: LOG.debug("getSurrogates() --> DEFAULT_SURROGATES");
186: else
187: LOG.debug("getSurrogates() --> list.size()="
188: + surrogates.size());
189: }
190: return surrogates;
191: }
192:
193: public Map getImages() {
194: if (LOG.isDebugEnabled()) {
195: if (images == null)
196: LOG.debug("getImages() --> null");
197: else
198: LOG
199: .debug("getImages() --> map.size()="
200: + images.size());
201: }
202: return images;
203: }
204:
205: public void setImages(Map types) {
206: if (LOG.isDebugEnabled()) {
207: if (types == null)
208: LOG.debug("setImages(null)");
209: else
210: LOG.debug("setImages(map.size()=" + types.size() + ")");
211: }
212: images = types;
213: }
214:
215: public boolean getViewContainment() {
216: if (LOG.isDebugEnabled())
217: LOG.debug("getViewContainment() --> " + viewContainment);
218: return viewContainment;
219: }
220:
221: public void setViewContainment(boolean b) {
222: if (LOG.isDebugEnabled())
223: LOG.debug("setViewContainment(" + b + ")");
224: viewContainment = b;
225: }
226:
227: /**
228: * @return Returns the showBranches.
229: */
230: public boolean getShowBranches() {
231: if (LOG.isDebugEnabled())
232: LOG.debug("getShowBranches() --> " + showBranches);
233: return showBranches;
234: }
235:
236: /**
237: * @param showBranches
238: * The showBranches to set.
239: */
240: public void setShowBranches(boolean showBranches) {
241: if (LOG.isDebugEnabled())
242: LOG.debug("setShowBranches(" + showBranches + ")");
243: this .showBranches = showBranches;
244: }
245:
246: /**
247: * Returns the plugged-in implementation of IDomainActionSet.
248: * @return
249: */
250: public IDomainActionSet getActionSet() {
251: if (LOG.isDebugEnabled()) {
252: if (actionSet == null)
253: LOG.debug("getActionSet() --> null");
254: else
255: LOG.debug("getActionSet() --> "
256: + actionSet.getClass().getName());
257: }
258: return actionSet;
259: }
260:
261: public void setActionSet(IDomainActionSet actionSet) {
262: if (LOG.isDebugEnabled()) {
263: if (actionSet == null)
264: LOG.debug("setActionSet(null)");
265: else
266: LOG.debug("setActionSet("
267: + actionSet.getClass().getName() + ")");
268: }
269: this .actionSet = actionSet;
270: }
271:
272: public Map getTreeUrlResolvers() {
273: if (treeUrlResolvers == null) {
274: String message = "No instance of "
275: + "ITreeActionUrlResolver was registered. Rendering can "
276: + "not take place without an implementation of this "
277: + "interface.";
278: LOG.error(message);
279: throw new IllegalArgumentException(message);
280: }
281: if (LOG.isDebugEnabled())
282: LOG.debug("getTreeUrlResolvers() --> map.size()="
283: + treeUrlResolvers.size());
284: return treeUrlResolvers;
285: }
286:
287: public void setTreeUrlResolver(ITreeActionUrlResolver resolver) {
288: if (LOG.isDebugEnabled()) {
289: if (resolver == null)
290: LOG.debug("setTreeUrlResolver(null)");
291: else
292: LOG.debug("setTreeUrlResolver("
293: + resolver.getClass().getName() + ")");
294: }
295: treeUrlResolvers = new HashMap();
296: treeUrlResolvers.put("expand", new UrlResolver(resolver,
297: ITreeActionUrlResolver.SHOW_CHILDREN));
298: treeUrlResolvers.put("collapse", new UrlResolver(resolver,
299: ITreeActionUrlResolver.HIDE_CHILDREN));
300: treeUrlResolvers.put("showAspects", new UrlResolver(resolver,
301: ITreeActionUrlResolver.SHOW_ASPECTS));
302: treeUrlResolvers.put("hideAspects", new UrlResolver(resolver,
303: ITreeActionUrlResolver.HIDE_ASPECTS));
304: }
305:
306: public void setIncludeUnresolveables(boolean includeUnresolveables) {
307: if (LOG.isDebugEnabled())
308: LOG.debug("setIncludeUnresolveables("
309: + includeUnresolveables + ")");
310: this .includeUnresolveables = includeUnresolveables;
311: }
312:
313: public boolean getIncludeUnresolveables() {
314: if (LOG.isDebugEnabled())
315: LOG.debug("getIncludeUnresolveables() --> "
316: + includeUnresolveables);
317: return includeUnresolveables;
318: }
319:
320: public boolean getLazilyLoad() {
321: if (LOG.isDebugEnabled())
322: LOG.debug("getLazilyLoad() --> " + lazilyLoad);
323: return lazilyLoad;
324: }
325:
326: public void setLazilyLoad(boolean b) {
327: if (LOG.isDebugEnabled())
328: LOG.debug("setLazilyLoad(" + b + ")");
329: this.lazilyLoad = b;
330: }
331: }
|