blob: 45b3dbd853a9dd5dd3149881fd0396faab88a00a [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2007 IBM Corporation and Others
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Daisuke SATO - initial API and implementation
*******************************************************************************/
package org.eclipse.actf.ai.xmlstore.local;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.eclipse.actf.ai.xmlstore.IXMLEditableInfo;
import org.eclipse.actf.ai.xmlstore.IXMLSelector;
import org.eclipse.actf.ai.xmlstore.XMLStoreException;
import org.eclipse.actf.ai.xmlstore.spi.XMLSelectorInfo;
import org.w3c.dom.DOMImplementation;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.ContentHandler;
import org.xml.sax.SAXException;
public class UserXML extends XMLFile implements IXMLEditableInfo {
private String namespaceURI;
private String qualifiedName;
private String documentation = "User Annotation";
private String targetUriPattern;
private Pattern uriPat;
private String pageTitle;
private String authorName;
private final boolean onlyInMemory;
private int priority;
private boolean removed = false;
private static String getFileName(String targetURI) {
long time = System.currentTimeMillis();
String uri = targetURI.replaceAll("[\\/:*?\"<>|]", "-");
if (uri.length() > 200)
uri = uri.substring(0, 200);
return time + "-" + uri + ".fnc";
}
UserXML(File file) throws XMLStoreException {
super(file);
onlyInMemory = false;
targetUriPattern = getSelectorInfo().getURI();
documentation = getSelectorInfo().getDocumentation();
priority = getSelectorInfo().getPriority();
pageTitle = getSelectorInfo().getPageTitle();
authorName = getSelectorInfo().getAuthorName();
}
UserXML(String namespaceURI, String qualifiedName, String targetUriPattern, File dir) throws XMLStoreException {
// super(new File(dir, getFileName()));
super(new File(dir, getFileName(targetUriPattern)), false);
this.namespaceURI = namespaceURI;
this.qualifiedName = qualifiedName;
this.onlyInMemory = true;
try {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
DOMImplementation impl = builder.getDOMImplementation();
doc = impl.createDocument(namespaceURI, qualifiedName, null);
setTargetURIPattern(targetUriPattern);
} catch (Exception e) {
e.printStackTrace();
}
}
public String getTargetUriPattern() {
return targetUriPattern;
}
@Override
public String getDocumentation() {
return documentation;
}
@Override
public boolean isUserEntry() {
return true;
}
public String getPageTitle() {
return pageTitle;
}
public String getAuthorName() {
return authorName;
}
@Override
public int getPriority() {
return priority;
}
@Override
public Node getRootNode() throws XMLStoreException {
if (onlyInMemory)
return doc.getDocumentElement();
else
return super.getRootNode();
}
@Override
public void setContentHandler(ContentHandler h) {
if (!onlyInMemory)
super.setContentHandler(h);
}
@Override
public void startSAX() throws XMLStoreException, SAXException {
if (onlyInMemory)
throw new SAXException("not supported");
else
super.startSAX();
}
@Override
public void reset() throws XMLStoreException {
if(!onlyInMemory)
super.reset();
}
public void save() {
save(doc, this.file);
}
public void save(File file) {
save(doc, file);
}
private void save(Document doc, File file) {
try {
FileOutputStream fos = new FileOutputStream(file);
save(doc, fos);
fos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
private void save(Document doc, OutputStream stream) {
try {
//System.out.println("store into " + file.getAbsolutePath());
TransformerFactory factory = TransformerFactory.newInstance();
Transformer transformer = factory.newTransformer();
transformer.setOutputProperty("indent", "yes");
DOMSource source = new DOMSource(doc);
StreamResult result = new StreamResult(stream);
transformer.transform(source, result);
} catch (Exception e) {
e.printStackTrace();
}
}
public void setPriority(int priority) {
this.priority = priority;
resetMeta();
}
public void setDocumentation(String documentation) {
this.documentation = documentation;
resetMeta();
}
private void setTargetURIPattern(String targetUriPattern) {
this.targetUriPattern = targetUriPattern;
uriPat = Pattern.compile(quote(targetUriPattern, '*'));
resetMeta();
}
public void setPageTitle(String pageTitle) {
this.pageTitle = pageTitle;
resetMeta();
}
public void setAuthorName(String authorName) {
this.authorName = authorName;
resetMeta();
}
private void resetMeta() {
Element meta = getElement("meta", doc.getDocumentElement());
getElement("userEntry", meta);
Element target = getElement("targetSite", meta);
Element documentation = getElement("documentation", meta);
Element pageTitle = getElement("pageTitle", meta);
Element authorName = getElement("authorName", meta);
target.setAttribute("uri", getTargetUriPattern());
documentation.setTextContent(getDocumentation());
pageTitle.setTextContent(getPageTitle());
authorName.setTextContent(getAuthorName());
}
private Element getElement(String name, Node parent) {
NodeList list = doc.getElementsByTagNameNS(XMLSelectorInfo.SELECTOR_NS, name);
if (list.getLength() == 0) {
Element temp = doc.createElementNS(XMLSelectorInfo.SELECTOR_NS, name);
parent.insertBefore(temp, parent.getFirstChild());
return temp;
}
return (Element) list.item(0);
}
private String quote(String pat, char wildCardChar) {
StringBuffer r = new StringBuffer();
for (int i = 0; i < pat.length(); i++) {
char c = pat.charAt(i);
if (c == wildCardChar) {
r.append(".*");
} else if (("\\?*+.[]{}()$^".indexOf(c) >= 0)) {
r.append('\\');
r.append(c);
} else {
r.append(c);
}
}
return r.toString();
}
public boolean match(IXMLSelector selector) {
if (removed)
return false;
if (!onlyInMemory)
return super.getSelectorInfo().match(selector);
if (!matchDocumentElement(selector))
return false;
if (!matchURI(selector))
return false;
return true;
}
private boolean matchDocumentElement(IXMLSelector selector) {
if (selector.getDocumentElementName() != null) {
if (!namespaceURI.equals(selector.getDocumentElementNS()))
return false;
if (!qualifiedName.equals(selector.getDocumentElementName()))
return false;
}
return true;
}
private boolean matchURI(IXMLSelector selector) {
String uri = selector.getURI();
if (uri == null)
return true;
Matcher m = uriPat.matcher(uri);
if (m.matches())
return true;
return false;
}
public void remove() {
removed = true;
if (!file.exists())
return;
file.delete();
}
public void save(ZipOutputStream zos) {
try {
zos.putNextEntry(new ZipEntry(file.getName()));
getRootNode();
save(doc, zos);
zos.closeEntry();
} catch (IOException e) {
e.printStackTrace();
} catch (XMLStoreException e) {
e.printStackTrace();
}
}
}