KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > outerj > daisy > books > publisher > impl > bookmodel > BookBuilder


1 /*
2  * Copyright 2004 Outerthought bvba and Schaubroeck nv
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 package org.outerj.daisy.books.publisher.impl.bookmodel;
17
18 import org.outerx.daisy.x10Bookdef.BookDocument;
19 import org.outerx.daisy.x10Bookdef.SectionDocument;
20 import org.outerx.daisy.x10Bookdef.QueryDocument;
21 import org.outerx.daisy.x10Bookdef.ImportNavigationTreeDocument;
22 import org.apache.xmlbeans.XmlObject;
23 import org.apache.xmlbeans.XmlOptions;
24 import org.outerj.daisy.repository.Repository;
25 import org.outerj.daisy.repository.VariantKey;
26 import org.outerj.daisy.repository.variant.VariantManager;
27 import org.outerj.daisy.navigation.NavigationManager;
28 import org.outerj.daisy.navigation.NavigationParams;
29 import org.outerj.daisy.xmlutil.LocalSAXParserFactory;
30 import org.xml.sax.Attributes JavaDoc;
31 import org.xml.sax.SAXException JavaDoc;
32 import org.xml.sax.helpers.DefaultHandler JavaDoc;
33
34 import java.io.InputStream JavaDoc;
35 import java.util.*;
36
37 public class BookBuilder {
38     private Repository repository;
39     private VariantManager variantManager;
40     private boolean used = false;
41     private Book book;
42     private long bookBranchId;
43     private long bookLanguageId;
44
45     public BookBuilder(Repository repository, long bookBranchId, long bookLanguageId) {
46         this.repository = repository;
47         this.variantManager = repository.getVariantManager();
48         this.bookBranchId = bookBranchId;
49         this.bookLanguageId = bookLanguageId;
50     }
51
52     /**
53      * Note: input stream must be closed by the caller.
54      */

55     public Book buildBook(InputStream JavaDoc is) throws Exception JavaDoc {
56         if (used)
57             throw new Exception JavaDoc("A BookBuilder can only be used once");
58         used = true;
59
60         book = new Book();
61         XmlOptions xmlOptions = new XmlOptions().setLoadUseXMLReader(LocalSAXParserFactory.newXmlReader());
62         BookDocument bookDocument = BookDocument.Factory.parse(is, xmlOptions);
63         XmlObject[] contentNodes = bookDocument.getBook().getContent().selectPath("*");
64         buildSections(book, contentNodes);
65         return book;
66     }
67
68     private void buildSections(SectionContainer sectionContainer, XmlObject[] nodes) throws Exception JavaDoc {
69         for (int i = 0; i < nodes.length; i++) {
70             if (nodes[i] instanceof QueryDocument.Query) {
71                 processQuery(sectionContainer, (QueryDocument.Query)nodes[i]);
72             } else if (nodes[i] instanceof ImportNavigationTreeDocument.ImportNavigationTree) {
73                 processImportNavigationTree(sectionContainer, (ImportNavigationTreeDocument.ImportNavigationTree)nodes[i]);
74             } else if (nodes[i] instanceof SectionDocument.Section) {
75                 SectionDocument.Section sectionXml = (SectionDocument.Section)nodes[i];
76                 Section section = new Section();
77
78                 if (sectionXml.isSetDocumentId())
79                     section.setDocumentId(sectionXml.getDocumentId());
80                 if (sectionXml.isSetBranch())
81                     section.setBranchId(variantManager.getBranch(sectionXml.getBranch(), false).getId());
82                 if (sectionXml.isSetLanguage())
83                     section.setLanguageId(variantManager.getLanguage(sectionXml.getLanguage(), false).getId());
84                 section.setVersion(sectionXml.getVersion());
85                 section.setTitle(sectionXml.getTitle());
86                 section.setType(sectionXml.getType());
87                 section.setBookStorePath(sectionXml.getBookStorePath());
88
89                 // recursively build child section
90
XmlObject[] childNodes = sectionXml.selectPath("*");
91                 buildSections(section, childNodes);
92
93                 sectionContainer.addSection(section);
94             } else {
95                 XmlOptions xmlOptions = new XmlOptions();
96                 xmlOptions.setSaveOuter();
97                 throw new Exception JavaDoc("Invalid node encountered in book definition: " + nodes[i].xmlText(xmlOptions));
98             }
99
100         }
101     }
102
103     private void processQuery(SectionContainer sectionContainer, QueryDocument.Query queryNode) throws Exception JavaDoc {
104         String JavaDoc query = queryNode.getQ();
105         String JavaDoc sectionType = queryNode.getSectionType();
106         VariantKey[] queryResult;
107
108         if (!queryNode.isSetFilterVariants() /* missing attribute means true */ || queryNode.getFilterVariants()) {
109             String JavaDoc extraCond = "branchId = " + bookBranchId + " and languageId = " + bookLanguageId;
110             queryResult = repository.getQueryManager().performQueryReturnKeys(query, extraCond, Locale.US);
111         } else {
112             queryResult = repository.getQueryManager().performQueryReturnKeys(query, Locale.US);
113         }
114
115         for (int i = 0; i < queryResult.length; i++) {
116             VariantKey variantKey = queryResult[i];
117             Section section = new Section();
118             section.setDocumentId(variantKey.getDocumentId());
119             section.setBranchId(variantKey.getBranchId());
120             section.setLanguageId(variantKey.getLanguageId());
121             section.setType(sectionType); // could be null, doesn't matter
122
sectionContainer.addSection(section);
123         }
124     }
125
126     private void processImportNavigationTree(SectionContainer sectionContainer, ImportNavigationTreeDocument.ImportNavigationTree importNavTreeNode) throws Exception JavaDoc {
127         NavigationManager navigationManager = (NavigationManager)repository.getExtension("NavigationManager");
128         long navigationDocId = importNavTreeNode.getId();
129         long branchId = bookBranchId;
130         long languageId = bookLanguageId;
131
132         if (importNavTreeNode.isSetBranch())
133             branchId = variantManager.getBranch(importNavTreeNode.getBranch(), false).getId();
134
135         if (importNavTreeNode.isSetLanguage())
136             languageId = variantManager.getLanguage(importNavTreeNode.getLanguage(), false).getId();
137
138         NavigationParams navigationParams = new NavigationParams(new VariantKey(navigationDocId, branchId, languageId), null, false);
139         navigationManager.generateNavigationTree(new Navigation2BookHandler(importNavTreeNode.getPath(), sectionContainer), navigationParams, null, false);
140     }
141
142     static class Navigation2BookHandler extends DefaultHandler JavaDoc {
143         private String JavaDoc[] path;
144         private boolean[] pathMatches;
145         private int nesting = -1;
146         private boolean inSubtree;
147         private Stack parents = new Stack();
148         private static final String JavaDoc NAVIGATION_NS = "http://outerx.org/daisy/1.0#navigation";
149
150         public Navigation2BookHandler(String JavaDoc pathSpec, SectionContainer sectionContainer) {
151             if (pathSpec == null) {
152                 inSubtree = true;
153                 path = new String JavaDoc[0];
154             } else {
155                 List pathList = new ArrayList();
156                 StringTokenizer tokenizer = new StringTokenizer(pathSpec, "/");
157                 while (tokenizer.hasMoreTokens()) {
158                     String JavaDoc token = tokenizer.nextToken().trim();
159                     if (token.length() != 0)
160                         pathList.add(token);
161                 }
162                 path = (String JavaDoc[])pathList.toArray(new String JavaDoc[pathList.size()]);
163                 pathMatches = new boolean[path.length];
164             }
165             parents.push(sectionContainer);
166         }
167
168         public void startElement(String JavaDoc uri, String JavaDoc localName, String JavaDoc qName, Attributes JavaDoc attributes) throws SAXException JavaDoc {
169             if (uri.equals(NAVIGATION_NS)) {
170                 if (localName.equals("doc") || localName.equals("group")) {
171                     nesting++;
172                     String JavaDoc nodeId = attributes.getValue("id");
173                     if (!inSubtree && nodeId != null && nesting < path.length && path[nesting].equals(nodeId)
174                             && previousLevelsMatch(nesting)) {
175                         pathMatches[nesting] = true;
176                         if (nesting == path.length - 1)
177                             inSubtree = true;
178                     }
179
180                     if (inSubtree) {
181                         if (localName.equals("doc")) {
182                             Section section = new Section();
183                             section.setDocumentId(Long.parseLong(attributes.getValue("documentId")));
184                             section.setBranchId(Long.parseLong(attributes.getValue("branchId")));
185                             section.setLanguageId(Long.parseLong(attributes.getValue("languageId")));
186                             ((SectionContainer)parents.peek()).addSection(section);
187                             parents.push(section);
188                         } else if (localName.equals("group") && nesting >= path.length) {
189                             // the condition "nesting > path.length" is to only import the children of the group node
190
String JavaDoc title = attributes.getValue("label");
191                             Section section = new Section();
192                             section.setTitle(title);
193                             ((SectionContainer)parents.peek()).addSection(section);
194                             parents.push(section);
195                         }
196                     }
197                 }
198             }
199         }
200
201         public void endElement(String JavaDoc uri, String JavaDoc localName, String JavaDoc qName) throws SAXException JavaDoc {
202             if (uri.equals(NAVIGATION_NS)) {
203                 if (localName.equals("doc") || localName.equals("group")) {
204                     if (inSubtree && !(localName.equals("group") && nesting == path.length - 1))
205                         parents.pop();
206                     if (inSubtree && nesting == path.length - 1)
207                         inSubtree = false;
208                     if (nesting < path.length)
209                         pathMatches[nesting] = false;
210                     nesting--;
211                 }
212             }
213         }
214
215         private boolean previousLevelsMatch(int level) {
216             for (int i = 0; i < level; i++) {
217                 if (!pathMatches[i])
218                     return false;
219             }
220             return true;
221         }
222     }
223 }
224
Popular Tags