1 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 ; 31 import org.xml.sax.SAXException ; 32 import org.xml.sax.helpers.DefaultHandler ; 33 34 import java.io.InputStream ; 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 55 public Book buildBook(InputStream is) throws Exception { 56 if (used) 57 throw new Exception ("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 { 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 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 ("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 { 104 String query = queryNode.getQ(); 105 String sectionType = queryNode.getSectionType(); 106 VariantKey[] queryResult; 107 108 if (!queryNode.isSetFilterVariants() || queryNode.getFilterVariants()) { 109 String 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); sectionContainer.addSection(section); 123 } 124 } 125 126 private void processImportNavigationTree(SectionContainer sectionContainer, ImportNavigationTreeDocument.ImportNavigationTree importNavTreeNode) throws Exception { 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 { 143 private String [] 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 NAVIGATION_NS = "http://outerx.org/daisy/1.0#navigation"; 149 150 public Navigation2BookHandler(String pathSpec, SectionContainer sectionContainer) { 151 if (pathSpec == null) { 152 inSubtree = true; 153 path = new String [0]; 154 } else { 155 List pathList = new ArrayList(); 156 StringTokenizer tokenizer = new StringTokenizer(pathSpec, "/"); 157 while (tokenizer.hasMoreTokens()) { 158 String token = tokenizer.nextToken().trim(); 159 if (token.length() != 0) 160 pathList.add(token); 161 } 162 path = (String [])pathList.toArray(new String [pathList.size()]); 163 pathMatches = new boolean[path.length]; 164 } 165 parents.push(sectionContainer); 166 } 167 168 public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { 169 if (uri.equals(NAVIGATION_NS)) { 170 if (localName.equals("doc") || localName.equals("group")) { 171 nesting++; 172 String 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 String 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 uri, String localName, String qName) throws SAXException { 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 |