/**
* Copyright (c) 2009 Juwi MacMillan Group GmbH
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package de.juwimm.cms.content;
import java.io.StringReader;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.apache.log4j.Logger;
import org.tizzit.util.XercesHelper;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.xml.sax.Attributes;
import org.xml.sax.ErrorHandler;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.helpers.DefaultHandler;
import de.juwimm.cms.content.modules.AbstractModule;
import de.juwimm.cms.content.modules.Module;
import de.juwimm.cms.content.modules.ModuleFactory;
/**
* <p>Title: </p>
* <p>Description: </p>
* <p>Copyright: Copyright (c) 2002</p>
* <p>Company: </p>
* @author <a href="mailto:s.kulawik@juwimm.com">Sascha-Matthias Kulawik</a>
* @version $Id$
*/
public class GetContentHandler extends DefaultHandler implements ErrorHandler {
private static Logger log = Logger.getLogger(GetContentHandler.class);
private StringBuffer content;
private String lastStartElement = "";
private boolean startOrEnd = false;
private String imInsideThisDCFElement = "";
private boolean imInsideTitle = false;
private boolean titleAlreadyWritten = false;
private String dcfname = "";
private ModuleFactory mf;
private String gcontent = "";
private String title = "";
private boolean doNotCallModule = false;
private boolean imInsideDCFInitial = false;
private boolean imInsideIterationElements = false;
public GetContentHandler(ModuleFactory moduleFactory, String strTitle) {
super();
doNotCallModule = false;
this.mf = moduleFactory;
this.title = strTitle;
}
/**
* This Constructor does NOT call a module for properties!<br>
* It is only used for creating an empty content out of a DCF for saving the first time.
* @param strTitle Title to be parsed inside the document
*/
public GetContentHandler(String strTitle) {
super();
doNotCallModule = true;
this.title = AbstractModule.getURLEncoded(strTitle);
}
@Override
public void startDocument() {
if (log.isDebugEnabled()) log.debug("Start document");
content = new StringBuffer();
startOrEnd = false;
gcontent = "";
}
@Override
public void startElement(String uri, String na2me, String qName, Attributes atts) {
if (imInsideThisDCFElement.equals("") || imInsideDCFInitial) {
if (qName.equals("title")) {
imInsideTitle = true;
}
String attributes = "";
for (int i = 0; i < atts.getLength(); i++) {
attributes += " " + atts.getQName(i) + "=\"" + XercesHelper.getHexEncoded(atts.getValue(i)) + "\"";
if (atts.getQName(i).equals("dcfname") && imInsideThisDCFElement.equals("")) {
imInsideThisDCFElement = qName;
dcfname = atts.getValue(i);
}
}
lastStartElement = qName;
if (startOrEnd) content.append(">");
// --- URI ---
content.append("<");
if (!uri.equalsIgnoreCase("")) {
content.append(uri).append(':');
}
content.append(qName).append(attributes);
// --- URI ---
startOrEnd = true;
} else if (doNotCallModule && !imInsideDCFInitial && !imInsideIterationElements && qName.equals("dcfInitial")) {
startOrEnd = true;
imInsideDCFInitial = true;
} else if (!imInsideIterationElements && qName.equals("iterationElements")) {
imInsideIterationElements = true;
if (log.isDebugEnabled()) log.debug("SET ITERATION ELEMENTS");
}
}
@Override
public void characters(char[] ch, int start, int length) {
if (imInsideThisDCFElement.equals("") || imInsideDCFInitial) {
if (imInsideTitle && !titleAlreadyWritten) {
content.append("><![CDATA[" + title + "]]>");
lastStartElement = "";
titleAlreadyWritten = true;
startOrEnd = true;
} else {
StringBuffer tmp = new StringBuffer();
for (int i = start; i < start + length; i++) {
tmp.append(ch[i]);
}
if (startOrEnd) {
content.append(">");
}
content.append(XercesHelper.getHexEncoded(tmp.toString()));
lastStartElement = "";
startOrEnd = false;
}
}
}
@Override
public void endElement(String uri, String na2me, String qName) throws SAXException {
if (imInsideThisDCFElement.equals("") || (imInsideDCFInitial && !qName.equals("dcfInitial"))) {
if (lastStartElement.equals(qName)) {
content.append("/>\n");
} else {
// --- URI ---
content.append("</");
if (!uri.equalsIgnoreCase("")) {
content.append(uri).append(':');
}
content.append(qName).append(">\n");
// --- URI ---
}
} else if (imInsideThisDCFElement.equals(qName)) {
imInsideThisDCFElement = "";
if (!doNotCallModule) {
Module module = mf.getModuleByDCFName(dcfname);
Node node = module.getProperties();
String validationError = module.getValidationError();
if (!validationError.equalsIgnoreCase("")) {
throw new SAXException(validationError);
}
String nde = "";
if (node != null) nde = XercesHelper.nodeList2string(node.getChildNodes());
if (log.isDebugEnabled()) log.debug("Added in endElement: " + nde);
// --- URI ---
content.append(">").append(nde).append("</");
if (!uri.equalsIgnoreCase("")) {
content.append(uri).append(':');
}
content.append(qName).append(">\n");
// --- URI ---
} else {
if (lastStartElement.equals(qName)) content.append(">");
// --- URI ---
content.append("</");
if (!uri.equalsIgnoreCase("")) {
content.append(uri).append(':');
}
content.append(qName).append(">\n");
// --- URI ---
}
dcfname = "";
} else if (imInsideDCFInitial && qName.equals("dcfInitial")) {
imInsideDCFInitial = false;
} else if (imInsideIterationElements && qName.equals("iterationElements")) {
imInsideIterationElements = false;
if (log.isDebugEnabled()) log.debug("GOT OUT OF ITERATION ELEMENTS");
}
if (qName.equals("title")) imInsideTitle = false;
startOrEnd = false;
}
@Override
public void endDocument() {
if (log.isDebugEnabled()) log.debug("End document ");
gcontent = content.toString();
}
public String getContent() throws Exception {
validateContent(gcontent);
return gcontent;
}
public static void validateContent(String cnt) throws Exception {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setValidating(true);
dbf.setNamespaceAware(false);
DocumentBuilder docBuilder = dbf.newDocumentBuilder();
docBuilder.setErrorHandler(new ValidationErrorHandler());
String xmlGrammar = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
String document = xmlGrammar + cnt;
if (log.isDebugEnabled()) log.debug("Content to VALIDATE: " + document);
InputSource in = new InputSource(new StringReader(document));
Document doc = docBuilder.parse(in);
if (log.isDebugEnabled()) {
if (doc == null) {
if (log.isDebugEnabled()) log.debug("DOC IS NULL");
} else {
if (log.isDebugEnabled()) log.debug("ALLES QL");
}
}
}
/**
* @author <a href="sascha.kulawik@juwimm.com">Sascha-Matthias Kulawik</a>
* @version $Id$
*/
private static class ValidationErrorHandler implements ErrorHandler {
public void warning(SAXParseException exception) throws SAXException {
//log.debug("ValidationErrorHandler warning " + exception.getMessage());
}
public void error(SAXParseException exception) throws SAXException {
//log.debug("ValidationErrorHandler error " + exception.getMessage());
}
public void fatalError(SAXParseException exception) throws SAXException {
if (log.isDebugEnabled()) log.debug("ValidationErrorHandler fatalError ", exception);
}
}
}