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.repository.*;
019: import org.outerj.daisy.repository.InvalidDocumentIdException;
020: import org.outerj.daisy.navigation.NavigationException;
021: import org.outerx.daisy.x10Bookdef.BookDocument;
022: import org.outerx.daisy.x10Bookdef.SectionDocument;
023: import org.outerx.daisy.x10Bookdef.QueryDocument;
024: import org.outerx.daisy.x10Bookdef.ImportNavigationTreeDocument;
025: import org.apache.xmlbeans.XmlObject;
026: import org.apache.xmlbeans.SchemaType;
027: import org.apache.xmlbeans.QNameSet;
028:
029: import java.util.ArrayList;
030:
031: public class BookNavigationBuilder implements
032: NavigationFactory.NavigationBuilder, NodeBuilder {
033: private CommonNavigationManager.Context context;
034:
035: public void buildTree(Node parentNode, XmlObject xmlObject,
036: BuildContext buildContext) throws RepositoryException {
037: context = buildContext.getNavContext();
038: build(parentNode, ((BookDocument) xmlObject).getBook(),
039: buildContext);
040: }
041:
042: public SchemaType getSchemaType() {
043: return BookDocument.type;
044: }
045:
046: private void build(Node parentNode, BookDocument.Book bookXml,
047: BuildContext buildContext) {
048: XmlObject[] nodesXml = bookXml.getContent().selectChildren(
049: QNameSet.ALL);
050: for (int i = 0; i < nodesXml.length; i++) {
051: build(parentNode, nodesXml[i], buildContext);
052: }
053: }
054:
055: private void build(Node parentNode,
056: SectionDocument.Section nodeXml, BuildContext buildContext) {
057: AbstractParentNode node;
058: if (nodeXml.isSetDocumentId()) {
059: long branchId = buildContext.getBranchId();
060: long languageId = buildContext.getLanguageId();
061: try {
062: if (nodeXml.isSetBranch())
063: branchId = context.getBranchId(nodeXml.getBranch());
064: if (nodeXml.isSetLanguage())
065: languageId = context.getLanguageId(nodeXml
066: .getLanguage());
067: } catch (Exception e) {
068: parentNode
069: .add(new ErrorNode("Error: " + e.getMessage()));
070: return;
071: }
072: String documentId = nodeXml.getDocumentId().trim();
073: try {
074: documentId = context.getRepository()
075: .normalizeDocumentId(documentId);
076: } catch (InvalidDocumentIdException e) {
077: parentNode.add(new ErrorNode("Invalid doc ID: "
078: + documentId));
079: return;
080: }
081: VariantKey variantKey = new VariantKey(documentId,
082: branchId, languageId);
083: node = new DocumentNode(variantKey, null, null,
084: NodeVisibility.ALWAYS, context, buildContext
085: .getBranchId(), buildContext
086: .getLanguageId(), buildContext
087: .getVersionMode());
088: } else {
089: String id = "g"
090: + buildContext
091: .getNextValue(BuildContext.CounterType.GROUP_COUNTER);
092: node = new GroupNode(id, nodeXml.getTitle(),
093: NodeVisibility.ALWAYS);
094: }
095:
096: try {
097: buildContext.pushCounters(BuildContext.getNewCounters());
098: XmlObject[] nodesXml = nodeXml.selectChildren(QNameSet.ALL);
099: for (int i = 0; i < nodesXml.length; i++) {
100: build(node, nodesXml[i], buildContext);
101: }
102: } finally {
103: buildContext.popCounters();
104: }
105:
106: parentNode.add(node);
107: }
108:
109: private void build(Node parentNode, QueryDocument.Query nodeXml,
110: BuildContext buildContext) {
111: String select = nodeXml.getQ();
112:
113: StringBuilder extraCond = null;
114: if (!nodeXml.isSetFilterVariants() /* missing attribute means true */
115: || nodeXml.getFilterVariants()) {
116: extraCond = new StringBuilder();
117: extraCond.append(" branchId = ").append(
118: buildContext.getBranchId()).append(
119: " and languageId = ").append(
120: buildContext.getLanguageId());
121: }
122:
123: XmlObject[] childNodes = nodeXml.selectChildren(QNameSet.ALL);
124: QueryTreeBuilder.buildQueryBasedTree(parentNode, select,
125: extraCond != null ? extraCond.toString() : null, -1,
126: NodeVisibility.ALWAYS,
127: new ArrayList<QueryTreeBuilder.ColumnConfig>(), this ,
128: childNodes, buildContext);
129: }
130:
131: private void build(Node parentNode,
132: ImportNavigationTreeDocument.ImportNavigationTree nodeXml,
133: BuildContext buildContext) {
134: String documentId = nodeXml.getId().trim();
135: try {
136: documentId = context.getRepository().normalizeDocumentId(
137: documentId);
138: } catch (Exception e) {
139: parentNode.add(new ErrorNode("Invalid doc ID: "
140: + documentId));
141: return;
142: }
143: long branchId = buildContext.getBranchId();
144: long languageId = buildContext.getLanguageId();
145: try {
146: if (nodeXml.isSetBranch())
147: branchId = context.getBranchId(nodeXml.getBranch());
148: if (nodeXml.isSetLanguage())
149: languageId = context.getLanguageId(nodeXml
150: .getLanguage());
151: } catch (Exception e) {
152: parentNode.add(new ErrorNode("Error: " + e.getMessage()));
153: return;
154: }
155:
156: VariantKey navigationDoc = new VariantKey(documentId, branchId,
157: languageId);
158: if (buildContext.containsImport(navigationDoc)) {
159: parentNode.add(new ErrorNode("(error: recursive import of "
160: + navigationDoc.getDocumentId() + ")"));
161: } else {
162: buildContext.pushImport(navigationDoc);
163: try {
164: NavigationFactory
165: .build(parentNode, new VariantKey(documentId,
166: branchId, languageId), buildContext);
167: } catch (NavigationException e) {
168: parentNode.add(new ErrorNode("(failed import of "
169: + navigationDoc.getDocumentId() + ")"));
170: } finally {
171: buildContext.popImport();
172: }
173: }
174: }
175:
176: public void build(Node parentNode, XmlObject object,
177: BuildContext buildContext) {
178: if (object instanceof SectionDocument.Section)
179: build(parentNode, (SectionDocument.Section) object,
180: buildContext);
181: else if (object instanceof QueryDocument.Query)
182: build(parentNode, (QueryDocument.Query) object,
183: buildContext);
184: else if (object instanceof ImportNavigationTreeDocument.ImportNavigationTree)
185: build(
186: parentNode,
187: (ImportNavigationTreeDocument.ImportNavigationTree) object,
188: buildContext);
189: else
190: throw new RuntimeException("Unexpected type: "
191: + object.getClass().getName());
192: }
193: }
|