001: /*
002: * File : $Source: /usr/local/cvs/opencms/src/org/opencms/workplace/tools/CmsToolManager.java,v $
003: * Date : $Date: 2008-02-27 12:05:31 $
004: * Version: $Revision: 1.48 $
005: *
006: * This library is part of OpenCms -
007: * the Open Source Content Management System
008: *
009: * Copyright (c) 2002 - 2008 Alkacon Software GmbH (http://www.alkacon.com)
010: *
011: * This library is free software; you can redistribute it and/or
012: * modify it under the terms of the GNU Lesser General Public
013: * License as published by the Free Software Foundation; either
014: * version 2.1 of the License, or (at your option) any later version.
015: *
016: * This library is distributed in the hope that it will be useful,
017: * but WITHOUT ANY WARRANTY; without even the implied warranty of
018: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
019: * Lesser General Public License for more details.
020: *
021: * For further information about Alkacon Software GmbH, please see the
022: * company website: http://www.alkacon.com
023: *
024: * For further information about OpenCms, please see the
025: * project website: http://www.opencms.org
026: *
027: * You should have received a copy of the GNU Lesser General Public
028: * License along with this library; if not, write to the Free Software
029: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
030: */
031:
032: package org.opencms.workplace.tools;
033:
034: import org.opencms.file.CmsObject;
035: import org.opencms.file.CmsProperty;
036: import org.opencms.file.CmsResource;
037: import org.opencms.i18n.CmsEncoder;
038: import org.opencms.jsp.CmsJspActionElement;
039: import org.opencms.main.CmsException;
040: import org.opencms.main.CmsLog;
041: import org.opencms.util.CmsRequestUtil;
042: import org.opencms.util.CmsStringUtil;
043: import org.opencms.workplace.CmsDialog;
044: import org.opencms.workplace.CmsWorkplace;
045:
046: import java.io.IOException;
047: import java.util.ArrayList;
048: import java.util.HashMap;
049: import java.util.Iterator;
050: import java.util.List;
051: import java.util.Map;
052:
053: import javax.servlet.ServletException;
054:
055: import org.apache.commons.logging.Log;
056:
057: /**
058: * Manages the registered tools, actualizing its state every time the workplace is reinitialize.<p>
059: *
060: * Manages also the configuration settings for the administration view, and provides
061: * several tool related methods.<p>
062: *
063: * @author Michael Moossen
064: *
065: * @version $Revision: 1.48 $
066: *
067: * @since 6.0.0
068: */
069: public class CmsToolManager {
070:
071: /** Root location of the administration view. */
072: public static final String ADMINVIEW_ROOT_LOCATION = CmsWorkplace.PATH_WORKPLACE
073: + "views/admin";
074:
075: /** Property definition name to look for. */
076: public static final String HANDLERCLASS_PROPERTY = "admintoolhandler-class";
077:
078: /** Navigation bar separator (html code). */
079: public static final String NAVBAR_SEPARATOR = "\n > \n";
080:
081: /** Tool root separator. */
082: public static final String ROOT_SEPARATOR = ":";
083:
084: /** Key for the default tool root, if there is no configured root with this a key, a new one will be configured. */
085: public static final String ROOTKEY_DEFAULT = "admin";
086:
087: /** Tool path separator. */
088: public static final String TOOLPATH_SEPARATOR = "/";
089:
090: /** Location of the default admin view jsp page. */
091: public static final String VIEW_JSPPAGE_LOCATION = ADMINVIEW_ROOT_LOCATION
092: + "/admin-main.jsp";
093:
094: /** The static log object for this class. */
095: private static final Log LOG = CmsLog.getLog(CmsToolManager.class);
096:
097: /** List of all available roots. */
098: private final CmsIdentifiableObjectContainer m_roots;
099:
100: /** List of all available tools. */
101: private final CmsIdentifiableObjectContainer m_tools;
102:
103: /** List of all available urls and related tool paths. */
104: private final CmsIdentifiableObjectContainer m_urls;
105:
106: /**
107: * Default constructor.<p>
108: */
109: public CmsToolManager() {
110:
111: m_roots = new CmsIdentifiableObjectContainer(true, false);
112: m_tools = new CmsIdentifiableObjectContainer(true, false);
113: m_urls = new CmsIdentifiableObjectContainer(false, false);
114: }
115:
116: /**
117: * Returns the OpenCms link for the given tool path which requires no parameters.<p>
118: *
119: * @param jsp the jsp action element
120: * @param toolPath the tool path
121: *
122: * @return the OpenCms link for the given tool path which requires parameters
123: */
124: public static String linkForToolPath(CmsJspActionElement jsp,
125: String toolPath) {
126:
127: StringBuffer result = new StringBuffer();
128: result.append(jsp.link(VIEW_JSPPAGE_LOCATION));
129: result.append('?');
130: result.append(CmsToolDialog.PARAM_PATH);
131: result.append('=');
132: result.append(CmsEncoder.encode(toolPath));
133: return result.toString();
134: }
135:
136: /**
137: * Returns the OpenCms link for the given tool path which requires parameters.<p>
138: *
139: * Please note: Don't overuse the parameter map because this will likely introduce issues
140: * with encoding. If possible, don't pass parameters at all, or only very simple parameters
141: * with no special chars that can easily be parsed.<p>
142: *
143: * @param jsp the jsp action element
144: * @param toolPath the tool path
145: * @param params the map of required tool parameters
146: *
147: * @return the OpenCms link for the given tool path which requires parameters
148: */
149: public static String linkForToolPath(CmsJspActionElement jsp,
150: String toolPath, Map params) {
151:
152: if (params == null) {
153: // no parameters - take the shortcut
154: return linkForToolPath(jsp, toolPath);
155: }
156: params.put(CmsToolDialog.PARAM_PATH, toolPath);
157: return CmsRequestUtil.appendParameters(jsp
158: .link(VIEW_JSPPAGE_LOCATION), params, true);
159: }
160:
161: /**
162: * Adds a new tool root to the tool manager.<p>
163: *
164: * @param toolRoot the tool root to add
165: */
166: public void addToolRoot(CmsToolRootHandler toolRoot) {
167:
168: m_roots.addIdentifiableObject(toolRoot.getKey(), toolRoot);
169: }
170:
171: /**
172: * Called by the <code>{@link org.opencms.workplace.CmsWorkplaceManager#initialize(CmsObject)}</code> method.<p>
173: *
174: * @param cms the admin cms context
175: */
176: public void configure(CmsObject cms) {
177:
178: if (CmsLog.INIT.isInfoEnabled()) {
179: CmsLog.INIT.info(Messages.get().getBundle().key(
180: Messages.INIT_TOOLMANAGER_CREATED_0));
181: }
182: if (m_roots.getObject(ROOTKEY_DEFAULT) == null) {
183: CmsToolRootHandler defToolRoot = new CmsToolRootHandler();
184: defToolRoot.setKey(ROOTKEY_DEFAULT);
185: defToolRoot.setUri(CmsWorkplace.PATH_WORKPLACE + "admin/");
186: defToolRoot.setName("${key."
187: + Messages.GUI_ADMIN_VIEW_ROOT_NAME_0 + "}");
188: defToolRoot.setHelpText("${key."
189: + Messages.GUI_ADMIN_VIEW_ROOT_HELP_0 + "}");
190: addToolRoot(defToolRoot);
191: }
192: m_tools.clear();
193: m_urls.clear();
194: Iterator it = getToolRoots().iterator();
195: while (it.hasNext()) {
196: CmsToolRootHandler toolRoot = (CmsToolRootHandler) it
197: .next();
198: if (!cms.existsResource(toolRoot.getUri())) {
199: if (CmsLog.INIT.isInfoEnabled()) {
200: CmsLog.INIT.info(Messages.get().getBundle().key(
201: Messages.INIT_TOOLMANAGER_ROOT_SKIPPED_2,
202: toolRoot.getKey(), toolRoot.getUri()));
203: }
204: continue;
205: }
206: try {
207: toolRoot.setup(cms, null, toolRoot.getUri());
208: configureToolRoot(cms, toolRoot);
209: // log info
210: if (CmsLog.INIT.isInfoEnabled()) {
211: CmsLog.INIT.info(Messages.get().getBundle().key(
212: Messages.INIT_TOOLMANAGER_SETUP_1,
213: toolRoot.getKey()));
214: }
215: } catch (CmsException e) {
216: // log failure
217: if (CmsLog.INIT.isWarnEnabled()) {
218: CmsLog.INIT.warn(Messages.get().getBundle().key(
219: Messages.INIT_TOOLMANAGER_SETUP_ERROR_1,
220: toolRoot.getKey()), e);
221: }
222: }
223: }
224: }
225:
226: /**
227: * Returns the navigation bar html code for the given tool path.<p>
228: *
229: * @param toolPath the path
230: * @param wp the jsp page
231: *
232: * @return the html code
233: */
234: public String generateNavBar(String toolPath, CmsWorkplace wp) {
235:
236: if (toolPath.equals(getBaseToolPath(wp))) {
237: return "<div class='pathbar'> </div>\n";
238: }
239: CmsTool adminTool = resolveAdminTool(getCurrentRoot(wp)
240: .getKey(), toolPath);
241: String html = A_CmsHtmlIconButton.defaultButtonHtml(
242: CmsHtmlIconButtonStyleEnum.SMALL_ICON_TEXT, "nav"
243: + adminTool.getId(), adminTool.getHandler()
244: .getName(), null, false, null, null, null);
245: String parent = toolPath;
246: while (!parent.equals(getBaseToolPath(wp))) {
247: parent = getParent(wp, parent);
248: adminTool = resolveAdminTool(getCurrentRoot(wp).getKey(),
249: parent);
250:
251: String id = "nav" + adminTool.getId();
252: String link = linkForToolPath(wp.getJsp(), parent,
253: adminTool.getHandler().getParameters(wp));
254: String onClic = "openPage('" + link + "');";
255: String buttonHtml = A_CmsHtmlIconButton.defaultButtonHtml(
256: CmsHtmlIconButtonStyleEnum.SMALL_ICON_TEXT, id,
257: adminTool.getHandler().getName(), adminTool
258: .getHandler().getHelpText(), true, null,
259: null, onClic);
260: html = buttonHtml + NAVBAR_SEPARATOR + html;
261: }
262: html = CmsToolMacroResolver.resolveMacros(html, wp);
263: html = CmsEncoder.decode(html);
264: html = CmsToolMacroResolver.resolveMacros(html, wp);
265: html = "<div class='pathbar'>\n" + html + " </div>\n";
266: return html;
267: }
268:
269: /**
270: * Returns the base tool path for the active user.<p>
271: *
272: * @param wp the workplace object
273: *
274: * @return the base tool path for the active user
275: */
276: public String getBaseToolPath(CmsWorkplace wp) {
277:
278: CmsToolUserData userData = getUserData(wp);
279: String path = TOOLPATH_SEPARATOR;
280: if (userData != null) {
281: path = userData.getBaseTool(getCurrentRoot(wp).getKey());
282: }
283: return path;
284: }
285:
286: /**
287: * Returns the current user's root handler.<p>
288: *
289: * @param wp the workplace context
290: *
291: * @return the current user's root handler
292: */
293: public CmsToolRootHandler getCurrentRoot(CmsWorkplace wp) {
294:
295: CmsToolUserData userData = getUserData(wp);
296: String root = ROOTKEY_DEFAULT;
297: if (userData != null) {
298: if (m_roots.getObject(userData.getRootKey()) != null) {
299: root = userData.getRootKey();
300: } else {
301: if (LOG.isErrorEnabled()) {
302: LOG.error(Messages.get().getBundle().key(
303: Messages.ERR_NOT_CONFIGURED_ROOT_1,
304: userData.getRootKey()));
305: }
306: }
307: }
308: return (CmsToolRootHandler) m_roots.getObject(root);
309: }
310:
311: /**
312: * Returns the current tool.<p>
313: *
314: * @param wp the workplace object
315: *
316: * @return the current tool
317: */
318: public CmsTool getCurrentTool(CmsWorkplace wp) {
319:
320: return resolveAdminTool(getCurrentRoot(wp).getKey(),
321: getCurrentToolPath(wp));
322: }
323:
324: /**
325: * Returns the current tool path.<p>
326: *
327: * @param wp the workplace object
328: *
329: * @return the current tool path
330: */
331: public String getCurrentToolPath(CmsWorkplace wp) {
332:
333: CmsToolUserData userData = getUserData(wp);
334: String path = getBaseToolPath(wp);
335: if (userData != null) {
336: path = userData.getCurrentToolPath(getCurrentRoot(wp)
337: .getKey());
338: }
339: return path;
340: }
341:
342: /**
343: * Returns the path to the parent of the tool identified by the given tool path.<p>
344: *
345: * The parent of the root is the same root.<p>
346: *
347: * @param wp the workplace object
348: * @param toolPath the abstract tool path
349: *
350: * @return his parent
351: */
352: public String getParent(CmsWorkplace wp, String toolPath) {
353:
354: if (toolPath.equals(getBaseToolPath(wp))) {
355: return toolPath;
356: }
357: int pos = toolPath.lastIndexOf(TOOLPATH_SEPARATOR);
358: return pos <= 0 ? TOOLPATH_SEPARATOR : toolPath.substring(0,
359: pos);
360: }
361:
362: /**
363: * Returns a list with all registered tools.<p>
364: *
365: * @return list if <code>{@link CmsTool}</code>
366: */
367: public List getToolHandlers() {
368:
369: return m_tools.elementList();
370: }
371:
372: /**
373: * Returns a list of tool roots.<p>
374: *
375: * @return a list of {@link CmsToolRootHandler} objects
376: */
377: public List getToolRoots() {
378:
379: return m_roots.elementList();
380: }
381:
382: /**
383: * Returns a list of all tools in the given path.<p>
384: *
385: * @param wp the workplace context
386: * @param baseTool the path
387: * @param includeSubtools if the tools in subfolders should be also returned
388: *
389: * @return a list of {@link CmsTool} objects
390: */
391: public List getToolsForPath(CmsWorkplace wp, String baseTool,
392: boolean includeSubtools) {
393:
394: List toolList = new ArrayList();
395: String rootKey = getCurrentRoot(wp).getKey();
396: Iterator itTools = m_tools.elementList().iterator();
397: while (itTools.hasNext()) {
398: CmsTool tool = (CmsTool) itTools.next();
399: String path = tool.getHandler().getPath();
400: if (resolveAdminTool(rootKey, path) != tool) {
401: continue;
402: }
403: if (path.equals(TOOLPATH_SEPARATOR)) {
404: continue;
405: }
406: // leave out everything above the base
407: if (!path.startsWith(baseTool)) {
408: continue;
409: }
410: // filter for path
411: if (baseTool.equals(TOOLPATH_SEPARATOR)
412: || path.startsWith(baseTool + TOOLPATH_SEPARATOR)) {
413: // filter sub tree
414: if (includeSubtools
415: || (path.indexOf(TOOLPATH_SEPARATOR, baseTool
416: .length() + 1) < 0)) {
417: toolList.add(tool);
418: }
419: }
420: }
421: return toolList;
422: }
423:
424: /**
425: * Returns the <code>{@link CmsToolUserData}</code> object for a given user.<p>
426: *
427: * @param wp the workplace object
428: *
429: * @return the current user data
430: */
431: public CmsToolUserData getUserData(CmsWorkplace wp) {
432:
433: CmsToolUserData userData = wp.getSettings().getToolUserData();
434: if (userData == null) {
435: userData = new CmsToolUserData();
436: userData.setRootKey(ROOTKEY_DEFAULT);
437: Iterator it = getToolRoots().iterator();
438: while (it.hasNext()) {
439: CmsToolRootHandler root = (CmsToolRootHandler) it
440: .next();
441: userData.setCurrentToolPath(root.getKey(),
442: TOOLPATH_SEPARATOR);
443: userData.setBaseTool(root.getKey(), TOOLPATH_SEPARATOR);
444: }
445: wp.getSettings().setToolUserData(userData);
446: }
447: return userData;
448: }
449:
450: /**
451: * Returns <code>true</code> if there is at least one tool registered using the given url.<p>
452: *
453: * @param url the url of the tool
454: *
455: * @return <code>true</code> if there is at least one tool registered using the given url
456: */
457: public boolean hasToolPathForUrl(String url) {
458:
459: List toolPaths = (List) m_urls.getObject(url);
460: return ((toolPaths != null) && !toolPaths.isEmpty());
461: }
462:
463: /**
464: * This method initializes the tool manager for the current user.<p>
465: *
466: * @param wp the jsp page coming from
467: */
468: public synchronized void initParams(CmsToolDialog wp) {
469:
470: setCurrentRoot(wp, wp.getParamRoot());
471: setCurrentToolPath(wp, wp.getParamPath());
472: setBaseToolPath(wp, wp.getParamBase());
473:
474: // if the current tool path is not under the current root, set the current root as the current tool
475: if (!getCurrentToolPath(wp).startsWith(getBaseToolPath(wp))) {
476: setCurrentToolPath(wp, getBaseToolPath(wp));
477: }
478: wp.setParamPath(getCurrentToolPath(wp));
479: wp.setParamBase(getBaseToolPath(wp));
480: wp.setParamRoot(getCurrentRoot(wp).getKey());
481: }
482:
483: /**
484: * Redirects to the given page with the given parameters.<p>
485: *
486: * @param wp the workplace object
487: * @param pagePath the path to the page to redirect to
488: * @param params the parameters to send
489: *
490: * @throws IOException in case of errors during forwarding
491: * @throws ServletException in case of errors during forwarding
492: */
493: public void jspForwardPage(CmsWorkplace wp, String pagePath,
494: Map params) throws IOException, ServletException {
495:
496: Map newParams = createToolParams(wp, pagePath, params);
497: if (pagePath.indexOf("?") > 0) {
498: pagePath = pagePath.substring(0, pagePath.indexOf("?"));
499: }
500:
501: wp.setForwarded(true);
502: // forward to the requested page uri
503: CmsRequestUtil.forwardRequest(wp.getJsp().link(pagePath),
504: CmsRequestUtil.createParameterMap(newParams), wp
505: .getJsp().getRequest(), wp.getJsp()
506: .getResponse());
507: }
508:
509: /**
510: * Redirects to the given tool with the given parameters.<p>
511: *
512: * @param wp the workplace object
513: * @param toolPath the path to the tool to redirect to
514: * @param params the parameters to send
515: *
516: * @throws IOException in case of errors during forwarding
517: * @throws ServletException in case of errors during forwarding
518: */
519: public void jspForwardTool(CmsWorkplace wp, String toolPath,
520: Map params) throws IOException, ServletException {
521:
522: Map newParams;
523: if (params == null) {
524: newParams = new HashMap();
525: } else {
526: newParams = new HashMap(params);
527: }
528: // update path param
529: newParams.put(CmsToolDialog.PARAM_PATH, toolPath);
530: jspForwardPage(wp, VIEW_JSPPAGE_LOCATION, newParams);
531: }
532:
533: /**
534: * Returns the admin tool corresponding to the given abstract path.<p>
535: *
536: * @param rootKey the tool root
537: * @param toolPath the path
538: *
539: * @return the corresponding tool, or <code>null</code> if not found
540: */
541: public CmsTool resolveAdminTool(String rootKey, String toolPath) {
542:
543: return (CmsTool) m_tools.getObject(rootKey + ROOT_SEPARATOR
544: + toolPath);
545: }
546:
547: /**
548: * Sets the base tool path.<p>
549: *
550: * @param wp the workplace object
551: * @param baseToolPath the base tool path to set
552: */
553: public void setBaseToolPath(CmsWorkplace wp, String baseToolPath) {
554:
555: // use last used base if param empty
556: if (CmsStringUtil.isEmpty(baseToolPath)
557: || baseToolPath.trim().equals("null")) {
558: baseToolPath = getBaseToolPath(wp);
559: }
560: baseToolPath = repairPath(wp, baseToolPath);
561: // set it
562: CmsToolUserData userData = getUserData(wp);
563: userData.setBaseTool(userData.getRootKey(), baseToolPath);
564: }
565:
566: /**
567: * Sets the current user's root key.<p>
568: *
569: * @param wp the workplace context
570: * @param key the current user's root key to set
571: */
572: public void setCurrentRoot(CmsWorkplace wp, String key) {
573:
574: // use last used root if param empty
575: if (CmsStringUtil.isEmpty(key) || key.trim().equals("null")) {
576: key = getCurrentRoot(wp).getKey();
577: }
578: // set it
579: CmsToolUserData userData = getUserData(wp);
580: userData.setRootKey(key);
581: }
582:
583: /**
584: * Sets the current tool path.<p>
585: *
586: * @param wp the workplace object
587: * @param currentToolPath the current tool path to set
588: */
589: public void setCurrentToolPath(CmsWorkplace wp,
590: String currentToolPath) {
591:
592: // use last used path if param empty
593: if (CmsStringUtil.isEmptyOrWhitespaceOnly(currentToolPath)
594: || currentToolPath.trim().equals("null")) {
595: currentToolPath = getCurrentToolPath(wp);
596: }
597: currentToolPath = repairPath(wp, currentToolPath);
598: // use it
599: CmsToolUserData userData = getUserData(wp);
600: userData.setCurrentToolPath(userData.getRootKey(),
601: currentToolPath);
602: }
603:
604: /**
605: * Configures a whole tool root with all its tools.<p>
606: *
607: * @param cms the cms context
608: * @param toolRoot the tool root to configure
609: *
610: * @throws CmsException if something goes wrong
611: */
612: private void configureToolRoot(CmsObject cms,
613: CmsToolRootHandler toolRoot) throws CmsException {
614:
615: List handlers = new ArrayList();
616:
617: // add tool root handler
618: handlers.add(toolRoot);
619:
620: // look in every file under the root uri for valid
621: // admin tools and register them
622: List resources = cms.readResourcesWithProperty(toolRoot
623: .getUri(), HANDLERCLASS_PROPERTY);
624: Iterator itRes = resources.iterator();
625: while (itRes.hasNext()) {
626: CmsResource res = (CmsResource) itRes.next();
627: CmsProperty prop = cms.readPropertyObject(
628: res.getRootPath(), HANDLERCLASS_PROPERTY, false);
629: if (!prop.isNullProperty()) {
630: try {
631: // instantiate the handler
632: Class handlerClass = Class.forName(prop.getValue());
633: I_CmsToolHandler handler = (I_CmsToolHandler) handlerClass
634: .newInstance();
635:
636: if (!handler
637: .setup(cms, toolRoot, res.getRootPath())) {
638: // log failure
639: if (CmsLog.INIT.isWarnEnabled()) {
640: CmsLog.INIT
641: .warn(Messages
642: .get()
643: .getBundle()
644: .key(
645: Messages.INIT_TOOLMANAGER_TOOL_SETUP_ERROR_1,
646: res.getRootPath()));
647: }
648: }
649:
650: // keep for later use
651: handlers.add(handler);
652: // log success
653: if (CmsLog.INIT.isDebugEnabled()) {
654: if (!handler.getLink().equals(
655: VIEW_JSPPAGE_LOCATION)) {
656: CmsLog.INIT
657: .debug(Messages
658: .get()
659: .getBundle()
660: .key(
661: Messages.INIT_TOOLMANAGER_NEWTOOL_FOUND_2,
662: handler.getPath(),
663: handler.getLink()));
664: } else {
665: CmsLog.INIT
666: .debug(Messages
667: .get()
668: .getBundle()
669: .key(
670: Messages.INIT_TOOLMANAGER_NEWTOOL_FOUND_2,
671: handler.getPath(),
672: res.getRootPath()));
673: }
674: }
675: } catch (Exception e) {
676: // log failure
677: if (CmsLog.INIT.isWarnEnabled()) {
678: CmsLog.INIT
679: .warn(
680: Messages
681: .get()
682: .getBundle()
683: .key(
684: Messages.INIT_TOOLMANAGER_TOOL_SETUP_ERROR_1,
685: res
686: .getRootPath()),
687: e);
688: }
689: }
690: }
691: }
692: registerHandlerList(cms, toolRoot, 1, handlers);
693: }
694:
695: /**
696: * Creates a parameter map from the given url and additional parameters.<p>
697: *
698: * @param wp the workplace context
699: * @param url the url to create the parameter map for (extracting query params)
700: * @param params additional parameter map
701: *
702: * @return the new parameter map
703: */
704: private Map createToolParams(CmsWorkplace wp, String url, Map params) {
705:
706: Map newParams = new HashMap();
707: // add query parameters to the parameter map if required
708: if (url.indexOf("?") > 0) {
709: String query = url.substring(url.indexOf("?"));
710: Map reqParameters = CmsRequestUtil
711: .createParameterMap(query);
712: newParams.putAll(reqParameters);
713: }
714: if (params != null) {
715: newParams.putAll(params);
716: }
717:
718: // put close link if not set
719: if (!newParams.containsKey(CmsDialog.PARAM_CLOSELINK)) {
720: Map argMap = resolveAdminTool(getCurrentRoot(wp).getKey(),
721: getCurrentToolPath(wp)).getHandler().getParameters(
722: wp);
723: newParams.put(CmsDialog.PARAM_CLOSELINK, linkForToolPath(wp
724: .getJsp(), getCurrentToolPath(wp), argMap));
725: }
726: return newParams;
727: }
728:
729: /**
730: * Registers a new tool at a given install point for the given tool root.<p>
731: *
732: * @param cms the cms context object
733: * @param toolRoot the tool root
734: * @param handler the handler to install
735: */
736: private void registerAdminTool(CmsObject cms,
737: CmsToolRootHandler toolRoot, I_CmsToolHandler handler) {
738:
739: String link = handler.getLink();
740: if (link.indexOf("?") > 0) {
741: link = link.substring(0, link.indexOf("?"));
742: }
743: // check visibility
744: if (!cms.existsResource(link)) {
745: return;
746: }
747:
748: //validate path
749: if (!validatePath(toolRoot.getKey(), handler.getPath(), false)) {
750: // log failure
751: if (CmsLog.INIT.isWarnEnabled()) {
752: CmsLog.INIT.warn(Messages.get().getBundle().key(
753: Messages.INIT_TOOLMANAGER_INCONSISTENT_PATH_2,
754: handler.getPath(), handler.getLink()));
755: }
756: return;
757: }
758:
759: String id = "tool" + m_tools.elementList().size();
760: CmsTool tool = new CmsTool(id, handler);
761:
762: try {
763: // try to find problems in custom tools
764: handler.isEnabled(cms);
765: handler.isVisible(cms);
766: } catch (Throwable ex) {
767: String message = Messages.get().getBundle().key(
768: Messages.INIT_TOOLMANAGER_INSTALL_ERROR_2,
769: handler.getPath(), handler.getLink());
770: if (CmsLog.INIT.isWarnEnabled()) {
771: CmsLog.INIT.warn(message);
772: } else if (CmsLog.INIT.isDebugEnabled()) {
773: CmsLog.INIT.debug(message, ex);
774: }
775: return;
776: }
777:
778: try {
779: // try to register, can fail if path is already used by another tool
780: m_tools.addIdentifiableObject(toolRoot.getKey()
781: + ROOT_SEPARATOR + handler.getPath(), tool);
782: // just for fast association of links with tools
783: m_urls.addIdentifiableObject(link, handler.getPath());
784: } catch (Throwable ex) {
785: CmsLog.INIT.warn(Messages.get().getBundle().key(
786: Messages.INIT_TOOLMANAGER_DUPLICATED_ERROR_3,
787: handler.getPath(),
788: handler.getLink(),
789: resolveAdminTool(toolRoot.getKey(),
790: handler.getPath()).getHandler().getLink()));
791: }
792: }
793:
794: /**
795: * Registers all tool handlers recursively for a given tool root.<p>
796: *
797: * @param cms the cms context object
798: * @param toolRoot the tool root
799: * @param len the recursion level
800: * @param handlers the list of handlers to register
801: */
802: private void registerHandlerList(CmsObject cms,
803: CmsToolRootHandler toolRoot, int len, List handlers) {
804:
805: boolean found = false;
806: Iterator it = handlers.iterator();
807: while (it.hasNext()) {
808: I_CmsToolHandler handler = (I_CmsToolHandler) it.next();
809: int myLen = CmsStringUtil.splitAsArray(handler.getPath(),
810: TOOLPATH_SEPARATOR).length;
811: if (((len == myLen) && !handler.getPath().equals(
812: TOOLPATH_SEPARATOR))
813: || ((len == 1) && handler.getPath().equals(
814: TOOLPATH_SEPARATOR))) {
815: found = true;
816: registerAdminTool(cms, toolRoot, handler);
817: }
818: }
819: if (found) {
820: registerHandlerList(cms, toolRoot, len + 1, handlers);
821: }
822:
823: }
824:
825: /**
826: * Given a string a valid and visible tool path is computed.<p>
827: *
828: * @param wp the workplace object
829: * @param path the path to repair
830: *
831: * @return a valid and visible tool path
832: */
833: private String repairPath(CmsWorkplace wp, String path) {
834:
835: String rootKey = getCurrentRoot(wp).getKey();
836: // navigate until to reach a valid path
837: while (!validatePath(rootKey, path, true)) {
838: // log failure
839: LOG.warn(Messages.get().getBundle().key(
840: Messages.LOG_MISSING_ADMIN_TOOL_1, path));
841: // try parent
842: path = getParent(wp, path);
843: }
844: // navigate until to reach a valid tool
845: while (resolveAdminTool(rootKey, path) == null) {
846: // log failure
847: LOG.warn(Messages.get().getBundle().key(
848: Messages.LOG_MISSING_ADMIN_TOOL_1, path));
849: // try parent
850: path = getParent(wp, path);
851: }
852:
853: // navegate until to reach an enabled path
854: CmsTool aTool = resolveAdminTool(rootKey, path);
855: while (!aTool.getHandler().isEnabled(wp)) {
856: if (aTool.getHandler().getLink().equals(
857: VIEW_JSPPAGE_LOCATION)) {
858: // just grouping
859: break;
860: }
861: path = getParent(wp, path);
862: aTool = resolveAdminTool(rootKey, path);
863: }
864:
865: return path;
866: }
867:
868: /**
869: * Tests if the full tool path is available.<p>
870: *
871: * @param rootKey the root tool
872: * @param toolPath the path
873: * @param full if <code>true</code> the whole path is checked, if not the last part is not checked (for new tools)
874: *
875: * @return if valid or not
876: */
877: private boolean validatePath(String rootKey, String toolPath,
878: boolean full) {
879:
880: if (toolPath.equals(TOOLPATH_SEPARATOR)) {
881: return true;
882: }
883: if (!toolPath.startsWith(TOOLPATH_SEPARATOR)) {
884: return false;
885: }
886: List groups = CmsStringUtil.splitAsList(toolPath,
887: TOOLPATH_SEPARATOR);
888: Iterator itGroups = groups.iterator();
889: String subpath = "";
890: while (itGroups.hasNext()) {
891: String group = (String) itGroups.next();
892: if (subpath.length() != TOOLPATH_SEPARATOR.length()) {
893: subpath += TOOLPATH_SEPARATOR + group;
894: } else {
895: subpath += group;
896: }
897: if (itGroups.hasNext() || full) {
898: try {
899: // just check if the tool is available
900: resolveAdminTool(rootKey, subpath).toString();
901: } catch (Exception e) {
902: return false;
903: }
904: }
905: }
906: return true;
907: }
908: }
|