- From: Jean-Guilhem Rouel via cvs-syncmail <cvsmail@w3.org>
- Date: Fri, 28 Aug 2009 12:40:14 +0000
- To: www-validator-cvs@w3.org
Update of /sources/public/2006/unicorn/src/org/w3c/unicorn
In directory hutz:/tmp/cvs-serv22368/src/org/w3c/unicorn
Added Files:
Framework.java UnicornCall.java Test.java
Log Message:
Merging dev2 in HEAD
--- NEW FILE: Framework.java ---
// $Id: Framework.java,v 1.2 2009/08/28 12:40:12 jean-gui Exp $
// Author: Damien LEROY.
// (c) COPYRIGHT MIT, ERCIM ant Keio, 2006.
// Please first read the full copyright statement in file COPYRIGHT.html
package org.w3c.unicorn;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Properties;
import javax.xml.namespace.NamespaceContext;
import javax.xml.parsers.ParserConfigurationException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.log4j.PropertyConfigurator;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;
import org.apache.velocity.app.VelocityEngine;
import org.w3c.unicorn.contract.Observer;
import org.w3c.unicorn.contract.WADLUnmarshaller;
import org.w3c.unicorn.contract.WADLUnmarshallerXPath;
import org.w3c.unicorn.exceptions.UnknownParserException;
import org.w3c.unicorn.language.Language;
import org.w3c.unicorn.response.parser.ResponseParser;
import org.w3c.unicorn.tasklist.RDFUnmarshaller;
import org.w3c.unicorn.tasklist.RDFUnmarshallerJena;
import org.w3c.unicorn.tasklist.Task;
import org.w3c.unicorn.tasklist.TaskListUnmarshallerBeans;
import org.w3c.unicorn.tasklist.Tasklist;
import org.w3c.unicorn.tasklist.TasksListUnmarshaller;
import org.w3c.unicorn.util.ListFiles;
import org.w3c.unicorn.util.Property;
import org.w3c.unicorn.util.UCNProperties;
import com.hp.hpl.jena.rdf.model.Model;
/**
* Main class of the central module of UniCORN.
*
* @author Damien LEROY
*/
public class Framework {
/**
* Data structure for the Observers
*/
public static Map<String, Observer> mapOfObserver;
/**
* Data structure for the tasks
*/
public static Tasklist mapOfTask;
/**
* Data structure for the various response parser
*/
public static Map<String, ResponseParser> mapOfReponseParser;
/**
* Logger
*/
public static Log logger = LogFactory.getLog(Framework.class);
/**
* URI to unicorn home
*/
public static URI unicornHome;
/**
* True if initialization did not throw any exception
*/
public static boolean isUcnInitialized = false;
private static Hashtable<String, Properties> unicornPropertiesFiles;
private static Hashtable<String, VelocityContext> languageContexts;
private static Hashtable<String, Properties> languageProperties;
private static Hashtable<String, String> languages;
private static VelocityEngine velocityEngine;
private static String[] configFiles = {
"extensions.properties",
"responseParsers.properties",
"specialFormaters.properties",
"velocity.properties"};
public static void reset() {
unicornPropertiesFiles = new Hashtable<String, Properties>();
languageContexts = new Hashtable<String, VelocityContext>();
languageProperties = new Hashtable<String, Properties>();
languages = new Hashtable<String, String>();
mapOfObserver = new LinkedHashMap<String, Observer>();
mapOfReponseParser = new LinkedHashMap<String, ResponseParser>();
}
/**
* Initialize Unicorn
*/
public static void init() {
reset();
initCore();
initConfig();
initUnmarshallers();
initResponseParsers();
initObservers();
initTasklists();
initLanguages();
initVelocity();
}
public static void initCore() {// throws Exception {
// Checks that unicorn.home (JVM parameter) is set to an existing directory
String ucnHome = System.getProperty("unicorn.home");
if (ucnHome == null) {
String fatal = "\"unicorn.home\" is not set in the JVM parameters. Please read the README file before trying to install Unicorn";
System.err.println("FATAL: " + fatal);
logger.fatal(fatal);
return;
} else {
File ucnHomeFile = new File(ucnHome);
if (!ucnHomeFile.exists() || !ucnHomeFile.isDirectory()) {
String fatal = "JVM parameter \"unicorn.home\" is not an existing directory: " + System.getProperty("unicorn.home");
System.err.println("FATAL: " + fatal);
logger.fatal(fatal);
return;
} else {
unicornHome = ucnHomeFile.toURI();
logger.info("OK - JVM parameter \"unicorn.home\" was found: " + unicornHome.getPath());
}
}
// Log4j initialization attempt
String log4jPath = unicornHome.getPath() + "/WEB-INF/conf/log4j.properties";
try {
loadConfigFile(log4jPath, true);
PropertyConfigurator.configure(unicornPropertiesFiles.get("log4j.properties"));
logger.info("OK - JVM parameter \"unicorn.home\" was found: " + unicornHome.getPath());
logger.info("OK - Log4j successfully initialized");
logger.debug("> Used log4j.properties file: " + log4jPath);
logger.debug("> log4j.properties:" + (UCNProperties) unicornPropertiesFiles.get("log4j.properties"));
} catch (FileNotFoundException e) {
logger.warn("Log4j config file \"log4j.properties\" could not be found: " + log4jPath);
logger.warn("Log4j will not be initialized");
} catch (IOException e) {
logger.error("Error reading \"log4j.properties\": ", e);
logger.warn("Log4j will not be initialized");
}
}
public static void initConfig() {
// Load unicorn.properties
logger.debug("-------------------------------------------------------");
String unicornPath = unicornHome.getPath() + "/WEB-INF/conf/unicorn.properties";
try {
loadConfigFile(unicornPath, true);
logger.info("OK - Config file unicorn.properties successfully loaded");
} catch (FileNotFoundException e) {
logger.fatal("Unicorn config file \"unicorn.properties\" could not be found: " + unicornPath);
return;
} catch (IOException e) {
logger.fatal("Error reading \"unicorn.properties\": ", e);
return;
}
// Loading config files
for (String fileName : configFiles) {
String path = Property.get("PATH_TO_CONF_FILES") + fileName;
logger.debug("-------------------------------------------------------");
try {
loadConfigFile(path, false);
logger.info("OK - Config file " + fileName + " successfully loaded");
} catch (FileNotFoundException e) {
logger.fatal("Mandatory config file \"" + fileName + "\" could not be found: " + path);
return;
} catch (IOException e) {
logger.fatal("Error reading \"" + fileName + "\": ", e);
return;
}
}
}
public static void initUnmarshallers() {
// Initialize WADLUnmarshallerXPath (Gets the Namespace URI and the prefix)
WADLUnmarshallerXPath.setNamespaceContext(new NamespaceContext() {
public String getNamespaceURI(final String sPrefix) {
if ("xs".equals(sPrefix)) {
return "http://www.w3.org/2001/XMLSchema";
} else if ("uco".equals(sPrefix)) {
return "http://www.w3.org/unicorn/observationresponse";
} else {
return null;
}
}
public String getPrefix(final String sNamespaceURI) {
if ("http://www.w3.org/2001/XMLSchema".equals(sNamespaceURI)) {
return "xs";
} else if ("http://www.w3.org/unicorn/observationresponse"
.equals(sNamespaceURI)) {
return "uco";
} else {
return null;
}
}
public Iterator<String> getPrefixes(final String sNamespaceURI) {
return null;
}
});
// Initialize RDFUnmarshallerJena
logger.debug("-------------------------------------------------------");
logger.debug("Initializing RDFUnmarshallerJena");
try {
FileInputStream fis = new FileInputStream(Property.get("TASKLIST_RDF_MODEL"));
RDFUnmarshallerJena.getModel().read(fis, null);
logger.debug("> Used model: " + Property.get("TASKLIST_RDF_MODEL"));
} catch (FileNotFoundException e) {
logger.fatal("The tasklist rdf model could not be found: " + Property.get("TASKLIST_RDF_MODEL"));
return;
}
Model model = RDFUnmarshallerJena.getModel();
String namespace = RDFUnmarshallerJena.getUcnNamespace();
// define resource use to find information into the RDF graph
RDFUnmarshallerJena.setRESOURCE_TASK(model.getProperty(
namespace + "Task"));
// define property use to find information into the RDF graph
RDFUnmarshallerJena.setPROPERTY_DESCRIPTION(model.getProperty(
namespace + "description"));
RDFUnmarshallerJena.setPROPERTY_HASPARAMETER(model.getProperty(
namespace + "hasParameter"));
RDFUnmarshallerJena.setPROPERTY_HASVALUE(model.getProperty(
namespace + "hasValue"));
RDFUnmarshallerJena.setPROPERTY_LONGNAME(model.getProperty(
namespace + "longName"));
RDFUnmarshallerJena.setPROPERTY_PARAMETER(model.getProperty(
namespace + "parameter"));
RDFUnmarshallerJena.setPROPERTY_REFERENCE(model.getProperty(
namespace + "reference"));
RDFUnmarshallerJena.setPROPERTY_DEFAULT(model.getProperty(
namespace + "default"));
RDFUnmarshallerJena.setPROPERTY_TYPE(model.getProperty(
"http://www.w3.org/1999/02/22-rdf-syntax-ns#type"));
RDFUnmarshallerJena.setPROPERTY_VALUE(model.getProperty(
namespace + "value"));
logger.info("OK - RDFUnmarshallerJena successfully initialized.");
}
public static void initResponseParsers() {
// Load the map of ResponseParser
logger.debug("-------------------------------------------------------");
logger.debug("Loading available parsers form responseParsers.properties");
Properties aProperties = Property.getProps("responseParsers.properties");
for (Object key : aProperties.keySet()) {
String className = aProperties.getProperty(key.toString());
try {
ResponseParser aResponseParser = (ResponseParser) Class
.forName(className).newInstance();
mapOfReponseParser.put(key.toString(), aResponseParser);
logger.debug("> Parser loaded: " + mapOfReponseParser.get(key).getClass().toString());
} catch (ClassNotFoundException e) {
logger.warn("Class not found: " + className + ". Check responseParsers.properties.", e);
} catch (Exception e) {
logger.warn("Error trying to instanciate: " + className, e);
}
}
if (mapOfReponseParser.size() == 0) {
logger.fatal("There is no parser loaded. Check responseParsers.properties.");
return;
} else {
logger.info("OK - " + mapOfReponseParser.size() + " parser(s) successfully loaded.");
}
}
public static void initObservers() {
// Loading observers
logger.debug("-------------------------------------------------------");
logger.debug("Loading available observers from the observers list file.");
BufferedReader aBufferedReader;
try {
aBufferedReader = new BufferedReader(new FileReader(Property.get("OBSERVER_LIST_FILE")));
logger.debug("Using file: " + Property.get("OBSERVER_LIST_FILE"));
} catch (FileNotFoundException e) {
logger.fatal("The list of observers could not be found: " + Property.get("OBSERVER_LIST_FILE"));
return;
}
String readLine;
do {
try {
readLine = aBufferedReader.readLine();
if (readLine == null)
break;
} catch (IOException e) {
logger.fatal("Error while reading the observer list file", e);
return;
}
if ("".equals(readLine.trim()) || readLine.matches("^#.*$"))
continue;
String sWADL = readLine;
if (!readLine.matches(".*\\.wadl$")) {
sWADL += "/" + Property.get("OBSERVER_XML_FILENAME");
}
logger.debug("- Loading observer contract: " + sWADL);
Observer obs = new Observer();
WADLUnmarshaller unmarshaller;
try {
unmarshaller = new WADLUnmarshallerXPath();
unmarshaller.addURL(new URL(sWADL));
unmarshaller.unmarshal();
} catch (MalformedURLException e) {
logger.error("Invalid observer contract URL \"" + sWADL + "\". Check the observers list file.", e);
logger.warn("> This observer will be skiped");
continue;
} catch (ParserConfigurationException e) {
logger.fatal(e.getMessage(), e);
return;
} catch (IOException e) {
logger.error("Unable to read observer contract: " + sWADL, e);
logger.warn("> This observer will be skiped");
continue;
} catch (Exception e) {
logger.error("Error unmarshalling contract: " + sWADL, e);
logger.warn("> This observer will be skiped");
continue;
}
try {
obs.setResponseType(unmarshaller.getResponseType());
} catch (UnknownParserException e) {
logger.error("Unknown parser: " + unmarshaller.getResponseType() + ". Check observer contract or responseParsers.properties.", e);
logger.warn("> This observer will be skiped");
continue;
}
obs.setListOfCallMethod(unmarshaller.getListOfCallMethod());
obs.setParamLangName(unmarshaller.getNameOfLangParameter());
obs.setID(unmarshaller.getID());
obs.setName(unmarshaller.getName());
obs.setDescription(unmarshaller.getDescription());
obs.setHelpLocation(unmarshaller.getHelpLocation());
obs.setProvider(unmarshaller.getProvider());
obs.setMapOfInputMethod(unmarshaller.getMapOfInputMethod());
obs.setSupportedMimeTypes(unmarshaller.getSupportedMimeTypes());
mapOfObserver.put(new String(obs.getID()), obs);
} while (readLine != null);
if (mapOfObserver.size() == 0) {
logger.fatal("There is no observer loaded. Check the observers list file.");
return;
} else {
logger.info("OK - " + mapOfObserver.size() + " observer(s) successfully loaded.");
}
}
public static void initTasklists() {
logger.debug("-------------------------------------------------------");
logger.debug("Loading xml task files from tasklist directory: " + Property.get("PATH_TO_TASKLIST"));
TasksListUnmarshaller aTaskListUnmarshaller = new TaskListUnmarshallerBeans(mapOfObserver);
File[] tFileXML = ListFiles.listFiles(Property.get("PATH_TO_TASKLIST"), "\\.xml$");
for (File aFile : tFileXML) {
try {
logger.debug("- Loading xml file: " + aFile.getName());
aTaskListUnmarshaller.addURL(aFile.toURI().toURL());
aTaskListUnmarshaller.unmarshal();
} catch (MalformedURLException e) {
logger.error(e.getMessage(), e);
} catch (IOException e) {
logger.error("Error reading file: " + aFile.getName(), e);
logger.warn("> This task file will be skiped");
} catch (Exception e) {
logger.error("Error unmarshalling file: " + aFile.getName(), e);
logger.warn("> This task file will be skiped");
}
}
logger.debug("-------------------------------------------------------");
logger.debug("Loading rdf task files from tasklist directory: " + Property.get("PATH_TO_TASKLIST"));
File[] tFileRDF = ListFiles.listFiles(Property.get("PATH_TO_TASKLIST"), "\\.rdf$");
RDFUnmarshaller aRDFUnmarshaller = new RDFUnmarshallerJena();
aRDFUnmarshaller.setMapOfTask(aTaskListUnmarshaller.getMapOfTask());
for (final File aFile : tFileRDF) {
try {
logger.debug("- Loading rdf file: " + aFile.getName());
aRDFUnmarshaller.addURL(aFile.toURI().toURL());
aRDFUnmarshaller.unmarshal();
} catch (MalformedURLException e) {
logger.error(e.getMessage(), e);
} catch (IOException e) {
logger.error("Error reading file: " + aFile.getName(), e);
logger.warn("> This task file will be skiped");
} catch (Exception e) {
logger.error("Error unmarshalling file: " + aFile.getName(), e);
logger.warn("> This task file will be skiped");
}
}
mapOfTask = aTaskListUnmarshaller.getMapOfTask();
for (Object key : mapOfTask.keySet()) {
Task task = mapOfTask.get(key.toString());
String defaultLang = Property.get("DEFAULT_LANGUAGE");
if (task.getLongName().getLocalization(defaultLang) == null) {
task.getLongName().addLocalization(defaultLang, key.toString());
logger.warn("Missing default language long name for task: " + key + ". Long name will be the task id.");
}
}
if (mapOfTask.size() == 0) {
logger.fatal("No task have been loaded. Check task files in: " + Property.get("PATH_TO_TASKLIST"));
return;
} else {
String s = "Map of tasks:";
/*for (String key : mapOfTask.keySet()) {
s += "\n\t" + key + " => " + mapOfTask.get(key).getLongName() + " - " + mapOfTask.get(key).getDescription();
}*/
logger.debug(s + mapOfTask);
logger.info("OK - " + mapOfTask.size() + " task(s) successfully loaded.");
}
}
public static void initLanguages() {
// Loading language files
logger.debug("-------------------------------------------------------");
logger.debug("Loading language files from language directory: " + Property.get("PATH_TO_LANGUAGE_FILES"));
if (!Language.isISOLanguageCode(Property.get("DEFAULT_LANGUAGE"))) {
logger.fatal("Property DEFAULT_LANGUAGE is not a valid ISO639 code: " + Property.get("DEFAULT_LANGUAGE"));
return;
}
File defaultLanguageFile = new File(Property.get("PATH_TO_LANGUAGE_FILES", "DEFAULT_LANGUAGE") + ".properties");
if (!defaultLanguageFile.exists()) {
logger.fatal("Default language file does not exists: " + Property.get("PATH_TO_LANGUAGE_FILES", "DEFAULT_LANGUAGE") + ".properties");
return;
}
File[] languageFiles = ListFiles.listFiles(Property
.get("PATH_TO_LANGUAGE_FILES"), "\\.properties$");
for (File langFile : languageFiles) {
String localeString = langFile.getName().split("\\.")[0];
if (!Language.isISOLanguageCode(localeString))
logger.warn("Invalid language file: " + langFile.getName() + "" +
". \"" + localeString + "\" is not a valid locale.");
else {
try {
FileInputStream fis = new FileInputStream(langFile);
InputStreamReader isr = new InputStreamReader(fis, "UTF-8");
Properties props = new Properties();
props.load(isr);
props.put("lang", localeString);
props.put("tasklist", mapOfTask);
languageProperties.put(localeString, props);
String s;
if (localeString.equals(Property.get("DEFAULT_LANGUAGE")))
s = " (default)";
else
s = "";
logger.debug("> Added language"+s+": " + localeString + " - " + props.getProperty("language"));
} catch (FileNotFoundException e) {
// Should not happen
logger.error(e.getMessage(), e);
} catch (UnsupportedEncodingException e) {
// Should not happen
logger.error(e.getMessage(), e);
} catch (IOException e) {
if (!localeString.equals(Property.get("DEFAULT_LANGUAGE"))) {
logger.error("Unable to read language file. " + langFile + ". This file will be skiped.");
continue;
}
else {
logger.fatal("Unable to read default language file. " + langFile);
return;
}
}
}
}
if (languageProperties.size() == 0) {
logger.fatal("No language have been loaded. Check language files in: " + Property.get("PATH_TO_LANGUAGE_FILES"));
return;
} else {
String s = "Language properties:";
for (String key : languageProperties.keySet()) {
s += "\n\n\t" + languageProperties.get(key).getProperty("language") + ":";
for (Object langKey : languageProperties.get(key).keySet()) {
s += "\n\t\t" + langKey + " => " + languageProperties.get(key).getProperty((String) langKey);
}
}
logger.debug(s);
logger.info("OK - " + languageProperties.size() + " language(s) successfully loaded.");
}
for (String key : languageProperties.keySet()) {
languages.put(key, languageProperties.get(key).getProperty("language"));
}
}
public static void initVelocity() {
// Creating velocity contexts
logger.debug("-------------------------------------------------------");
logger.debug("Initializing Velocity");
for (String locale : languageProperties.keySet()) {
VelocityContext context = new VelocityContext();
Properties langProps = languageProperties.get(locale);
for (Object key : langProps.keySet()) {
context.put((String) key, langProps.get(key));
}
context.put("tasklist", mapOfTask);
context.put("param_prefix", Property.get("UNICORN_PARAMETER_PREFIX"));
context.put("languages", languages);
languageContexts.put(locale, context);
}
logger.debug("> "+languageContexts.size()+" velocity context(s) created");
// Creating velocity engine
velocityEngine = new VelocityEngine();
Properties bProperties = Property.getProps("velocity.properties");
bProperties.put(Velocity.FILE_RESOURCE_LOADER_PATH,
Property.get("PATH_TO_TEMPLATES") + "," +
Property.get("PATH_TO_TEMPLATES")+"includes/");
logger.debug("> Initializing velocity engine with FILE_RESOURCE_LOADER_PATH: " + Property.get("PATH_TO_TEMPLATES"));
try {
velocityEngine.init(bProperties);
logger.debug("> Velocity engine successfully initialized");
} catch (Exception e) {
logger.fatal("Error instanciating velocity engine. " + e.getMessage(), e);
return;
}
logger.info("OK - Velocity successfully initialized");
Framework.logger.info("Unicorn initialized successfully.");
isUcnInitialized = true;
}
private static void loadConfigFile(String path, boolean addUnicornHome) throws FileNotFoundException, IOException {
UCNProperties properties = new UCNProperties();
File configFile = new File(path);
String fileName = configFile.getName();
if (fileName != null) {
logger.debug("Loading config file: " + fileName);
if (addUnicornHome)
properties.put("UNICORN_HOME", unicornHome.getPath());
properties.load(new FileInputStream(configFile));
unicornPropertiesFiles.put(fileName, properties);
logger.debug("> " + fileName + ":" + properties);
}
}
public static Hashtable<String, Properties> getUnicornPropertiesFiles() {
return unicornPropertiesFiles;
}
public static Hashtable<String, VelocityContext> getLanguageContexts() {
return languageContexts;
}
public static VelocityEngine getVelocityEngine() {
return velocityEngine;
}
public static Hashtable<String, Properties> getLanguageProperties() {
return languageProperties;
}
}
--- NEW FILE: Test.java ---
package org.w3c.unicorn;
import java.util.Locale;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Test {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
/*String s = "${TEST} sdf zer ${TEST2}";
System.out.println(s.matches("\\$\\{[a-zA-Z_0-9]*\\}"));
Matcher matcher = Pattern.compile("\\$\\{[a-zA-Z_0-9]*\\}").matcher(s);
while (matcher.find()) {
System.out.println(matcher.group());
}
System.out.println(matcher.lookingAt());
System.out.println(matcher.group());
System.out.println(matcher.group(0));
System.out.println(matcher.group(1));
System.out.println(matcher.lookingAt());
System.out.println(matcher.group());
//replaceAll(repl)*/
Locale loc = new Locale("sssqn");
System.out.println("z" + loc.getLanguage());
}
}
--- NEW FILE: UnicornCall.java ---
// $Id: UnicornCall.java,v 1.2 2009/08/28 12:40:12 jean-gui Exp $
// Author: Jean-Guilhem Rouel
// (c) COPYRIGHT MIT, ERCIM and Keio, 2006.
// Please first read the full copyright statement in file COPYRIGHT.html
package org.w3c.unicorn;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import javax.activation.MimeType;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathFactory;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.lang.StringEscapeUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.log4j.Logger;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.event.EventCartridge;
import org.apache.velocity.app.event.implement.EscapeXmlReference;
import org.w3c.dom.Document;
import org.w3c.unicorn.contract.CallParameter;
import org.w3c.unicorn.contract.EnumInputMethod;
import org.w3c.unicorn.contract.InputMethod;
import org.w3c.unicorn.contract.Observer;
import org.w3c.unicorn.exceptions.EmptyDocumentException;
import org.w3c.unicorn.exceptions.NoDocumentException;
import org.w3c.unicorn.exceptions.NoMimeTypeException;
import org.w3c.unicorn.input.InputFactory;
import org.w3c.unicorn.request.Request;
import org.w3c.unicorn.request.RequestList;
import org.w3c.unicorn.response.Response;
import org.w3c.unicorn.response.parser.ResponseParserFactory;
import org.w3c.unicorn.tasklist.Task;
import org.w3c.unicorn.tasklist.parameters.Mapping;
import org.w3c.unicorn.tasklist.parameters.Parameter;
import org.w3c.unicorn.tasklist.parameters.Value;
import org.w3c.unicorn.tasklisttree.EnumCondType;
import org.w3c.unicorn.tasklisttree.TLTCond;
import org.w3c.unicorn.tasklisttree.TLTExec;
import org.w3c.unicorn.tasklisttree.TLTIf;
import org.w3c.unicorn.tasklisttree.TLTNode;
import org.w3c.unicorn.util.Property;
import org.w3c.unicorn.util.TemplateHelper;
import org.w3c.unicorn.util.Templates;
import com.sun.org.apache.xpath.internal.jaxp.XPathFactoryImpl;
/**
* UnicornCall Created: Jun 29, 2006 2:44:12 PM
*
* @author Jean-Guilhem Rouel
*/
public class UnicornCall {
/**
* Log Object to perform powerful logs
*/
private static final Log logger = LogFactory.getLog(UnicornCall.class);
// Request
/**
* The task to call
*/
private Task aTask = null;
/**
* Check Method : Upload, URI , Direct...
*/
private EnumInputMethod aEnumInputMethod = null;
private Object oInputParameterValue = null;
private String sDocumentName = null;
private String sLang = null;
private RequestList aRequestList = null;
private Map<String, String[]> mapOfStringParameter = null;
/**
* Data Structure for the response
*/
private Map<String, Response> mapOfResponse;
/**
* Active threads number in doRequests() method
*/
private int nbActiveThreads;
/**
* Tells if all the checks passed
*/
private boolean bPassed;
/**
* Creates a new UnicornCall.
*/
public UnicornCall() {
UnicornCall.logger.trace("Constructor()");
this.mapOfStringParameter = new LinkedHashMap<String, String[]>();
this.mapOfResponse = new LinkedHashMap<String, Response>();
this.nbActiveThreads = 0;
}
/**
* Execute the task aTask
*
* @throws Exception
*/
public void doTask() throws Exception {
UnicornCall.logger.trace("doTask.");
if (UnicornCall.logger.isDebugEnabled()) {
UnicornCall.logger.debug("String task id : " + this.aTask.getID()
+ ".");
UnicornCall.logger.debug("EnumInputMethod : "
+ this.aEnumInputMethod + ".");
UnicornCall.logger.debug("Document name : " + this.sDocumentName
+ ".");
UnicornCall.logger.debug("Map of string parameter : "
+ this.mapOfStringParameter + ".");
}
// find mimetype of the document
MimeType aMimeType = this.getMimeType();
// Create input method
final InputFactory aInputFactory = new InputFactory(aMimeType,
this.aEnumInputMethod, this.oInputParameterValue);
this.doNode(aInputFactory, this.aTask.getTree());
aInputFactory.dispose();
}
/**
* Main function called to do the recursion over the Task tree to launch the
* requests
*
* @param aInputFactory
* InputFactory used for the resquests
* @param node
* the current node that we're parsing in the Task tree
* @throws Exception
* raised from generateRequestList and doRequest
*/
private void doNode(InputFactory aInputFactory, TLTNode node)
throws Exception {
// Generate the list of request
UnicornCall.logger.trace("doNode.");
if (UnicornCall.logger.isDebugEnabled()) {
UnicornCall.logger.debug("InputFactory : " + aInputFactory + ".");
UnicornCall.logger.debug("Current node : " + node + ".");
}
if (node != null) {
this.aRequestList = this.generateRequestList(aInputFactory,
this.mapOfStringParameter, node);
if (UnicornCall.logger.isDebugEnabled()) {
UnicornCall.logger.debug("RequestList : " + this.aRequestList
+ ".");
}
// send requests to observer
this.doRequests();
UnicornCall.logger.info("Check the condition of the Ifs");
// browse the conditions to do the connection
for (TLTIf ifs : node.getIfList()) {
if (this.checkCond(ifs)) {
this.doNode(aInputFactory, ifs.getIfOk());
} else {
this.doNode(aInputFactory, ifs.getIfNotOk());
}
}
} else {
// Inform if the node is null
if (UnicornCall.logger.isDebugEnabled()) {
UnicornCall.logger.debug("The node is null at this point.");
}
}
}
/**
* Check the conditions of the if branch it makes a OR between all
* conditions
*
* @param ifs
* the if branch to check
* @return whether or not the conditions are true
* @throws Exception
*/
private boolean checkCond(TLTIf ifs) throws Exception {
UnicornCall.logger.trace("checkCond.");
if (UnicornCall.logger.isDebugEnabled()) {
UnicornCall.logger.debug("If node : " + ifs + ".");
}
boolean conditionOK = false;
// boolean to manage the OR in the conditions, if the cond is false we
// change the boolean to true , if not we don't care
// that will simulate the OR
for (TLTCond cond : ifs.getCondArray()) {
if (this.checkCond(cond)) {
conditionOK = true;
}
}
return conditionOK;
}
/**
* Creates the map of all the Observer to call in the current node
*
* @param node
* the current node of the Task tree we are parsing
*/
private Map<String, Observer> createExecList(TLTNode node) {
Map<String, Observer> mapOfCurrentNodeObserver = new LinkedHashMap<String, Observer>();
for (TLTExec exec : node.getExecutionList()) {
mapOfCurrentNodeObserver.put(exec.getValue(), exec.getObserver());
}
return mapOfCurrentNodeObserver;
}
/**
* Adds 1 to active threads number
*/
public synchronized void incCounter() {
this.nbActiveThreads++;
}
/**
* Substracts 1 to active threads number
*/
public synchronized void decCounter() {
this.nbActiveThreads--;
}
/**
* Change the value the boolean bPassed
*
* @param b
* new value
*/
public void setbPassed(boolean b) {
this.bPassed = b;
}
/**
* getter for bPassed
*
* @return the value of bPassed
*/
public boolean getBPassed() {
return this.bPassed;
}
/**
* Execute the request depending on the priority
*
* @param aTPriority
* priority of the request
* @throws IOException
* Input/Output error
*/
private boolean doRequests() throws IOException {
UnicornCall.logger.trace("doRequest");
bPassed = true;
final Map<String, Request> requests = this.aRequestList.getRequestMap();
// Creation of the thread list
ArrayList<Thread> threadsList = new ArrayList<Thread>();
for (final String obsID : requests.keySet()) {
// send request to observer
if (UnicornCall.logger.isDebugEnabled()) {
UnicornCall.logger.debug("Request : "
+ requests.get(obsID).toString());
}
threadsList.add(new RequestThread(mapOfResponse, requests
.get(obsID), obsID, this));
}
for (int i = 0; i < threadsList.size(); i++) {
threadsList.get(i).start();
}
for (int i = 0; i < threadsList.size(); i++) {
try {
threadsList.get(i).join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return bPassed;
}
/**
* Generate the list of the request for the call
*
* @param aInputFactory
* Input factory for the parameter
* @param mapOfArrayUseParameter
* array of the parameter
* @param node
* the current node that we are parsing
* @return the list of the request for the call
* @throws Exception
* error occured during the process
*/
private RequestList generateRequestList(final InputFactory aInputFactory,
final Map<String, String[]> mapOfArrayUseParameter, TLTNode node)
throws Exception {
// Log information
UnicornCall.logger.trace("generateRequestList");
if (UnicornCall.logger.isDebugEnabled()) {
UnicornCall.logger.debug("InputFactory : " + aInputFactory + ".");
UnicornCall.logger.debug("Map of string parameter : "
+ mapOfArrayUseParameter + ".");
}
final MimeType aMimeType = aInputFactory.getMimeType();
final EnumInputMethod aEnumInputMethod = aInputFactory
.getDefaultInputModule().getEnumInputMethod();
final RequestList aRequestList = new RequestList(this.sLang);
// Iterate over all observation of this task to build a basic
// request list with only the url of observator and input parameter
// Il faut creer une list avec tous les exec et toutes les rencardeur de
// ifs
// Une liste d'Observer
for (final Observer aObserver : this.createExecList(node).values()) {
final String sObserverID = aObserver.getID();
// add only observer who handle the current mimetype
if (!aObserver.canHandleMimeType(aMimeType)) {
if (UnicornCall.logger.isDebugEnabled()) {
UnicornCall.logger.debug("Observer " + sObserverID
+ " does not handle mime type "
+ aMimeType.toString());
}
continue;
}
// the best available observation method
final InputMethod aInputMethod = aObserver
.getBestInputMethod(aEnumInputMethod);
// create a new request with input parameter
final Request aRequest = Request.createRequest(
// the corresponding best input module
aInputFactory.getInputModule(aInputMethod.getMethod()),
// URL of the service to call
aInputMethod.getCallMethod().getURL().toString(),
// Name of the parameter holding resource information
// (uri,url,txt,text,file,...)
aInputMethod.getCallParameter().getName(),
// Has a file been uploaded?
aInputMethod.getCallMethod().isPost(),
// Response format
aObserver.getResponseType());
// add this request to request list
aRequestList.addRequest(aRequest, aObserver.getID());
// log debug information
if (UnicornCall.logger.isDebugEnabled()) {
UnicornCall.logger.debug("Redirect request " + aRequest
+ " from " + aEnumInputMethod + " to "
+ aInputMethod.getMethod() + " added to request list.");
}
// Get value of ucn_lang parameter to associate it with parameter
// lang of the observer (if it has one).
// ucn_lang is defined in forms of index templates
// (xx_index.html.vm)
String[] valOfUcnLang = this.mapOfStringParameter.get(Property
.get("UNICORN_PARAMETER_PREFIX")
+ "lang");
// Get name of the lang parameter (defined in RDF file)
String observerParamLangName = aObserver.getParamLangName();
// If lang parameter exists, we add name and value in parameters of
// the request.
if (observerParamLangName != null && valOfUcnLang != null) {
aRequest.addParameter(observerParamLangName, valOfUcnLang[0]);
}
// Add this request to request list
aRequestList.addRequest(aRequest, aObserver.getID());
// Log debug information
if (UnicornCall.logger.isDebugEnabled()) {
UnicornCall.logger.debug("Request " + aRequest
+ " added to request list.");
}
// Add fixed parameter
for (final CallParameter aCallParameter : aObserver.getCallMethod(
aInputMethod.getMethod()).getMapOfCallParameter().values()) {
if (aCallParameter.isRequired() && aCallParameter.isFixed()) {
aRequest.addParameter(aCallParameter.getName(),
aCallParameter.getFixed());
}
}
} // foreach this.aTask.getMapOfObservation().values()
// Iterate over all parameter of this task to add at the
// request list the parameter input by the framework client
for (final String sTaskParameterName : this.aTask.getMapOfParameter()
.keySet()) {
final Parameter aTaskParameter = this.aTask.getMapOfParameter()
.get(sTaskParameterName);
if (UnicornCall.logger.isDebugEnabled()) {
UnicornCall.logger.debug("Parameter : " + sTaskParameterName
+ ".");
}
// check if this parameter have a given value
String[] tStringUseParameterValue = mapOfArrayUseParameter
.get(sTaskParameterName);
if (null == tStringUseParameterValue) {
if (UnicornCall.logger.isDebugEnabled()) {
UnicornCall.logger.debug("No value input for parameter "
+ sTaskParameterName + ".");
}
// check if this parameter have a default value
final Map<String, Value> mapOfDefaultValue = aTaskParameter
.getMapOfDefaultValue();
if (null == mapOfDefaultValue || 0 == mapOfDefaultValue.size()) {
UnicornCall.logger.warn("Parameter " + sTaskParameterName
+ " has no value intput and no default value.");
continue;
}
tStringUseParameterValue = new String[mapOfDefaultValue
.keySet().size()];
int i = 0;
for (final String s : mapOfDefaultValue.keySet()) {
tStringUseParameterValue[i++] = s;
}
}
if (UnicornCall.logger.isDebugEnabled()) {
for (final String sParameterValue : tStringUseParameterValue) {
UnicornCall.logger.debug("Parameter Value : "
+ sParameterValue + ".");
}
}
final Map<String, Value> mapOfValue = aTaskParameter
.getMapOfValue();
// if there no value the parameter allow all string
if (null == mapOfValue) {
final Map<String, Value> mapOfDefaultValue = aTaskParameter
.getMapOfDefaultValue();
// Parameter allow all string !
final Value aValue = mapOfDefaultValue.values().iterator()
.next();
final Map<String, List<Mapping>> mapOfMapping = aValue
.getMapOfMapping();
for (final String sObserverName : mapOfMapping.keySet()) {
final Request aRequest = aRequestList
.getRequest(sObserverName);
for (final Mapping aMapping : mapOfMapping
.get(sObserverName)) {
final String sValue = aMapping.getValue();
// check
if (null == sValue || "".equals(sValue)) {
aRequest.addParameter(aMapping.getParam(),
tStringUseParameterValue[0]);
continue;
}
aRequest.addParameter(aMapping.getParam(), sValue);
}
} // foreach mapOfMapping.keySet()
continue;
}
for (final String sUseParameterValue : tStringUseParameterValue) {
final Value aValue = mapOfValue.get(sUseParameterValue);
final Map<String, List<Mapping>> mapOfMapping = aValue
.getMapOfMapping();
for (final String sObserverName : mapOfMapping.keySet()) {
if (aRequestList.getRequest(sObserverName) != null) {
final Request aRequest = aRequestList
.getRequest(sObserverName);
for (final Mapping aMapping : mapOfMapping
.get(sObserverName)) {
final String sValue = aMapping.getValue();
// check
if (null == sValue || "".equals(sValue)) {
aRequest.addParameter(aMapping.getParam(),
sUseParameterValue);
continue;
}
aRequest.addParameter(aMapping.getParam(), aMapping
.getValue());
}
}
} // foreach mapOfMapping.keySet()
} // foreach sArrayParameterValue
} // foreach this.parameters.values()
return aRequestList;
}
/**
* Returns the responses of low priority observations.
*
* @return responses of low priority observations.
*/
public Map<String, Response> getResponses() {
return this.mapOfResponse;
}
/**
* Set the task to perform
*
* @param sTaskID
* ID of the task to perform
*/
public void setTask(final String sTaskID) {
if (null == sTaskID) {
UnicornCall.logger.error("Call setTask with null argument.");
return;
}
this.aTask = Framework.mapOfTask.get(sTaskID);
if (null == this.aTask) {
UnicornCall.logger.error("The task " + sTaskID
+ " does not exists.");
}
}
/**
* define the lang of the check
*
* @param sLang
* defines the lang to configure
*/
public void setLang(final String sLang) {
UnicornCall.logger.debug("setLang(" + sLang + ")");
this.sLang = sLang;
}
public String getLang() {
return sLang.split(",")[0];
}
/**
* Returns the document name
*
* @return Returns the documentName.
*/
public String getDocumentName() {
return this.sDocumentName;
}
/**
* Set the name of the document
*
* @param sDocumentName
* The documentName to set.
*/
public void setDocumentName(final String sDocumentName) {
this.sDocumentName = sDocumentName;
}
/**
* Gives the list of the observations
*
* @return map of the observations of the check
*/
public Map<String, Response> getObservationList() {
return mapOfResponse;
}
public String getObserverName(String observer, String lang) {
return Framework.mapOfObserver.get(observer).getName(lang);
}
/**
* @return Returns the mapOfStringParameter.
*/
public Map<String, String[]> getMapOfStringParameter() {
return mapOfStringParameter;
}
/**
* Enter a new parameter in the list
*
* @param sName
* Name of the parameter
* @param tStringValue
* value of the parameter
*/
public void addParameter(final String sName, final String[] tStringValue) {
final String[] tStringValueLocal = mapOfStringParameter.get(sName);
if (tStringValueLocal != null) {
int tValuesLength = tStringValueLocal.length;
int newSize = tStringValue.length + tValuesLength;
final String[] tStringValueNew = new String[newSize];
for (int i = 0; i < tStringValueLocal.length; i++) {
tStringValueNew[i] = tStringValueLocal[i];
}
for (int i = 0; i < tStringValue.length; i++) {
tStringValueNew[tValuesLength + i] = tStringValue[i];
}
this.mapOfStringParameter.put(sName, tStringValueNew);
} else {
this.mapOfStringParameter.put(sName, tStringValue);
}
}
/**
* Set the map of String Parameter
*
* @param mapOfStringParameter
* The mapOfStringParameter to set.
*/
public void setMapOfStringParameter(
final Map<String, String[]> mapOfStringParameter) {
this.mapOfStringParameter = mapOfStringParameter;
}
/**
* Returns the current task
*
* @return Returns the current task.
*/
public Task getTask() {
return this.aTask;
}
/**
* Set the aEnumInputMethod
*
* @param enumInputMethod
* The aEnumInputMethod to set.
*/
public void setEnumInputMethod(final EnumInputMethod aEnumInputMethod) {
this.aEnumInputMethod = aEnumInputMethod;
}
public EnumInputMethod getInputMethod() {
return aEnumInputMethod;
}
/**
* Set the uploadedFile
*
* @param uploadedFile
* The uploadedFile to set.
*/
public void setInputParameterValue(final Object oInputParameterValue) {
this.oInputParameterValue = oInputParameterValue;
}
/**
* Giving a TLTCond, checks in the map of response if the condition passes
* or fails and consequently returns a boolean.
*
* @param cond
* The condition to check
* @return true if there is a matching response and if the condition passes
* else false
*/
public boolean checkCond(TLTCond cond) throws Exception {
UnicornCall.logger.trace("checkCond : ");
UnicornCall.logger.trace(cond);
UnicornCall.logger.trace("condId : " + cond.getId());
UnicornCall.logger.trace("condType : " + cond.getType());
UnicornCall.logger.trace("condValue : " + cond.getValue());
boolean passed = false;
if (cond.getType().equals(EnumCondType.MIMETYPE)) {
passed = cond.getValue().equals(getMimeType().toString());
} else if (cond.getType().equals(EnumCondType.XPATH)) {
UnicornCall.logger.trace("condObserver : "
+ cond.getObserver().getID());
Response res = mapOfResponse.get(cond.getObserver().getID());
// Testing if there is a matching response in the map
// and if it is passed
if (res != null) {
String xmlStr = res.getXml().toString();
DocumentBuilderFactory xmlFact = DocumentBuilderFactory
.newInstance();
// namespace awareness is escaped since we don't use it
// for the moment
xmlFact.setNamespaceAware(false);
DocumentBuilder builder = xmlFact.newDocumentBuilder();
Document doc = builder.parse(new java.io.ByteArrayInputStream(
xmlStr.getBytes("UTF-8")));
String xpathStr = cond.getValue();
XPathFactory xpathFact = new XPathFactoryImpl();
XPath xpath = xpathFact.newXPath();
XPathExpression xpe = xpath.compile(xpathStr);
passed = (Boolean) xpe.evaluate(doc, XPathConstants.BOOLEAN);
}
}
cond.setResult(passed);
UnicornCall.logger.trace("cond result : " + passed);
return passed;
}
/**
*
* @return The MimeType of the document
* @throws Exception
*/
private MimeType getMimeType() throws Exception {
UnicornCall.logger.trace("getMimeType");
MimeType aMimeType = null;
String sMimeType;
switch (this.aEnumInputMethod) {
case URI:
sMimeType = (new URL(this.sDocumentName)).openConnection()
.getContentType();
if (null == sMimeType || "".equals(sMimeType)) {
UnicornCall.logger.error("No specified mimetype for upload.");
throw new NoMimeTypeException("Mimetype not found");
}
if (UnicornCall.logger.isDebugEnabled()) {
UnicornCall.logger.debug("URI MimeType : " + sMimeType + ".");
}
sMimeType = sMimeType.split(";")[0];
aMimeType = new MimeType(sMimeType);
break;
case UPLOAD:
FileItem f = (FileItem) this.oInputParameterValue;
if (f.getName() == null || f.getName().equals("")) {
UnicornCall.logger.error("No document provided.");
throw new NoDocumentException("No document provided");
}
if (f.getSize() == 0) {
UnicornCall.logger.error("Empty document provided.");
throw new EmptyDocumentException("Empty document provided");
}
sMimeType = ((FileItem) this.oInputParameterValue).getContentType();
if (null == sMimeType || "".equals(sMimeType)) {
UnicornCall.logger.error("No specified mimetype for upload.");
throw new NoMimeTypeException("Mimetype not found");
}
aMimeType = new MimeType(sMimeType);
break;
case DIRECT:
sMimeType = this.mapOfStringParameter.get(Property
.get("UNICORN_PARAMETER_PREFIX")
+ "mime")[0];
if (null == sMimeType || "".equals(sMimeType)) {
UnicornCall.logger
.error("No mimetype specified for direct input.");
throw new NoMimeTypeException("Mimetype not found.");
}
aMimeType = new MimeType(sMimeType);
break;
}
if (UnicornCall.logger.isDebugEnabled()) {
UnicornCall.logger
.debug("MimeType : " + aMimeType.toString() + ".");
}
return aMimeType;
}
}
/**
* Thread executing a request
*
* @author Damien Leroy
*
*/
class RequestThread extends Thread {
/**
* Used for complex logging purpose
*/
private static final Log logger = LogFactory.getLog(RequestThread.class);;
/**
* Data Structure for the responses
*/
private Map<String, Response> mapOfResponse;
/**
* The request to make
*/
private Request aRequest;
/**
* ID of the Observer
*/
private String obsID;
/**
* The call to perform
*/
private UnicornCall unicornCall;
/**
* Initialize the thread by filling the properties
*
* @param mapOfResponse
* the map of the responses
* @param aRequest
* the request to make
* @param obsID
* the ID of the observer
* @param unicorn
* the unicorn call to make
*/
public RequestThread(Map<String, Response> mapOfResponse, Request aRequest,
String obsID, UnicornCall unicorn) {
this.mapOfResponse = mapOfResponse;
this.aRequest = aRequest;
this.obsID = obsID;
this.unicornCall = unicorn;
}
/**
* Allow to launch the thread
*/
@Override
public void run() {
this.unicornCall.incCounter();
Response aResponse = null;
try {
// Uncomment/comment next lines to test io_error
//throw new Exception("Message test de l'exception");
aResponse = this.aRequest.doRequest();
} catch (final Exception e) {
RequestThread.logger.error("Exception : " + e.getMessage(), e);
e.printStackTrace();
try {
StringBuilder builder = new StringBuilder();
//String lang[] = unicornCall.getMapOfStringParameter().get(
// Property.get("UNICORN_PARAMETER_PREFIX") + "lang");
String lang = unicornCall.getLang();
VelocityContext context = new VelocityContext(Framework.getLanguageContexts().get(lang));
final EventCartridge aEventCartridge = new EventCartridge();
aEventCartridge.addEventHandler(new EscapeXmlReference());
aEventCartridge.attachToContext(context);
if (e.getMessage() != null)
context.put("exception", e.getMessage());
else
context.put("exception", "");
ByteArrayOutputStream os = new ByteArrayOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(os);
Templates.write("io_error.vm", context, osw);
osw.close();
InputStreamReader isr = new InputStreamReader(
new ByteArrayInputStream(os.toByteArray()));
char[] chararray = new char[8192];
int readLength = 0;
while ((readLength = isr.read(chararray, 0, 8192)) > -1) {
builder.append(chararray, 0, readLength);
}
aResponse = ResponseParserFactory.parse(builder.toString(),
this.aRequest.getResponseType());
aResponse.setXml(builder);
} catch (MalformedURLException e1) {
RequestThread.logger
.error("Exception : " + e1.getMessage(), e1);
e1.printStackTrace();
} catch (IOException e1) {
RequestThread.logger
.error("Exception : " + e1.getMessage(), e1);
e1.printStackTrace();
} catch (Exception e1) {
RequestThread.logger
.error("Exception : " + e1.getMessage(), e1);
e1.printStackTrace();
}
}
synchronized (mapOfResponse) {
mapOfResponse.put(obsID, aResponse);
}
if (!aResponse.isPassed() && this.unicornCall.getBPassed()) {
this.unicornCall.setbPassed(false);
}
this.unicornCall.decCounter();
}
}
Received on Friday, 28 August 2009 12:40:26 UTC