/*
* Copyright 2008 Federal Chancellery Austria and
* Graz University of Technology
*
* 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 at.gv.egiz.idlink;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamSource;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.Text;
public class IdentityLinkTransformer {
private class IdLTransformer {
/**
* Is transformer in use?
*/
private boolean inUse = false;
/**
* How often has this transformer been used?
*/
private int timesUsed = 0;
/**
* The time this transformer has been created.
*/
private long created;
/**
* When has this transformer been used the last time?
*/
private long lastTimeUsed;
/**
* Average performance in milliseconds.
*/
private long time;
/**
* Time used for initialization.
*/
private long initTime;
/**
* The stylesheet transformer.
*/
private Transformer transformer;
/**
* Stylesheet URL.
*/
private String stylesheetURL;
/**
*
* @param stylesheetURL
* @throws IOException
* @throws TransformerConfigurationException
*/
public IdLTransformer(String stylesheetURL) throws IOException, TransformerConfigurationException {
created = System.currentTimeMillis();
// TODO: implement stylesheet cache
this.stylesheetURL = stylesheetURL;
URL url = new URL(stylesheetURL);
if (!"http".equalsIgnoreCase(url.getProtocol()) && !"https".equalsIgnoreCase(url.getProtocol())) {
throw new MalformedURLException("Protocol " + url.getProtocol() + " not supported for IssuerTemplate URL.");
}
StreamSource source = new StreamSource(url.openStream());
transformer = factory.newTransformer(source);
initTime = System.currentTimeMillis() - created;
}
public void transform(Source xmlSource, Result outputTarget) throws TransformerException {
long t0 = System.currentTimeMillis();
try {
transformer.transform(xmlSource, outputTarget);
} catch (TransformerException e) {
throw e;
} finally {
inUse = false;
long t1 = System.currentTimeMillis();
time += (t1 - t0);
timesUsed++;
lastTimeUsed = System.currentTimeMillis();
}
}
/**
* @return true
if this transformer is in use, or false
otherwise
*/
public boolean isInUse() {
return inUse;
}
@Override
public String toString() {
StringBuffer str = new StringBuffer();
str.append("Transformer ").append(stylesheetURL)
.append("\n created ").append(new Date(created)).append(" used ").append(
timesUsed).append(" times, (init ").append(initTime).append("ms / ")
.append(((float) time) / timesUsed).append("ms avg) last time ").append(new Date(lastTimeUsed));
return str.toString();
}
}
/**
* The transfomer factory.
*/
private static TransformerFactory factory;
/**
* The instance to be returned by {@link #getInstance()}.
*/
private static IdentityLinkTransformer instance;
/**
* Returns an instance of this IdentityLinkTransfomer
.
*
* @return an instance of this IdentityLinkTransformer
*/
public static IdentityLinkTransformer getInstance() {
if (instance == null) {
instance = new IdentityLinkTransformer();
factory = TransformerFactory.newInstance();
}
return instance;
}
/**
* Sets the given domainIdentifier
on the corresponding
* node of the given idLink
.
*
This method may be used to cope with a flaw in the IssuerTemplate-Stylesheets
* used to transform a CompressedIdentitiyLink
into an
* IdentityLink
. Some IssuerTemplate-Stylesheets do not
* consider the pr:Type
element value of the
* CompressedIdentityLink
and render a pr:Type
* element value of urn:publicid:gv.at:baseid
* into the IdentityLink
structure. This method allows to
* set the pr:Type
element value on the given idLink
* after the transformation.
*
IdentityLink
element or one of it's ancestors.
* Must not be null
.
*
* @param domainIdentifier the value to be set for the pr:Type
element
*
* @throws NullPointerException if idLink
is null
.
*/
public static void setDomainIdentifier(Node idLink, String domainIdentifier) {
Element element;
if (idLink instanceof Element) {
element = (Element) idLink;
} else if (idLink instanceof Document) {
element = ((Document) idLink).getDocumentElement();
} else if (idLink != null) {
Document document = idLink.getOwnerDocument();
element = document.getDocumentElement();
} else {
throw new NullPointerException("Parameter 'idLink' must no be null.");
}
NodeList nodeList = element.getElementsByTagNameNS(
"http://reference.e-government.gv.at/namespace/persondata/20020228#",
"Type");
for (int i = 0; i < nodeList.getLength(); i++) {
if (nodeList.item(i) instanceof Element) {
Element typeElement = (Element) nodeList.item(i);
NodeList children = typeElement.getChildNodes();
for (int j = 0; j < children.getLength(); j++) {
if (children.item(j) instanceof Text) {
((Text) children.item(j)).setNodeValue(domainIdentifier);
}
}
}
}
}
/**
* The pool of Transformer
.
*/
private Map