001: /*
002: * Copyright 2004 Outerthought bvba and Schaubroeck nv
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: * WITHOUT 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: package org.outerj.daisy.navigation.impl;
017:
018: import org.outerj.daisy.navigation.NavigationVersionMode;
019: import org.outerj.daisy.navigation.NavigationException;
020: import org.outerj.daisy.repository.*;
021: import org.xml.sax.ContentHandler;
022: import org.xml.sax.SAXException;
023: import org.xml.sax.helpers.AttributesImpl;
024:
025: import java.util.Map;
026:
027: /**
028: * Link to an (external) URL.
029: */
030: public class LinkNode extends AbstractParentNode {
031: private String url;
032: private String label;
033: private String id;
034: /** link node will be hidden if no read access to this document */
035: private VariantKey aclVariantKey;
036: private boolean aclDocExists;
037: private CommonNavigationManager.Context context;
038: private NavigationVersionMode versionMode;
039:
040: public LinkNode(String id, String url, String label,
041: VariantKey aclVariantKey,
042: NavigationVersionMode versionMode,
043: CommonNavigationManager.Context context)
044: throws NavigationException {
045: this .id = id;
046: this .url = url;
047: this .label = label;
048: this .aclVariantKey = aclVariantKey;
049: this .versionMode = versionMode;
050: this .context = context;
051:
052: checkAclDocExists();
053: }
054:
055: public boolean checkId(String id, long branchId, long languageId) {
056: return this .id.equals(id);
057: }
058:
059: public void populateNodeLookupMap(Map<VariantKey, String> map,
060: String path) throws RepositoryException {
061: path = path + "/" + id;
062: super .populateNodeLookupMap(map, path);
063: }
064:
065: public boolean generateXml(ContentHandler contentHandler,
066: Node[] activeNodePath, int pos, int depth, String path,
067: long userId, long[] roleIds,
068: NavigationValueFormatter valueFormatter,
069: boolean addChildCounts) throws RepositoryException,
070: SAXException {
071:
072: if (!isVisible(userId, roleIds, activeNodePath, pos))
073: return false;
074:
075: path = path + "/" + id;
076: AttributesImpl attrs = new AttributesImpl();
077: attrs.addAttribute("", "label", "label", "CDATA", label);
078: attrs.addAttribute("", "id", "id", "CDATA", id);
079: attrs.addAttribute("", "path", "path", "CDATA", path);
080: attrs.addAttribute("", "url", "url", "CDATA", url);
081: if (activeNodePath != null) {
082: if (pos < activeNodePath.length
083: && activeNodePath[pos] == this )
084: attrs.addAttribute("", "selected", "selected", "CDATA",
085: "true");
086: if (pos == activeNodePath.length - 1
087: && activeNodePath[pos] == this )
088: attrs.addAttribute("", "active", "active", "CDATA",
089: "true");
090: }
091:
092: if (addChildCounts) {
093: addChildCountAttrs(attrs, userId, roleIds, activeNodePath,
094: pos);
095: }
096:
097: contentHandler.startElement(NAVIGATION_NS, "link", "link",
098: attrs);
099: generateChildXml(contentHandler, activeNodePath, pos + 1,
100: depth, path, userId, roleIds, valueFormatter,
101: addChildCounts);
102: contentHandler.endElement(NAVIGATION_NS, "link", "link");
103:
104: return true;
105: }
106:
107: public boolean isIdentifiable() {
108: return true;
109: }
110:
111: public String getId() {
112: return id;
113: }
114:
115: public boolean isVisible(long userId, long[] roleId,
116: Node[] activeNodePath, int activeNodePathPos)
117: throws RepositoryException {
118: return exists(userId, roleId, activeNodePath, activeNodePathPos);
119: }
120:
121: public boolean exists(long userId, long[] roleIds,
122: Node[] activeNodePath, int activeNodePathPos)
123: throws RepositoryException {
124: if (aclVariantKey == null)
125: return true;
126: else if (!aclDocExists)
127: return false;
128: else if (versionMode == NavigationVersionMode.LIVE)
129: return context.canRead(aclVariantKey, userId, roleIds);
130: else
131: return context.canReadNonLive(aclVariantKey, userId,
132: roleIds);
133: }
134:
135: public boolean[] getVisibleAndExists(long userId, long[] roleIds,
136: Node[] activeNodePath, int activeNodePathPos)
137: throws RepositoryException {
138: boolean exists = exists(userId, roleIds, activeNodePath,
139: activeNodePathPos);
140: return new boolean[] { exists, exists };
141: }
142:
143: public Object getLabel() {
144: return label;
145: }
146:
147: public ValueType getLabelValueType() {
148: return ValueType.STRING;
149: }
150:
151: public QueryParams getQueryParams() {
152: return null;
153: }
154:
155: public Object getResolvedLabel() {
156: return label;
157: }
158:
159: private void checkAclDocExists() throws NavigationException {
160: if (aclVariantKey == null)
161: return;
162:
163: try {
164: context.getRepository().getDocument(aclVariantKey, false);
165: this .aclDocExists = true;
166: } catch (Exception e) {
167: if (e instanceof DocumentNotFoundException
168: || e instanceof DocumentVariantNotFoundException) {
169: aclDocExists = true;
170: context.getLogger().warn(
171: "A navigation tree link-node references the non-existing "
172: + aclVariantKey);
173: } else {
174: throw new NavigationException(
175: "Error retrieving info for " + aclVariantKey, e);
176: }
177: }
178: }
179: }
|