1 16 package org.outerj.daisy.books.publisher.impl.publicationprocess; 17 18 import org.outerj.daisy.books.store.BookInstance; 19 import org.outerj.daisy.books.publisher.impl.BookInstanceLayout; 20 import org.outerj.daisy.books.publisher.impl.util.AbstractContentHandler; 21 import org.outerj.daisy.xmlutil.LocalSAXParserFactory; 22 import org.outerj.daisy.xmlutil.XmlSerializer; 23 import org.outerj.daisy.repository.LocaleHelper; 24 import org.xml.sax.InputSource ; 25 import org.xml.sax.ContentHandler ; 26 import org.xml.sax.Attributes ; 27 import org.xml.sax.SAXException ; 28 import org.apache.cocoon.xml.AttributesImpl; 29 30 import javax.xml.parsers.SAXParser ; 31 import java.util.Map ; 32 import java.util.HashMap ; 33 import java.io.InputStream ; 34 import java.io.OutputStream ; 35 36 42 public class CallPipelineTask implements PublicationProcessTask { 43 private final String input; 44 private final String output; 45 private final String outputPrefix; 46 private static final String NS = "http://outerx.org/daisy/1.0#bookCallPipelineTask"; 47 48 public CallPipelineTask(Map attributes) throws Exception { 49 this.input = PublicationProcessTaskUtil.getRequiredAttribute(attributes, "input", "callPipeline"); 50 this.output = PublicationProcessTaskUtil.getRequiredAttribute(attributes, "output", "callPipeline"); 51 52 if (attributes.containsKey("outputPrefix")) { 53 outputPrefix = (String )attributes.get("outputPrefix"); 54 } else { 55 outputPrefix = "after-call-pipeline/"; 56 } 57 } 58 59 public void run(PublicationContext context) throws Exception { 60 context.getPublicationLog().info("Running Call Pipeline task."); 61 BookInstance bookInstance = context.getBookInstance(); 62 String publicationOutputPath = BookInstanceLayout.getPublicationOutputPath(context.getPublicationOutputName()); 63 String startXmlLocation = publicationOutputPath + input; 64 InputStream is = null; 65 OutputStream os = null; 66 try { 67 is = bookInstance.getResource(startXmlLocation); 68 os = bookInstance.getResourceOutputStream(publicationOutputPath + output); 69 SAXParser parser = LocalSAXParserFactory.getSAXParserFactory().newSAXParser(); 70 XmlSerializer serializer = new XmlSerializer(os); 71 CallPipelineHandler callPipelineHandler = new CallPipelineHandler(serializer, context); 72 parser.getXMLReader().setContentHandler(callPipelineHandler); 73 parser.getXMLReader().parse(new InputSource (is)); 74 } finally { 75 if (is != null) 76 try { is.close(); } catch (Exception e) { } 77 if (os != null) 78 try { os.close(); } catch (Exception e) { } 79 } 80 } 81 82 class CallPipelineHandler extends AbstractContentHandler { 83 private PublicationContext context; 84 private boolean insideCallPipeline = false; 85 private String callPipelineOutput; 86 87 public CallPipelineHandler(ContentHandler consumer, PublicationContext context) { 88 super(consumer); 89 this.context = context; 90 } 91 92 public void startElement(String namespaceURI, String localName, String qName, Attributes atts) throws SAXException { 93 if (namespaceURI.equals(NS) && localName.equals("callPipeline")) { 94 if (insideCallPipeline) 95 throw new SAXException ("callPipelineTask: Nested callPipeline elements are not supported."); 96 callPipelineOutput = null; 97 98 String bookStorePath = getRequiredAttribute(atts, "bookStorePath"); 100 String outputPrefix = atts.getValue("outputPrefix"); 101 if (outputPrefix == null) 102 outputPrefix = CallPipelineTask.this.outputPrefix; 103 String outputExtension = atts.getValue("outputExtension"); 104 if (outputExtension == null) 105 outputExtension = ""; 106 String pipe = getRequiredAttribute(atts, "pipe"); 107 108 InputStream inputStream = null; 110 OutputStream outputStream = null; 111 try { 112 BookInstance bookInstance = context.getBookInstance(); 113 114 String publicationOutputPath = BookInstanceLayout.getPublicationOutputPath(context.getPublicationOutputName()); 115 callPipelineOutput = publicationOutputPath + outputPrefix + PublicationProcessTaskUtil.getFileName(bookStorePath) + outputExtension; 116 outputStream = bookInstance.getResourceOutputStream(callPipelineOutput); 117 118 inputStream = bookInstance.getResource(bookStorePath); 119 120 Map params = new HashMap (); 121 params.put("inputStream", inputStream); 122 params.put("bookInstanceName", bookInstance.getName()); 123 params.put("bookInstance", bookInstance); 124 params.put("locale", context.getLocale()); 125 params.put("pubProps", context.getProperties()); 126 params.put("bookMetadata", context.getBookMetadata()); 127 params.put("localeAsString", LocaleHelper.getString(context.getLocale())); 128 params.put("publicationTypeName", context.getPublicationTypeName()); 129 params.put("publicationOutputName", context.getPublicationOutputName()); 130 131 pipe = context.getDaisyCocoonPath() + "/books/publicationTypes/" + context.getPublicationTypeName() + "/" + pipe; 132 PublicationProcessTaskUtil.executePipeline(pipe, params, outputStream, context); 133 } catch (Exception e) { 134 throw new SAXException ("Error (preparing for) executing pipeline in callPipeline task.", e); 135 } finally { 136 if (inputStream != null) try { inputStream.close(); } catch (Exception e) { } 137 if (outputStream != null) try { outputStream.close(); } catch (Exception e) { } 138 } 139 insideCallPipeline = true; 140 } else { 141 if (insideCallPipeline && callPipelineOutput != null) 142 atts = processAttributes(atts); 143 super.startElement(namespaceURI, localName, qName, atts); 144 } 145 } 146 147 public void endElement(String namespaceURI, String localName, String qName) throws SAXException { 148 if (namespaceURI.equals(NS) && localName.equals("callPipeline")) { 149 insideCallPipeline = false; 150 } else { 152 super.endElement(namespaceURI, localName, qName); 153 } 154 } 155 156 private String getRequiredAttribute(Attributes atts, String attrName) throws SAXException { 157 String value = atts.getValue(attrName); 158 if (value == null || value.trim().length() == 0) 159 throw new SAXException ("Missing attribute on callPipeline: " + attrName); 160 return value; 161 } 162 163 private Attributes processAttributes(Attributes atts) { 164 AttributesImpl newAttrs = new AttributesImpl(atts); 165 for (int i = 0; i < newAttrs.getLength(); i++) { 166 String value = newAttrs.getValue(i); 167 value = value.replaceAll("\\{callPipelineOutput}", callPipelineOutput); 168 newAttrs.setValue(i, value); 169 } 170 return newAttrs; 171 } 172 } 173 } 174 | Popular Tags |