/*
* org.xmlsmartdoc.goldenport
* Copyright (C) 2000-2004 ASAMI, Tomoharu (asami@relaxer.org)
*/
package org.xmlsmartdoc.goldenport.adapters;
import java.io.IOException;
import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.List;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.xml.sax.SAXException;
import org.xmlsmartdoc.goldenport.adapter.AbstractAdapter;
import org.xmlsmartdoc.goldenport.engine.GoldenportException;
import org.xmlsmartdoc.goldenport.engine.PortContext;
import org.xmlsmartdoc.goldenport.engine.PortNodeList;
import com.AsamiOffice.util.UArray;
import com.AsamiOffice.xml.UDOM;
/**
* SmartDocAdapter
*
* @since Apr. 13, 2004
* @version Jul. 6, 2004
* @author ASAMI, Tomoharu (asami@relaxer.org)
*/
public class SmartDocAdapter extends AbstractAdapter {
public static final String SMARTDOC_NS = "http://www.xmlsmartdoc.org/xmlns/smartdoc";
public static final String PROPERTY_ADJUST_IDS = "adjust-ids";
public SmartDocAdapter() {
}
public void endElement(
Element element,
PortNodeList halfResult,
PortContext context,
PortNodeList result
) throws GoldenportException {
super.endElement(element, halfResult, context, result);
String ns = element.getNamespaceURI();
String localName = element.getLocalName();
if ("pre".equals(localName) ||
"program".equals(localName) ||
"console".equals(localName) ||
"native".equals(localName)) {
adjustLink_(element, context, result);
} else {
importSdoc_(element, context, result);
}
}
private void adjustLink_(
Element element,
PortContext context,
PortNodeList result
) throws GoldenportException {
Attr attr = element.getAttributeNode("src");
if (attr != null) {
try {
String uri = attr.getNodeValue();
uri = context.getAdjustedUri(uri);
result.setAttribute("src", uri);
} catch (MalformedURLException e) {
throw (new GoldenportException(e));
} finally {
}
}
}
private void importSdoc_(
Element element,
PortContext context,
PortNodeList result
) throws GoldenportException {
Attr attr = element.getAttributeNode("src");
if (attr != null) {
try {
String uri = attr.getNodeValue();
if (!uri.endsWith(".sdoc")) {
adjustLink_(element, context, result);
return;
}
Document doc = context.loadDocument(uri);
Element root = doc.getDocumentElement();
Element[] goldenport = UDOM.getElements(root, PORT_NS, "goldenport");
Element[] oldGoldenport = UDOM.getElements(root, "http://www.relaxer.org/xmlns/goldenport", "macro");
Element[] heads = UDOM.getElements(root, "head");
Element[] titles = getLocaledTitles_(heads);
Element body = UDOM.getFirstElement(root, "body");
PortContext newContext = new PortContext(context);
newContext.setBaseUri(uri);
if (isAdjustIds_()) {
adjustIds_(body, newContext);
}
insertElements_(body, goldenport);
insertElements_(body, oldGoldenport);
Node evaluated = context.getEngine().executeAdapters(body, newContext);
result.addChildren(titles);
result.addChildren(evaluated);
result.removeAttribute("src");
} catch (SAXException e) {
throw (new GoldenportException(e));
} catch (IOException e) {
throw (new GoldenportException(e));
}
}
}
private boolean isAdjustIds_() {
return (getBooleanProperty(PROPERTY_ADJUST_IDS, true));
}
private Element[] getLocaledTitles_(Element[] heads) {
List list = new ArrayList();
for (int i = 0;i < heads.length;i++) {
getLocaledTitles_(heads[i], list);
}
Element[] result = new Element[list.size()];
return ((Element[])list.toArray(result));
}
private void getLocaledTitles_(Element head, List list) {
Attr locale = head.getAttributeNode("locale");
Element[] titles = UDOM.getElements(head, "title");
if (locale != null) {
String value = locale.getNodeValue();
for (int i = 0;i < titles.length;i++) {
Element title = titles[i];
Attr titleLocale = title.getAttributeNode("locale");
if (titleLocale == null) {
title.setAttribute("locale", value);
}
list.add(title);
}
} else {
UArray.addAll(list, titles);
}
}
private void insertElements_(Element body, Element[] children) {
Element first = UDOM.getFirstElement(body);
for (int i = 0;i < children.length;i++) {
body.insertBefore(children[i], first);
}
}
private void adjustIds_(Element element, PortContext newContext) {
if ("true".equals(element.getAttribute("id.absolute"))) {
return;
}
Attr attr = element.getAttributeNode("id");
if (attr != null) {
attr.setNodeValue(newContext.getAdjustedId(attr.getNodeValue()));
}
attr = element.getAttributeNode("idref");
if (attr != null) {
attr.setNodeValue(newContext.getAdjustedId(attr.getNodeValue()));
}
attr = element.getAttributeNode("href");
if (attr != null) {
String value = attr.getNodeValue();
if (value.startsWith("#")) {
value = value.substring(1);
attr.setNodeValue("#" + newContext.getAdjustedId(value));
}
}
Element[] children = UDOM.getElements(element);
for (int i = 0;i < children.length;i++) {
adjustIds_(children[i], newContext);
}
}
}