Java tutorial
/** * Copyright (C) 2000 - 2012 Silverpeas * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * As a special exception to the terms and conditions of version 3.0 of * the GPL, you may redistribute this Program in connection with Free/Libre * Open Source Software ("FLOSS") applications as described in Silverpeas's * FLOSS exception. You should have received a copy of the text describing * the FLOSS exception, and it is also available here: * "http://www.silverpeas.org/legal/licensing" * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package com.silverpeas.tags.navigation; import java.rmi.RemoteException; import java.util.Collection; import java.util.Iterator; import java.util.StringTokenizer; import javax.servlet.jsp.JspException; import javax.servlet.jsp.JspWriter; import javax.servlet.jsp.tagext.TagSupport; import org.apache.commons.lang.StringEscapeUtils; import com.silverpeas.tags.kmelia.KmeliaTagUtil; import com.silverpeas.tags.navigation.links.LinkGeneratorFactory; import com.stratelia.webactiv.util.node.model.NodeDetail; import com.stratelia.webactiv.util.publication.model.PublicationDetail; /** * Tag permettant de gnrer un fil d'ariane partir d'une position donne. * @author svuillet */ public class FilArianeTag extends TagSupport { private static final long serialVersionUID = -8729790317427902342L; private KmeliaTagUtil themetracker = null; private String idsTopicsRoots; private String idCurrentTopic; private String separator; private String pageNumber; private boolean displayPubName = false; private boolean linkOnCurrentTopic = false; private String classNamesHierarchy = null; private String prefixIdHierarchyByIdTopicRoot = null; /** * Noms des classes CSS (spars par des virgules) appliquer chaque niveau de l'arborescence. * Si le nombre de classes CSS est infrieur la profondeur de l'arborescence, alors la dernires * classes CSS est applique au niveau infrieurs. * @param classNamesHierarchy */ public void setClassNamesHierarchy(String classNamesHierarchy) { this.classNamesHierarchy = classNamesHierarchy; } /** * Syntaxe : rootID1[prefix1,prefix2];rootID2[prefix3, prefix4] * @param prefixIdHierarchyByIdTopicRoot */ public void setPrefixIdHierarchyByIdTopicRoot(String prefixIdHierarchyByIdTopicRoot) { this.prefixIdHierarchyByIdTopicRoot = prefixIdHierarchyByIdTopicRoot; } /** * Source de donnes. * @param tt */ public void setThemetracker(String tt) { int scope = pageContext.getAttributesScope(tt); themetracker = (KmeliaTagUtil) pageContext.getAttribute(tt, scope); } /** * Point d'arrt du parcours de l'arborescence (plusieurs alternatives sont possibles, les sparer * pas ","). * @param idsTopicsRoots */ public void setIdsTopicsRoots(String idsTopicsRoots) { this.idsTopicsRoots = idsTopicsRoots; } /** * Point de dmarrage du parcours de l'arborescence. * @param idCurrentTopic */ public void setIdCurrentTopic(String idCurrentTopic) { this.idCurrentTopic = idCurrentTopic; } public void setSeparator(String separator) { this.separator = separator; } public void setPageNumber(String pageNumber) { this.pageNumber = pageNumber; } public void setDisplayPubName(String displayPubName) { this.displayPubName = Boolean.parseBoolean(displayPubName); } public void setLinkOnCurrentTopic(String linkOnCurrentTopic) { this.linkOnCurrentTopic = Boolean.parseBoolean(linkOnCurrentTopic); } @Override public int doStartTag() throws JspException { try { JspWriter out = pageContext.getOut(); NodeDetail current = themetracker.getTopic(idCurrentTopic); String path = generateBreadcrumb(current); out.println(path); } catch (Exception e) { e.printStackTrace(); } return SKIP_BODY; } /** * Construction du fil d'ariane. * @param node * @return * @throws RemoteException */ private String generateBreadcrumb(NodeDetail node) throws RemoteException { StringBuffer path = new StringBuffer(); StringTokenizer nodes = new StringTokenizer(node.getPath(), "/"); boolean beginPath = false; int level = 0; while (nodes.hasMoreTokens()) { String nodeId = nodes.nextToken(); if (beginPath) { NodeDetail n = themetracker.getTopic(nodeId); writeLink(n, path, level); path.append(separator); level++; } else { beginPath = isRootTopic(nodeId); } } if (linkOnCurrentTopic) { if (beginPath) { writeLink(node, path, level); } } else { if (beginPath) path.append(transformLabel(node.getName())); } if (displayPubName) { @SuppressWarnings("rawtypes") Collection pubs = themetracker.getPublicationsByTopic(String.valueOf(node.getId() + ",order,asc")); @SuppressWarnings("rawtypes") Iterator iPubs = pubs.iterator(); int i = 1; while (iPubs.hasNext()) { PublicationDetail pub = (PublicationDetail) iPubs.next(); if (pageNumber == null || (pageNumber != null && Integer.parseInt(pageNumber) == i)) { if (beginPath) path.append(separator); path.append(transformLabel(pub.getName())); } i++; } } return path.toString(); } /** * Gnration du lien html. * @param node * @param path * @param level * @throws RemoteException */ private void writeLink(NodeDetail node, StringBuffer path, int level) throws RemoteException { path.append("<a href='"); path.append(generateFullSemanticPath(node)); path.append("' title='"); path.append(StringEscapeUtils.escapeHtml(node.getDescription())); path.append("' class='"); path.append(getCssClass(level)); path.append("'>"); path.append(transformLabel(node.getName())); path.append("</a>"); } /** * Rcupre la classe css du niveau hierarchique. * @param level * @return */ private String getCssClass(int level) { if (classNamesHierarchy != null) { StringTokenizer classes = new StringTokenizer(classNamesHierarchy, ","); int i = 0; while (classes.hasMoreTokens()) { String classe = classes.nextToken(); if (level == i) return classe; i++; } } return ""; } /** * Construction de l'url de l'item. * @param node * @return * @throws RemoteException */ private String generateFullSemanticPath(NodeDetail node) throws RemoteException { try { // TODO use prefix id return LinkGeneratorFactory.getInstance().newLinkGenerator().generateFullSemanticPath(pageContext, themetracker, node, idsTopicsRoots, null, getPrefixIdByLevelAndRoot(node)); } catch (Exception e) { throw new RemoteException("", e); } } private String getPrefixIdByLevelAndRoot(NodeDetail node) throws Exception { if (prefixIdHierarchyByIdTopicRoot != null) { // recherche de la racine du topic StringTokenizer nodes = new StringTokenizer(node.getPath(), "/"); String rootId = null; while (nodes.hasMoreTokens()) { String nodeId = nodes.nextToken(); if (isRootTopic(nodeId)) { rootId = nodeId; } } if (rootId != null) { // selection des prefixes du root StringTokenizer tokenizer = new StringTokenizer(prefixIdHierarchyByIdTopicRoot, ";"); String token = null; while (tokenizer.hasMoreTokens()) { token = tokenizer.nextToken(); if (token.startsWith(rootId + "[")) { int rootLevel = themetracker.getTopic(String.valueOf(rootId)).getLevel(); int level = node.getLevel() - rootLevel; // recherche du prefixe StringTokenizer tokenizerPrefix = new StringTokenizer( token.substring(token.indexOf("[") + 1, token.indexOf("]")), ","); int l = 1; String prefix = null; while (tokenizerPrefix.hasMoreTokens()) { prefix = tokenizerPrefix.nextToken(); if (level == l) { return prefix; } l++; } } } } else { return null; } } return null; } /** * Vrifie que un theme est un theme racine. * @param nodeId * @return */ private boolean isRootTopic(String nodeId) { StringTokenizer rootNodes = new StringTokenizer(idsTopicsRoots, ","); while (rootNodes.hasMoreTokens()) { String rootNodeId = rootNodes.nextToken(); if (rootNodeId.equals(nodeId)) { return true; } } return false; } /** * Suppression des caractres ne pas afficher. * @param label * @return */ private String transformLabel(String label) { label = label.replaceAll("\\<.*?>", ""); label = StringEscapeUtils.escapeHtml(label); return label; } }