- 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