You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@manifoldcf.apache.org by kw...@apache.org on 2010/07/14 14:55:28 UTC
svn commit: r964035 [1/4] - in /incubator/lcf/trunk/modules: ./ framework/
framework/api/ framework/api/WEB-INF/ framework/api/WEB-INF/lib/
framework/api/org/ framework/api/org/apache/ framework/api/org/apache/lcf/
framework/api/org/apache/lcf/api/ fra...
Author: kwright
Date: Wed Jul 14 12:55:26 2010
New Revision: 964035
URL: http://svn.apache.org/viewvc?rev=964035&view=rev
Log:
Add partial LCF api. The API's context path is lcf-api. Current support in place for json versions of all job-related commands. Additional commands, and documentation too, will follow.
Added:
incubator/lcf/trunk/modules/framework/api/
incubator/lcf/trunk/modules/framework/api/WEB-INF/
incubator/lcf/trunk/modules/framework/api/WEB-INF/lib/
incubator/lcf/trunk/modules/framework/api/WEB-INF/web.xml (with props)
incubator/lcf/trunk/modules/framework/api/org/
incubator/lcf/trunk/modules/framework/api/org/apache/
incubator/lcf/trunk/modules/framework/api/org/apache/lcf/
incubator/lcf/trunk/modules/framework/api/org/apache/lcf/api/
incubator/lcf/trunk/modules/framework/api/org/apache/lcf/api/APIServlet.java (with props)
incubator/lcf/trunk/modules/framework/api/org/apache/lcf/api/Argument.java (with props)
incubator/lcf/trunk/modules/json/
incubator/lcf/trunk/modules/json/org/
incubator/lcf/trunk/modules/json/org/json/
incubator/lcf/trunk/modules/json/org/json/CDL.java (with props)
incubator/lcf/trunk/modules/json/org/json/Cookie.java (with props)
incubator/lcf/trunk/modules/json/org/json/CookieList.java (with props)
incubator/lcf/trunk/modules/json/org/json/HTTP.java (with props)
incubator/lcf/trunk/modules/json/org/json/HTTPTokener.java (with props)
incubator/lcf/trunk/modules/json/org/json/JSONArray.java (with props)
incubator/lcf/trunk/modules/json/org/json/JSONException.java (with props)
incubator/lcf/trunk/modules/json/org/json/JSONML.java (with props)
incubator/lcf/trunk/modules/json/org/json/JSONObject.java (with props)
incubator/lcf/trunk/modules/json/org/json/JSONString.java (with props)
incubator/lcf/trunk/modules/json/org/json/JSONStringer.java (with props)
incubator/lcf/trunk/modules/json/org/json/JSONTokener.java (with props)
incubator/lcf/trunk/modules/json/org/json/JSONWriter.java (with props)
incubator/lcf/trunk/modules/json/org/json/Test.java (with props)
incubator/lcf/trunk/modules/json/org/json/XML.java (with props)
incubator/lcf/trunk/modules/json/org/json/XMLTokener.java (with props)
Modified:
incubator/lcf/trunk/modules/build.xml
incubator/lcf/trunk/modules/framework/build.xml
incubator/lcf/trunk/modules/framework/core/org/apache/lcf/core/interfaces/ConfigNode.java
incubator/lcf/trunk/modules/framework/core/org/apache/lcf/core/interfaces/Configuration.java
incubator/lcf/trunk/modules/framework/core/org/apache/lcf/core/interfaces/ConfigurationNode.java
incubator/lcf/trunk/modules/framework/core/org/apache/lcf/core/interfaces/SpecificationNode.java
incubator/lcf/trunk/modules/framework/jetty-runner/org/apache/lcf/jettyrunner/LCFJettyRunner.java
incubator/lcf/trunk/modules/framework/pull-agent/org/apache/lcf/crawler/system/LCF.java
Modified: incubator/lcf/trunk/modules/build.xml
URL: http://svn.apache.org/viewvc/incubator/lcf/trunk/modules/build.xml?rev=964035&r1=964034&r2=964035&view=diff
==============================================================================
--- incubator/lcf/trunk/modules/build.xml (original)
+++ incubator/lcf/trunk/modules/build.xml Wed Jul 14 12:55:26 2010
@@ -38,11 +38,26 @@
<delete dir="connectors/webcrawler/lib"/>
</target>
- <target name="build-framework">
+ <target name="build-json">
+ <mkdir dir="build/json/classes"/>
+ <javac srcdir="json" destdir="build/json/classes" target="1.5" source="1.4" debug="true" debuglevel="lines,vars,source">
+ <classpath>
+ </classpath>
+ </javac>
+ </target>
+ <target name="jar-json" depends="build-json">
+ <mkdir dir="build/jar"/>
+ <jar destfile="build/jar/json.jar" basedir="build/json/classes"/>
+ </target>
+
+ <target name="build-framework" depends="jar-json">
<mkdir dir="framework/lib"/>
<!-- Individually specify the needed libraries, since otherwise that information would not be available readily -->
<copy todir="framework/lib">
+ <fileset dir="build/jar">
+ <include name="json.jar"/>
+ </fileset>
<fileset dir="lib">
<include name="commons-codec*.jar"/>
<include name="commons-collections*.jar"/>
@@ -656,7 +671,7 @@
<mkdir dir="build/example"/>
<manifest file="build/example/manifest">
<attribute name="Main-Class" value="org.apache.lcf.jettyrunner.LCFJettyRunner"/>
- <attribute name="Class-Path" value="lib/commons-codec.jar lib/commons-collections.jar lib/commons-el.jar lib/commons-fileupload.jar lib/commons-httpclient-lcf.jar lib/commons-io.jar lib/commons-logging.jar lib/derbyclient.jar lib/derby.jar lib/derbyLocale_cs.jar lib/derbyLocale_de_DE.jar lib/derbyLocale_es.jar lib/derbyLocale_fr.jar lib/derbyLocale_hu.jar lib/derbyLocale_it.jar lib/derbyLocale_ja_JP.jar lib/derbyLocale_ko_KR.jar lib/derbyLocale_pl.jar lib/derbyLocale_pt_BR.jar lib/derbyLocale_ru.jar lib/derbyLocale_zh_CN.jar lib/derbyLocale_zh_TW.jar lib/derbynet.jar lib/derbyrun.jar lib/derbytools.jar lib/eclipse-ecj.jar lib/jasper-6.0.24.jar lib/jasper-el-6.0.24.jar lib/jdbcpool-0.99.jar lib/jetty-6.1.22.jar lib/jetty-util-6.1.22.jar lib/jsp-api-2.1-glassfish-9.1.1.B60.25.p2.jar lib/lcf-agents.jar lib/lcf-core.jar lib/lcf-jetty-runner.jar lib/lcf-pull-agent.jar lib/lcf-ui-core.jar lib/log4j-1.2.jar lib/postgresql.jar lib/serializer.jar lib/servlet-api-2.5-20081
211.jar lib/tomcat-juli-6.0.24.jar lib/xalan2.jar lib/xercesImpl-lcf.jar lib/xml-apis.jar"/>
+ <attribute name="Class-Path" value="lib/commons-codec.jar lib/commons-collections.jar lib/commons-el.jar lib/commons-fileupload.jar lib/commons-httpclient-lcf.jar lib/commons-io.jar lib/commons-logging.jar lib/derbyclient.jar lib/derby.jar lib/derbyLocale_cs.jar lib/derbyLocale_de_DE.jar lib/derbyLocale_es.jar lib/derbyLocale_fr.jar lib/derbyLocale_hu.jar lib/derbyLocale_it.jar lib/derbyLocale_ja_JP.jar lib/derbyLocale_ko_KR.jar lib/derbyLocale_pl.jar lib/derbyLocale_pt_BR.jar lib/derbyLocale_ru.jar lib/derbyLocale_zh_CN.jar lib/derbyLocale_zh_TW.jar lib/derbynet.jar lib/derbyrun.jar lib/derbytools.jar lib/eclipse-ecj.jar lib/jasper-6.0.24.jar lib/jasper-el-6.0.24.jar lib/jdbcpool-0.99.jar lib/jetty-6.1.22.jar lib/jetty-util-6.1.22.jar lib/jsp-api-2.1-glassfish-9.1.1.B60.25.p2.jar lib/json.jar lib/lcf-agents.jar lib/lcf-core.jar lib/lcf-jetty-runner.jar lib/lcf-pull-agent.jar lib/lcf-ui-core.jar lib/log4j-1.2.jar lib/postgresql.jar lib/serializer.jar lib/servlet-
api-2.5-20081211.jar lib/tomcat-juli-6.0.24.jar lib/xalan2.jar lib/xercesImpl-lcf.jar lib/xml-apis.jar"/>
</manifest>
<jar destfile="dist/example/start.jar" manifest="build/example/manifest"/>
</target>
Added: incubator/lcf/trunk/modules/framework/api/WEB-INF/web.xml
URL: http://svn.apache.org/viewvc/incubator/lcf/trunk/modules/framework/api/WEB-INF/web.xml?rev=964035&view=auto
==============================================================================
--- incubator/lcf/trunk/modules/framework/api/WEB-INF/web.xml (added)
+++ incubator/lcf/trunk/modules/framework/api/WEB-INF/web.xml Wed Jul 14 12:55:26 2010
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+
+<!DOCTYPE web-app
+ PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN"
+ "http://java.sun.com/j2ee/dtds/web-app_2.2.dtd">
+
+<!-- Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<web-app>
+ <display-name>Lucene Connectors Framework General API</display-name>
+
+ <description>Lucene Connectors Framework General API</description>
+
+ <servlet>
+ <servlet-name>APIServlet</servlet-name>
+ <servlet-class>org.apache.lcf.api.APIServlet</servlet-class>
+ </servlet>
+
+ <servlet-mapping>
+ <servlet-name>APIServlet</servlet-name>
+ <url-pattern>/*</url-pattern>
+ </servlet-mapping>
+
+ <session-config>
+ <session-timeout>5</session-timeout>
+ </session-config>
+
+</web-app>
Propchange: incubator/lcf/trunk/modules/framework/api/WEB-INF/web.xml
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: incubator/lcf/trunk/modules/framework/api/WEB-INF/web.xml
------------------------------------------------------------------------------
svn:keywords = Id
Added: incubator/lcf/trunk/modules/framework/api/org/apache/lcf/api/APIServlet.java
URL: http://svn.apache.org/viewvc/incubator/lcf/trunk/modules/framework/api/org/apache/lcf/api/APIServlet.java?rev=964035&view=auto
==============================================================================
--- incubator/lcf/trunk/modules/framework/api/org/apache/lcf/api/APIServlet.java (added)
+++ incubator/lcf/trunk/modules/framework/api/org/apache/lcf/api/APIServlet.java Wed Jul 14 12:55:26 2010
@@ -0,0 +1,177 @@
+/* $Id$ */
+
+/**
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+package org.apache.lcf.api;
+
+import org.apache.lcf.core.interfaces.*;
+import org.apache.lcf.agents.interfaces.*;
+import org.apache.lcf.crawler.interfaces.*;
+import org.apache.lcf.crawler.system.LCF;
+import org.apache.lcf.crawler.system.Logging;
+
+import java.io.*;
+import java.util.*;
+import java.net.*;
+
+import javax.servlet.*;
+import javax.servlet.http.*;
+
+/** This servlet class provides API services for LCF.
+*/
+public class APIServlet extends HttpServlet
+{
+ public static final String _rcsid = "@(#)$Id$";
+
+ /** The init method.
+ */
+ public void init(ServletConfig config)
+ throws ServletException
+ {
+ super.init(config);
+ try
+ {
+ // Set up the environment
+ LCF.initializeEnvironment();
+ // Nothing more needs to be done at this point.
+ }
+ catch (LCFException e)
+ {
+ Logging.misc.error("Error starting API service: "+e.getMessage(),e);
+ throw new ServletException("Error starting API service: "+e.getMessage(),e);
+ }
+
+ }
+
+ /** The destroy method.
+ */
+ public void destroy()
+ {
+ try
+ {
+ // Set up the environment
+ LCF.initializeEnvironment();
+ // Nothing more needs to be done.
+ }
+ catch (LCFException e)
+ {
+ Logging.misc.error("Error shutting down API service: "+e.getMessage(),e);
+ }
+ super.destroy();
+ }
+
+ /** The get method.
+ */
+ protected void doGet(HttpServletRequest request, HttpServletResponse response)
+ throws ServletException, IOException
+ {
+ try
+ {
+ // Set up the environment
+ LCF.initializeEnvironment();
+
+ // Mint a thread context
+ IThreadContext tc = ThreadContextFactory.make();
+
+ // Get the path info string. This will furnish the command.
+ String pathInfo = request.getPathInfo();
+
+ // The first field of the pathInfo string is the protocol. Someday this will be a dispatcher using reflection. Right now, we only support json, so a quick check is fine.
+ if (pathInfo == null)
+ {
+ response.sendError(response.SC_BAD_REQUEST,"Unknown API protocol");
+ return;
+ }
+
+ // Strip off leading "/"
+ if (pathInfo.startsWith("/"))
+ pathInfo = pathInfo.substring(1);
+
+ int index = pathInfo.indexOf("/");
+ String protocol;
+ String command;
+ if (index == -1)
+ {
+ protocol = pathInfo;
+ command = "";
+ }
+ else
+ {
+ protocol = pathInfo.substring(0,index);
+ command = pathInfo.substring(index+1);
+ }
+
+ // Handle multipart forms
+ IPostParameters parameters = new org.apache.lcf.ui.multipart.MultipartWrapper(request);
+
+ // Input
+ String argument = parameters.getParameter("object");
+ // Output
+ String outputText = null;
+
+ if (protocol.equals("json"))
+ {
+ // Parse the input argument, if it is present
+ Configuration input;
+ if (argument != null)
+ {
+ input = new Argument();
+ input.fromJSON(argument);
+ }
+ else
+ input = null;
+
+ Configuration output = LCF.executeCommand(tc,command,input);
+
+ // Format the response
+ outputText = output.toJSON();
+ }
+ else
+ {
+ response.sendError(response.SC_BAD_REQUEST,"Unknown API protocol: "+protocol);
+ return;
+ }
+
+ byte[] responseValue = outputText.getBytes("utf-8");
+
+ // Set response mime type
+ response.setContentType("text/plain; charset=utf-8");
+ response.setIntHeader("Content-Length", (int)responseValue.length);
+ ServletOutputStream out = response.getOutputStream();
+ try
+ {
+ out.write(responseValue,0,responseValue.length);
+ out.flush();
+ }
+ finally
+ {
+ out.close();
+ }
+ }
+ catch (java.io.UnsupportedEncodingException e)
+ {
+ //Logging.authorityService.error("Unsupported encoding: "+e.getMessage(),e);
+ throw new ServletException("Fatal error occurred: "+e.getMessage(),e);
+ }
+ catch (LCFException e)
+ {
+ //Logging.authorityService.error("API servlet error: "+e.getMessage(),e);
+ response.sendError(response.SC_INTERNAL_SERVER_ERROR,e.getMessage());
+ }
+ }
+
+}
Propchange: incubator/lcf/trunk/modules/framework/api/org/apache/lcf/api/APIServlet.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: incubator/lcf/trunk/modules/framework/api/org/apache/lcf/api/APIServlet.java
------------------------------------------------------------------------------
svn:keywords = Id
Added: incubator/lcf/trunk/modules/framework/api/org/apache/lcf/api/Argument.java
URL: http://svn.apache.org/viewvc/incubator/lcf/trunk/modules/framework/api/org/apache/lcf/api/Argument.java?rev=964035&view=auto
==============================================================================
--- incubator/lcf/trunk/modules/framework/api/org/apache/lcf/api/Argument.java (added)
+++ incubator/lcf/trunk/modules/framework/api/org/apache/lcf/api/Argument.java Wed Jul 14 12:55:26 2010
@@ -0,0 +1,54 @@
+/* $Id$ */
+
+/**
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+package org.apache.lcf.api;
+
+import org.apache.lcf.core.interfaces.*;
+import java.util.*;
+import java.io.*;
+
+/** This class represents a specification, which is a generalized hierarchy of nodes that
+* can be interpreted by an appropriate connector in an appropriate way.
+*/
+public class Argument extends Configuration
+{
+ public static final String _rcsid = "@(#)$Id$";
+
+ /** Constructor.
+ */
+ public Argument()
+ {
+ super();
+ }
+
+ /** Return the root node type.
+ *@return the node type name.
+ */
+ protected String getRootNodeLabel()
+ {
+ return "object";
+ }
+
+ /** Create a new object of the appropriate class.
+ */
+ protected Configuration createNew()
+ {
+ return new Argument();
+ }
+
+}
Propchange: incubator/lcf/trunk/modules/framework/api/org/apache/lcf/api/Argument.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: incubator/lcf/trunk/modules/framework/api/org/apache/lcf/api/Argument.java
------------------------------------------------------------------------------
svn:keywords = Id
Modified: incubator/lcf/trunk/modules/framework/build.xml
URL: http://svn.apache.org/viewvc/incubator/lcf/trunk/modules/framework/build.xml?rev=964035&r1=964034&r2=964035&view=diff
==============================================================================
--- incubator/lcf/trunk/modules/framework/build.xml (original)
+++ incubator/lcf/trunk/modules/framework/build.xml Wed Jul 14 12:55:26 2010
@@ -98,6 +98,20 @@
</javac>
</target>
+ <target name="compile-api" depends="compile-core,compile-ui-core,compile-agents,compile-pull-agent">
+ <mkdir dir="build/api/classes"/>
+ <javac srcdir="api" destdir="build/api/classes" target="1.5" source="1.4" debug="true" debuglevel="lines,vars,source">
+ <classpath>
+ <fileset dir="lib">
+ <include name="*.jar"/>
+ </fileset>
+ <pathelement location="build/core/classes"/>
+ <pathelement location="build/ui-core/classes"/>
+ <pathelement location="build/agents/classes"/>
+ <pathelement location="build/pull-agent/classes"/>
+ </classpath>
+ </javac>
+ </target>
<target name="compile-crawler-ui" depends="compile-core,compile-ui-core,compile-agents,compile-pull-agent">
<!-- Define the jsp compilation task using tomcat libraries -->
@@ -173,6 +187,7 @@
<include name="commons-io*.jar"/>
<include name="commons-logging*.jar"/>
<include name="jdbcpool-0.99.jar"/>
+ <include name="json.jar"/>
<include name="log4j*.jar"/>
<include name="serializer*.jar"/>
<include name="xalan*.jar"/>
@@ -193,7 +208,42 @@
</copy>
<jar destfile="build/webapp/authority-service/WEB-INF/lib/lcf-authority-servlet.jar" basedir="build/authority-service/classes"/>
</target>
-
+
+ <target name="webapp-api" depends="jar-core,jar-ui-core,jar-agents,jar-pull-agent,compile-api">
+ <mkdir dir="build/webapp/api/WEB-INF/lib"/>
+ <copy todir="build/webapp/api/WEB-INF/lib">
+ <fileset dir="lib">
+ <include name="commons-codec*.jar"/>
+ <include name="commons-collections*.jar"/>
+ <include name="commons-el*.jar"/>
+ <include name="commons-fileupload*.jar"/>
+ <include name="commons-httpclient-lcf.jar"/>
+ <include name="commons-io*.jar"/>
+ <include name="commons-logging*.jar"/>
+ <include name="jdbcpool-0.99.jar"/>
+ <include name="json.jar"/>
+ <include name="log4j*.jar"/>
+ <include name="serializer*.jar"/>
+ <include name="xalan*.jar"/>
+ <include name="xercesImpl-lcf.jar"/>
+ <include name="xml-apis*.jar"/>
+ </fileset>
+ <fileset dir="lib">
+ <include name="postgresql*.jar"/>
+ <include name="derby*.jar"/>
+ </fileset>
+ </copy>
+ <copy todir="build/webapp/api/WEB-INF/lib">
+ <fileset dir="build/jar">
+ <include name="lcf-core.jar"/>
+ <include name="lcf-ui-core.jar"/>
+ <include name="lcf-agents.jar"/>
+ <include name="lcf-pull-agent.jar"/>
+ </fileset>
+ </copy>
+ <jar destfile="build/webapp/api/WEB-INF/lib/lcf-api-servlet.jar" basedir="build/api/classes"/>
+ </target>
+
<target name="webapp-crawler-ui" depends="compile-crawler-ui,jar-core,jar-ui-core,jar-agents,jar-pull-agent">
<mkdir dir="build/webapp/crawler-ui/WEB-INF/lib"/>
<copy todir="build/webapp/crawler-ui/WEB-INF/lib">
@@ -211,6 +261,7 @@
<include name="commons-io*.jar"/>
<include name="commons-logging*.jar"/>
<include name="jdbcpool-0.99.jar"/>
+ <include name="json.jar"/>
<include name="log4j*.jar"/>
<include name="serializer*.jar"/>
<include name="xalan*.jar"/>
@@ -245,7 +296,12 @@
<mkdir dir="dist/web/war"/>
<war destfile="dist/web/war/lcf-authority-service.war" webxml="authority-service/WEB-INF/web.xml" basedir="build/webapp/authority-service"/>
</target>
-
+
+ <target name="war-api" depends="webapp-api">
+ <mkdir dir="dist/web/war"/>
+ <war destfile="dist/web/war/lcf-api.war" webxml="api/WEB-INF/web.xml" basedir="build/webapp/api"/>
+ </target>
+
<target name="war-crawler-ui" depends="webapp-crawler-ui">
<mkdir dir="dist/web/war"/>
<war destfile="dist/web/war/lcf-crawler-ui.war" webxml="crawler-ui/WEB-INF/web.xml" basedir="build/webapp/crawler-ui"/>
@@ -263,6 +319,7 @@
<include name="commons-io*.jar"/>
<include name="commons-logging*.jar"/>
<include name="jdbcpool-0.99.jar"/>
+ <include name="json.jar"/>
<include name="log4j*.jar"/>
<include name="serializer*.jar"/>
<include name="servlet-api*.jar"/>
@@ -288,7 +345,7 @@
</copy>
</target>
- <target name="example" depends="war-crawler-ui,war-authority-service,jar-jetty-runner,jar-core,jar-agents,jar-pull-agent">
+ <target name="example" depends="war-crawler-ui,war-api,war-authority-service,jar-jetty-runner,jar-core,jar-agents,jar-pull-agent">
<mkdir dir="dist/example/lib"/>
<copy todir="dist/example/lib">
<fileset dir="lib">
@@ -303,6 +360,7 @@
<include name="jasper*.jar"/>
<include name="jdbcpool-0.99.jar"/>
<include name="jetty*.jar"/>
+ <include name="json.jar"/>
<include name="jsp-api*.jar"/>
<include name="jsp-2.5*.jar"/>
<include name="log4j*.jar"/>
@@ -342,7 +400,7 @@
</copy>
</target>
- <target name="compile-tests" depends="compile-core,compile-ui-core,compile-agents,compile-pull-agent,compile-authority-service">
+ <target name="compile-tests" depends="compile-core,compile-ui-core,compile-agents,compile-pull-agent,compile-authority-service,compile-api">
<mkdir dir="build/tests/classes"/>
<javac srcdir="tests" destdir="build/tests/classes" target="1.5" source="1.5" debug="true" debuglevel="lines,vars,source">
<classpath>
@@ -354,6 +412,7 @@
<pathelement location="build/agents/classes"/>
<pathelement location="build/pull-agent/classes"/>
<pathelement location="build/authority-service/classes"/>
+ <pathelement location="build/api/classes"/>
</classpath>
</javac>
</target>
@@ -384,6 +443,7 @@
<pathelement location="build/agents/classes"/>
<pathelement location="build/pull-agent/classes"/>
<pathelement location="build/authority-service/classes"/>
+ <pathelement location="build/api/classes"/>
<pathelement location="build/tests/classes"/>
</classpath>
<test name="org.apache.lcf.agents.tests.Sanity" todir="test-output"/>
@@ -392,6 +452,6 @@
</junit>
</target>
- <target name="all" depends="processes,war-authority-service,war-crawler-ui,example,doc,tests,run-tests"/>
+ <target name="all" depends="processes,war-authority-service,war-crawler-ui,war-api,example,doc,tests,run-tests"/>
</project>
Modified: incubator/lcf/trunk/modules/framework/core/org/apache/lcf/core/interfaces/ConfigNode.java
URL: http://svn.apache.org/viewvc/incubator/lcf/trunk/modules/framework/core/org/apache/lcf/core/interfaces/ConfigNode.java?rev=964035&r1=964034&r2=964035&view=diff
==============================================================================
--- incubator/lcf/trunk/modules/framework/core/org/apache/lcf/core/interfaces/ConfigNode.java (original)
+++ incubator/lcf/trunk/modules/framework/core/org/apache/lcf/core/interfaces/ConfigNode.java Wed Jul 14 12:55:26 2010
@@ -35,12 +35,26 @@ public class ConfigNode extends Configur
super(type);
}
+ /** Copy constructor.
+ */
+ public ConfigNode(ConfigurationNode source)
+ {
+ super(source);
+ }
+
/** Create a new node of this same type and class.
*/
protected ConfigurationNode createNewNode()
{
return new ConfigNode(type);
}
+
+ /** Make a new node that is a copy of the specified node.
+ */
+ protected ConfigurationNode createNewNode(ConfigurationNode source)
+ {
+ return new ConfigNode(source);
+ }
/** Duplicate.
*@return the duplicate.
Modified: incubator/lcf/trunk/modules/framework/core/org/apache/lcf/core/interfaces/Configuration.java
URL: http://svn.apache.org/viewvc/incubator/lcf/trunk/modules/framework/core/org/apache/lcf/core/interfaces/Configuration.java?rev=964035&r1=964034&r2=964035&view=diff
==============================================================================
--- incubator/lcf/trunk/modules/framework/core/org/apache/lcf/core/interfaces/Configuration.java (original)
+++ incubator/lcf/trunk/modules/framework/core/org/apache/lcf/core/interfaces/Configuration.java Wed Jul 14 12:55:26 2010
@@ -23,6 +23,7 @@ import java.util.*;
import java.io.*;
import org.apache.lcf.core.system.LCF;
import org.apache.lcf.core.common.XMLDoc;
+import org.json.*;
/** This class represents XML configuration information, in its most basic incarnation.
*/
@@ -30,6 +31,12 @@ public abstract class Configuration
{
public static final String _rcsid = "@(#)$Id$";
+ // JSON special key values
+
+ protected static final String JSON_ATTRIBUTE = "_attribute_";
+ protected static final String JSON_VALUE = "_value_";
+
+
// The children
protected ArrayList children = new ArrayList();
// Read-only flag
@@ -139,7 +146,7 @@ public abstract class Configuration
}
/** Get as XML
- *@return the xml corresponding to these ConfigParams.
+ *@return the xml corresponding to these Configuration.
*/
public String toXML()
throws LCFException
@@ -158,6 +165,35 @@ public abstract class Configuration
return doc.getXML();
}
+ /** Get as JSON.
+ *@return the json corresponding to this Configuration.
+ */
+ public String toJSON()
+ throws LCFException
+ {
+ try
+ {
+ JSONWriter writer = new JSONStringer();
+ writer.object();
+ // We do NOT use the root node label, unlike XML.
+ // Now, go through all children
+ int i = 0;
+ while (i < children.size())
+ {
+ ConfigurationNode node = (ConfigurationNode)children.get(i++);
+ writeNode(writer,node,true);
+ }
+ writer.endObject();
+
+ // Convert to a string.
+ return writer.toString();
+ }
+ catch (JSONException e)
+ {
+ throw new LCFException(e.getMessage(),e);
+ }
+ }
+
/** Write a specification node.
*@param doc is the document.
*@param parent is the parent.
@@ -190,6 +226,103 @@ public abstract class Configuration
}
}
+
+ /** Write a JSON specification node.
+ *@param writer is the JSON writer.
+ *@param node is the node.
+ *@param writeKey is true if the key needs to be written, false otherwise.
+ */
+ protected static void writeNode(JSONWriter writer, ConfigurationNode node, boolean writeKey)
+ throws LCFException
+ {
+ try
+ {
+ // Node types correspond directly to keys. Attributes correspond to "_attribute_<attribute_name>".
+ // Get the type
+ if (writeKey)
+ {
+ String type = node.getType();
+ writer.key(type);
+ }
+ // Problem: Two ways of handling a naked 'value'. First way is to NOT presume a nested object is needed. Second way is to require a nested
+ // object. On reconstruction, the right thing will happen, and a naked value will become a node with a value, while an object will become
+ // a node that has an optional "_value_" key inside it.
+ String value = node.getValue();
+ if (value != null && node.getAttributeCount() == 0 && node.getChildCount() == 0)
+ {
+ writer.value(value);
+ }
+ else
+ {
+ writer.object();
+
+ if (value != null)
+ {
+ writer.key(JSON_VALUE);
+ writer.value(value);
+ }
+
+ Iterator iter = node.getAttributes();
+ while (iter.hasNext())
+ {
+ String attribute = (String)iter.next();
+ String attrValue = node.getAttributeValue(attribute);
+ writer.key(JSON_ATTRIBUTE+attribute);
+ writer.value(attrValue);
+ }
+
+ // Now, do children. To get the arrays right, we need to glue together all children with the
+ // same type, which requires us to do an appropriate pass to gather that stuff together.
+ Map childMap = new HashMap();
+ int i = 0;
+ while (i < node.getChildCount())
+ {
+ ConfigurationNode child = node.findChild(i++);
+ String key = child.getType();
+ ArrayList list = (ArrayList)childMap.get(key);
+ if (list == null)
+ {
+ list = new ArrayList();
+ childMap.put(key,list);
+ }
+ list.add(child);
+ }
+
+ iter = childMap.keySet().iterator();
+ while (iter.hasNext())
+ {
+ String key = (String)iter.next();
+ ArrayList list = (ArrayList)childMap.get(key);
+ if (list.size() > 1)
+ {
+ // Write the key
+ writer.key(key);
+ // Write it as an array
+ writer.array();
+ i = 0;
+ while (i < list.size())
+ {
+ ConfigurationNode child = (ConfigurationNode)list.get(i++);
+ writeNode(writer,child,false);
+ }
+ writer.endArray();
+ }
+ else
+ {
+ // Write it as a singleton
+ writeNode(writer,(ConfigurationNode)list.get(0),true);
+ }
+ }
+
+ writer.endObject();
+ }
+ }
+ catch (JSONException e)
+ {
+ throw new LCFException(e.getMessage(),e);
+ }
+ }
+
/** Read from XML.
*@param xml is the input XML.
*/
@@ -200,6 +333,134 @@ public abstract class Configuration
initializeFromDoc(doc);
}
+ /** Read from JSON.
+ *@param json is the input JSON.
+ */
+ public void fromJSON(String json)
+ throws LCFException
+ {
+ if (readOnly)
+ throw new IllegalStateException("Attempt to change read-only object");
+
+ clearChildren();
+ try
+ {
+ JSONObject object = new JSONObject(json);
+ // Convert the object into our configuration
+ Iterator iter = object.keys();
+ while (iter.hasNext())
+ {
+ String key = (String)iter.next();
+ Object x = object.opt(key);
+ if (x instanceof JSONArray)
+ {
+ // Iterate through.
+ JSONArray array = (JSONArray)x;
+ int i = 0;
+ while (i < array.length())
+ {
+ x = array.opt(i++);
+ processObject(key,x);
+ }
+ }
+ else
+ processObject(key,x);
+ }
+ }
+ catch (JSONException e)
+ {
+ throw new LCFException("Json syntax error - "+e.getMessage(),e);
+ }
+ }
+
+ /** Process a JSON object */
+ protected void processObject(String key, Object x)
+ {
+ if (x instanceof JSONObject)
+ {
+ // Nested single object
+ ConfigurationNode cn = readNode(key,(JSONObject)x);
+ addChild(getChildCount(),cn);
+ }
+ else if (x == JSONObject.NULL)
+ {
+ // Null object. Don't enter the key.
+ }
+ else
+ {
+ // It's a string or a number or some scalar value
+ String value = x.toString();
+ ConfigurationNode cn = createNewNode(key);
+ cn.setValue(value);
+ addChild(getChildCount(),cn);
+ }
+ }
+
+ /** Read a node from a json object */
+ protected ConfigurationNode readNode(String key, JSONObject object)
+ {
+ ConfigurationNode rval = createNewNode(key);
+ Iterator iter = object.keys();
+ while (iter.hasNext())
+ {
+ String nestedKey = (String)iter.next();
+ Object x = object.opt(nestedKey);
+ if (x instanceof JSONArray)
+ {
+ // Iterate through.
+ JSONArray array = (JSONArray)x;
+ int i = 0;
+ while (i < array.length())
+ {
+ x = array.opt(i++);
+ processObject(rval,nestedKey,x);
+ }
+ }
+ else
+ processObject(rval,nestedKey,x);
+ }
+ return rval;
+ }
+
+ /** Process a JSON object */
+ protected void processObject(ConfigurationNode cn, String key, Object x)
+ {
+ if (x instanceof JSONObject)
+ {
+ // Nested single object
+ ConfigurationNode nestedCn = readNode(key,(JSONObject)x);
+ cn.addChild(cn.getChildCount(),nestedCn);
+ }
+ else if (x == JSONObject.NULL)
+ {
+ // Null object. Don't enter the key.
+ }
+ else
+ {
+ // It's a string or a number or some scalar value
+ String value = x.toString();
+ // Is it an attribute, or a value?
+ if (key.startsWith(JSON_ATTRIBUTE))
+ {
+ // Attribute. Set the attribute in the current node.
+ cn.setAttribute(key.substring(JSON_ATTRIBUTE.length()),value);
+ }
+ else if (key.equals(JSON_VALUE))
+ {
+ // Value. Set the value in the current node.
+ cn.setValue(value);
+ }
+ else
+ {
+ // Something we don't recognize, which can only be a simplified key/value pair.
+ // Create a child node representing the key/value pair.
+ ConfigurationNode nestedCn = createNewNode(key);
+ nestedCn.setValue(value);
+ cn.addChild(cn.getChildCount(),nestedCn);
+ }
+ }
+ }
+
/** Read from an XML binary stream.
*@param xmlstream is the input XML stream. Does NOT close the stream.
*/
Modified: incubator/lcf/trunk/modules/framework/core/org/apache/lcf/core/interfaces/ConfigurationNode.java
URL: http://svn.apache.org/viewvc/incubator/lcf/trunk/modules/framework/core/org/apache/lcf/core/interfaces/ConfigurationNode.java?rev=964035&r1=964034&r2=964035&view=diff
==============================================================================
--- incubator/lcf/trunk/modules/framework/core/org/apache/lcf/core/interfaces/ConfigurationNode.java (original)
+++ incubator/lcf/trunk/modules/framework/core/org/apache/lcf/core/interfaces/ConfigurationNode.java Wed Jul 14 12:55:26 2010
@@ -43,6 +43,28 @@ public class ConfigurationNode
this.type = type;
}
+ /** Duplication constructor.
+ */
+ public ConfigurationNode(ConfigurationNode source)
+ {
+ this.type = source.type;
+ this.value = source.value;
+ this.readOnly = source.readOnly;
+ Iterator iter = source.attributes.keySet().iterator();
+ while (iter.hasNext())
+ {
+ String attribute = (String)iter.next();
+ String attrValue = (String)source.attributes.get(attribute);
+ this.attributes.put(attribute,attrValue);
+ }
+ int i = 0;
+ while (i < source.getChildCount())
+ {
+ ConfigurationNode child = source.findChild(i++);
+ this.addChild(this.getChildCount(),createNewNode(child));
+ }
+ }
+
/** Make a new blank node identical in type and class to the current node.
*@return the new node.
*/
@@ -50,7 +72,14 @@ public class ConfigurationNode
{
return new ConfigurationNode(type);
}
-
+
+ /** Make a new node that is a copy of the specified node.
+ */
+ protected ConfigurationNode createNewNode(ConfigurationNode source)
+ {
+ return new ConfigurationNode(source);
+ }
+
/** Make this node (and its children) read-only
*/
public void makeReadOnly()
@@ -109,6 +138,8 @@ public class ConfigurationNode
{
if (readOnly)
throw new IllegalStateException("Attempt to change read-only object");
+ if (value != null && value.length() == 0)
+ value = null;
this.value = value;
}
@@ -144,7 +175,14 @@ public class ConfigurationNode
*/
public void removeChild(int index)
{
- children.remove(index);
+ if (readOnly)
+ throw new IllegalStateException("Attempt to change read-only object");
+ if (children != null)
+ {
+ children.remove(index);
+ if (children.size() == 0)
+ children = null;
+ }
}
/** Add child at specified position.
@@ -153,6 +191,9 @@ public class ConfigurationNode
*/
public void addChild(int index, ConfigurationNode child)
{
+ if (readOnly)
+ throw new IllegalStateException("Attempt to change read-only object");
+
if (children == null)
children = new ArrayList();
children.add(index,child);
@@ -169,7 +210,11 @@ public class ConfigurationNode
if (value == null)
{
if (attributes != null)
+ {
attributes.remove(attribute);
+ if (attributes.size() == 0)
+ attributes = null;
+ }
}
else
{
@@ -179,6 +224,17 @@ public class ConfigurationNode
}
}
+ /** Get the attribute count.
+ *@return the attribute count.
+ */
+ public int getAttributeCount()
+ {
+ if (attributes == null)
+ return 0;
+ else
+ return attributes.size();
+ }
+
/** Iterate over attributes.
*@return the attribute iterator.
*/
Modified: incubator/lcf/trunk/modules/framework/core/org/apache/lcf/core/interfaces/SpecificationNode.java
URL: http://svn.apache.org/viewvc/incubator/lcf/trunk/modules/framework/core/org/apache/lcf/core/interfaces/SpecificationNode.java?rev=964035&r1=964034&r2=964035&view=diff
==============================================================================
--- incubator/lcf/trunk/modules/framework/core/org/apache/lcf/core/interfaces/SpecificationNode.java (original)
+++ incubator/lcf/trunk/modules/framework/core/org/apache/lcf/core/interfaces/SpecificationNode.java Wed Jul 14 12:55:26 2010
@@ -35,12 +35,26 @@ public class SpecificationNode extends C
super(type);
}
+ /** Copy constructor.
+ */
+ public SpecificationNode(ConfigurationNode source)
+ {
+ super(source);
+ }
+
/** Create a new node of this same type and class.
*/
protected ConfigurationNode createNewNode()
{
return new SpecificationNode(type);
}
+
+ /** Make a new node that is a copy of the specified node.
+ */
+ protected ConfigurationNode createNewNode(ConfigurationNode source)
+ {
+ return new SpecificationNode(source);
+ }
/** Duplicate.
*@return the duplicate.
Modified: incubator/lcf/trunk/modules/framework/jetty-runner/org/apache/lcf/jettyrunner/LCFJettyRunner.java
URL: http://svn.apache.org/viewvc/incubator/lcf/trunk/modules/framework/jetty-runner/org/apache/lcf/jettyrunner/LCFJettyRunner.java?rev=964035&r1=964034&r2=964035&view=diff
==============================================================================
--- incubator/lcf/trunk/modules/framework/jetty-runner/org/apache/lcf/jettyrunner/LCFJettyRunner.java (original)
+++ incubator/lcf/trunk/modules/framework/jetty-runner/org/apache/lcf/jettyrunner/LCFJettyRunner.java Wed Jul 14 12:55:26 2010
@@ -63,7 +63,7 @@ public class LCFJettyRunner
protected Server server;
- public LCFJettyRunner( int port, String crawlerWarPath, String authorityServiceWarPath )
+ public LCFJettyRunner( int port, String crawlerWarPath, String authorityServiceWarPath, String apiWarPath )
{
server = new Server( port );
server.setStopAtShutdown( true );
@@ -77,6 +77,9 @@ public class LCFJettyRunner
// This will cause jetty to ignore all of the framework and jdbc jars in the war, which is what we want.
lcfAuthorityService.setParentLoaderPriority(true);
server.addHandler(lcfAuthorityService);
+ WebAppContext lcfApi = new WebAppContext(apiWarPath,"/lcf-api");
+ lcfApi.setParentLoaderPriority(true);
+ server.addHandler(lcfApi);
}
public void start()
@@ -138,9 +141,9 @@ public class LCFJettyRunner
*/
public static void main( String[] args )
{
- if (args.length != 3 && args.length != 1 && args.length != 0)
+ if (args.length != 4 && args.length != 1 && args.length != 0)
{
- System.err.println("Usage: LCFJettyRunner [<port> [<crawler-war-path> <authority-service-war-path>]]");
+ System.err.println("Usage: LCFJettyRunner [<port> [<crawler-war-path> <authority-service-war-path> <api-war-path>]]");
System.exit(1);
}
@@ -160,10 +163,12 @@ public class LCFJettyRunner
String crawlerWarPath = "war/lcf-crawler-ui.war";
String authorityserviceWarPath = "war/lcf-authority-service.war";
- if (args.length == 3)
+ String apiWarPath = "war/lcf-api.war";
+ if (args.length == 4)
{
crawlerWarPath = args[1];
authorityserviceWarPath = args[2];
+ apiWarPath = args[3];
}
// Ready to begin in earnest...
@@ -404,7 +409,7 @@ public class LCFJettyRunner
System.err.println("Starting jetty...");
// Create a jetty instance
- LCFJettyRunner jetty = new LCFJettyRunner(jettyPort,crawlerWarPath,authorityserviceWarPath);
+ LCFJettyRunner jetty = new LCFJettyRunner(jettyPort,crawlerWarPath,authorityserviceWarPath,apiWarPath);
// This will register a shutdown hook as well.
jetty.start();
Modified: incubator/lcf/trunk/modules/framework/pull-agent/org/apache/lcf/crawler/system/LCF.java
URL: http://svn.apache.org/viewvc/incubator/lcf/trunk/modules/framework/pull-agent/org/apache/lcf/crawler/system/LCF.java?rev=964035&r1=964034&r2=964035&view=diff
==============================================================================
--- incubator/lcf/trunk/modules/framework/pull-agent/org/apache/lcf/crawler/system/LCF.java (original)
+++ incubator/lcf/trunk/modules/framework/pull-agent/org/apache/lcf/crawler/system/LCF.java Wed Jul 14 12:55:26 2010
@@ -983,5 +983,735 @@ public class LCF extends org.apache.lcf.
{
return outputActivityName+" ("+outputConnectionName+")";
}
+
+ // API support
+
+ protected static final String API_ERRORNODE = "error";
+ protected static final String API_JOBNODE = "job";
+ protected static final String API_JOBIDNODE = "job_id";
+
+ /** Execute specified command. Note that the command is a string, and that it is permitted to accept at most one argument, which
+ * will be a Configuration object, and return the same.
+ *@param tc is the thread context.
+ *@param command is the command.
+ *@param inputArgument is the (optional) argument.
+ *@return the response, which cannot be null.
+ */
+ public static Configuration executeCommand(IThreadContext tc, String command, Configuration inputArgument)
+ throws LCFException
+ {
+ Configuration rval = new ResponseValue();
+ if (command.equals("job/list"))
+ {
+ IJobManager jobManager = JobManagerFactory.make(tc);
+ IJobDescription[] jobs = jobManager.getAllJobs();
+ int i = 0;
+ while (i < jobs.length)
+ {
+ ConfigurationNode job = formatJobDescription(API_JOBNODE,jobs[i++]);
+ rval.addChild(rval.getChildCount(),job);
+ }
+ }
+ else if (command.equals("job/get"))
+ {
+ // Get the job id from the argument
+ if (inputArgument == null)
+ {
+ ConfigurationNode error = new ConfigurationNode(API_ERRORNODE);
+ error.setValue("Input argument required");
+ rval.addChild(rval.getChildCount(),error);
+ return rval;
+ }
+
+ String jobID = getRootArgument(inputArgument,API_JOBIDNODE);
+ if (jobID == null)
+ {
+ ConfigurationNode error = new ConfigurationNode(API_ERRORNODE);
+ error.setValue("Input argument must have '"+API_JOBIDNODE+"' field");
+ rval.addChild(rval.getChildCount(),error);
+ return rval;
+ }
+
+ IJobManager jobManager = JobManagerFactory.make(tc);
+ IJobDescription job = jobManager.load(new Long(jobID));
+ if (job != null)
+ {
+ // Fill the return object with job information
+ ConfigurationNode jobNode = formatJobDescription(API_JOBNODE,job);
+ rval.addChild(rval.getChildCount(),jobNode);
+ }
+ }
+ else if (command.equals("job/save"))
+ {
+ // Get the job from the argument
+ if (inputArgument == null)
+ {
+ ConfigurationNode error = new ConfigurationNode(API_ERRORNODE);
+ error.setValue("Input argument required");
+ rval.addChild(rval.getChildCount(),error);
+ return rval;
+ }
+
+ ConfigurationNode jobNode = findConfigurationNode(inputArgument,API_JOBNODE);
+ if (jobNode == null)
+ {
+ ConfigurationNode error = new ConfigurationNode(API_ERRORNODE);
+ error.setValue("Input argument must have '"+API_JOBNODE+"' field");
+ rval.addChild(rval.getChildCount(),error);
+ return rval;
+ }
+
+ // Turn the configuration node into a JobDescription
+ IJobDescription job = readJobDescription(tc,jobNode);
+
+ // Save the job.
+ IJobManager jobManager = JobManagerFactory.make(tc);
+ jobManager.save(job);
+ }
+ else if (command.equals("job/delete"))
+ {
+ // Get the job id from the argument
+ if (inputArgument == null)
+ {
+ ConfigurationNode error = new ConfigurationNode(API_ERRORNODE);
+ error.setValue("Input argument required");
+ rval.addChild(rval.getChildCount(),error);
+ return rval;
+ }
+
+ String jobID = getRootArgument(inputArgument,API_JOBIDNODE);
+ if (jobID == null)
+ {
+ ConfigurationNode error = new ConfigurationNode(API_ERRORNODE);
+ error.setValue("Input argument must have '"+API_JOBIDNODE+"' field");
+ rval.addChild(rval.getChildCount(),error);
+ return rval;
+ }
+
+ IJobManager jobManager = JobManagerFactory.make(tc);
+ jobManager.deleteJob(new Long(jobID));
+ }
+ else if (command.equals("jobstatus/list"))
+ {
+ }
+ else if (command.equals("jobstatus/start"))
+ {
+ }
+ else if (command.equals("jobstatus/abort"))
+ {
+ }
+ else if (command.equals("jobstatus/restart"))
+ {
+ }
+ else if (command.equals("jobstatus/pause"))
+ {
+ }
+ else if (command.equals("jobstatus/resume"))
+ {
+ }
+ else if (command.equals("outputconnection/list"))
+ {
+ }
+ else if (command.equals("outputconnection/get"))
+ {
+ }
+ else if (command.equals("outputconnection/save"))
+ {
+ }
+ else if (command.equals("outputconnection/delete"))
+ {
+ }
+ else if (command.equals("outputconnection/checkstatus"))
+ {
+ }
+ else if (command.equals("repositoryconnection/list"))
+ {
+ }
+ else if (command.equals("repositoryconnection/get"))
+ {
+ }
+ else if (command.equals("repositoryconnection/save"))
+ {
+ }
+ else if (command.equals("repositoryconnection/delete"))
+ {
+ }
+ else if (command.equals("repositoryconnection/checkstatus"))
+ {
+ }
+ else if (command.equals("authorityconnection/list"))
+ {
+ }
+ else if (command.equals("authorityconnection/get"))
+ {
+ }
+ else if (command.equals("authorityconnection/save"))
+ {
+ }
+ else if (command.equals("authorityconnection/delete"))
+ {
+ }
+ else if (command.equals("authorityconnection/checkstatus"))
+ {
+ }
+ else if (command.equals("report/documentstatus"))
+ {
+ }
+ else if (command.equals("report/queuestatus"))
+ {
+ }
+ else if (command.equals("report/simplehistory"))
+ {
+ }
+ else if (command.equals("report/maximumbandwidth"))
+ {
+ }
+ else if (command.equals("report/maximumactivity"))
+ {
+ }
+ else if (command.equals("report/resultsummary"))
+ {
+ }
+ else
+ {
+ ConfigurationNode error = new ConfigurationNode(API_ERRORNODE);
+ error.setValue("Unrecognized command: "+command);
+ rval.addChild(rval.getChildCount(),error);
+ }
+ return rval;
+ }
+
+ // Job node types
+ protected static final String JOBNODE_ID = "id";
+ protected static final String JOBNODE_DESCRIPTION = "description";
+ protected static final String JOBNODE_CONNECTIONNAME = "repository_connection";
+ protected static final String JOBNODE_OUTPUTNAME = "output_connection";
+ protected static final String JOBNODE_DOCUMENTSPECIFICATION = "document_specification";
+ protected static final String JOBNODE_OUTPUTSPECIFICATION = "output_specification";
+ protected static final String JOBNODE_STARTMODE = "start_mode";
+ protected static final String JOBNODE_RUNMODE = "run_mode";
+ protected static final String JOBNODE_HOPCOUNTMODE = "hopcount_mode";
+ protected static final String JOBNODE_PRIORITY = "priority";
+ protected static final String JOBNODE_RECRAWLINTERVAL = "recrawl_interval";
+ protected static final String JOBNODE_EXPIRATIONINTERVAL = "expiration_interval";
+ protected static final String JOBNODE_RESEEDINTERVAL = "reseed_interval";
+ protected static final String JOBNODE_SCHEDULE = "schedule";
+ protected static final String JOBNODE_RECORD = "record";
+ protected static final String JOBNODE_TIMEZONE = "timezone";
+ protected static final String JOBNODE_DURATION = "duration";
+ protected static final String JOBNODE_DAYOFWEEK = "dayofweek";
+ protected static final String JOBNODE_MONTHOFYEAR = "monthofyear";
+ protected static final String JOBNODE_DAYOFMONTH = "dayofmonth";
+ protected static final String JOBNODE_YEAR = "year";
+ protected static final String JOBNODE_HOUROFDAY = "hourofday";
+ protected static final String JOBNODE_MINUTESOFHOUR = "minutesofhour";
+ protected static final String JOBNODE_ENUMVALUE = "value";
+
+ /** Convert a node into a job description */
+ protected static IJobDescription readJobDescription(IThreadContext tc, ConfigurationNode jobNode)
+ throws LCFException
+ {
+ org.apache.lcf.crawler.jobs.JobDescription jobDescription = new org.apache.lcf.crawler.jobs.JobDescription();
+ // Walk through the node's children
+ int i = 0;
+ while (i < jobNode.getChildCount())
+ {
+ ConfigurationNode child = jobNode.findChild(i++);
+ String childType = child.getType();
+ if (childType.equals(JOBNODE_ID))
+ {
+ if (child.getValue() == null)
+ throw new LCFException("Job id node requires a value");
+ jobDescription.setID(new Long(child.getValue()));
+ }
+ else if (childType.equals(JOBNODE_DESCRIPTION))
+ {
+ jobDescription.setDescription(child.getValue());
+ }
+ else if (childType.equals(JOBNODE_CONNECTIONNAME))
+ {
+ jobDescription.setConnectionName(child.getValue());
+ }
+ else if (childType.equals(JOBNODE_OUTPUTNAME))
+ {
+ jobDescription.setOutputConnectionName(child.getValue());
+ }
+ else if (childType.equals(JOBNODE_DOCUMENTSPECIFICATION))
+ {
+ // Get the job's document specification, clear out the children, and copy new ones from the child.
+ DocumentSpecification ds = jobDescription.getSpecification();
+ ds.clearChildren();
+ int j = 0;
+ while (j < child.getChildCount())
+ {
+ ConfigurationNode cn = child.findChild(j++);
+ ds.addChild(ds.getChildCount(),new SpecificationNode(cn));
+ }
+ }
+ else if (childType.equals(JOBNODE_OUTPUTSPECIFICATION))
+ {
+ // Get the job's output specification, clear out the children, and copy new ones from the child.
+ OutputSpecification os = jobDescription.getOutputSpecification();
+ os.clearChildren();
+ int j = 0;
+ while (j < child.getChildCount())
+ {
+ ConfigurationNode cn = child.findChild(j++);
+ os.addChild(os.getChildCount(),new SpecificationNode(cn));
+ }
+ }
+ else if (childType.equals(JOBNODE_STARTMODE))
+ {
+ jobDescription.setStartMethod(mapToStartMode(child.getValue()));
+ }
+ else if (childType.equals(JOBNODE_RUNMODE))
+ {
+ jobDescription.setType(mapToRunMode(child.getValue()));
+ }
+ else if (childType.equals(JOBNODE_HOPCOUNTMODE))
+ {
+ jobDescription.setHopcountMode(mapToHopcountMode(child.getValue()));
+ }
+ else if (childType.equals(JOBNODE_PRIORITY))
+ {
+ try
+ {
+ jobDescription.setPriority(Integer.parseInt(child.getValue()));
+ }
+ catch (NumberFormatException e)
+ {
+ throw new LCFException(e.getMessage(),e);
+ }
+ }
+ else if (childType.equals(JOBNODE_RECRAWLINTERVAL))
+ {
+ jobDescription.setInterval(interpretInterval(child.getValue()));
+ }
+ else if (childType.equals(JOBNODE_EXPIRATIONINTERVAL))
+ {
+ jobDescription.setExpiration(interpretInterval(child.getValue()));
+ }
+ else if (childType.equals(JOBNODE_RESEEDINTERVAL))
+ {
+ jobDescription.setReseedInterval(interpretInterval(child.getValue()));
+ }
+ else if (childType.equals(JOBNODE_SCHEDULE))
+ {
+ // The children of this node should be schedule records. Walk through them.
+ int k = 0;
+ while (k < child.getChildCount())
+ {
+ ConfigurationNode scheduleNode = child.findChild(k++);
+ if (scheduleNode.getType().equals(JOBNODE_RECORD))
+ {
+ // Create a schedule record.
+ String timezone = null;
+ Long duration = null;
+ EnumeratedValues dayOfWeek = null;
+ EnumeratedValues monthOfYear = null;
+ EnumeratedValues dayOfMonth = null;
+ EnumeratedValues year = null;
+ EnumeratedValues hourOfDay = null;
+ EnumeratedValues minutesOfHour = null;
+
+ // Now, walk through children of the schedule node.
+ int q = 0;
+ while (q < scheduleNode.getChildCount())
+ {
+ ConfigurationNode scheduleField = scheduleNode.findChild(q++);
+ String fieldType = scheduleField.getType();
+ if (fieldType.equals(JOBNODE_TIMEZONE))
+ {
+ timezone = scheduleField.getValue();
+ }
+ else if (fieldType.equals(JOBNODE_DURATION))
+ {
+ duration = new Long(scheduleField.getValue());
+ }
+ else if (fieldType.equals(JOBNODE_DAYOFWEEK))
+ {
+ dayOfWeek = processEnumeratedValues(scheduleField);
+ }
+ else if (fieldType.equals(JOBNODE_MONTHOFYEAR))
+ {
+ monthOfYear = processEnumeratedValues(scheduleField);
+ }
+ else if (fieldType.equals(JOBNODE_YEAR))
+ {
+ year = processEnumeratedValues(scheduleField);
+ }
+ else if (fieldType.equals(JOBNODE_DAYOFMONTH))
+ {
+ dayOfMonth = processEnumeratedValues(scheduleField);
+ }
+ else if (fieldType.equals(JOBNODE_HOUROFDAY))
+ {
+ hourOfDay = processEnumeratedValues(scheduleField);
+ }
+ else if (fieldType.equals(JOBNODE_MINUTESOFHOUR))
+ {
+ minutesOfHour = processEnumeratedValues(scheduleField);
+ }
+ else
+ throw new LCFException("Unrecognized field in schedule record: '"+fieldType+"'");
+ }
+ ScheduleRecord sr = new ScheduleRecord(dayOfWeek,monthOfYear,dayOfMonth,year,hourOfDay,minutesOfHour,timezone,duration);
+ // Add the schedule record to the job.
+ jobDescription.addScheduleRecord(sr);
+ }
+ else
+ throw new LCFException("Encountered an unexpected node type in schedule: '"+scheduleNode.getType()+"'");
+ }
+ }
+ else
+ throw new LCFException("Unrecognized job field: '"+childType+"'");
+ }
+ if (jobDescription.getID() == null)
+ {
+ jobDescription.setID(new Long(IDFactory.make(tc)));
+ jobDescription.setIsNew(true);
+ }
+ else
+ jobDescription.setIsNew(false);
+ return jobDescription;
+ }
+
+ /** Convert a job description into a ConfigurationNode */
+ protected static ConfigurationNode formatJobDescription(String nodeType, IJobDescription job)
+ {
+ ConfigurationNode jobNode = new ConfigurationNode(nodeType);
+ // For each field of the job, add an appropriate child node, with value.
+ ConfigurationNode child;
+ int j;
+
+ // id
+ if (job.getID() != null)
+ {
+ child = new ConfigurationNode(JOBNODE_ID);
+ child.setValue(job.getID().toString());
+ jobNode.addChild(jobNode.getChildCount(),child);
+ }
+
+ // description
+ if (job.getDescription() != null)
+ {
+ child = new ConfigurationNode(JOBNODE_DESCRIPTION);
+ child.setValue(job.getDescription());
+ jobNode.addChild(jobNode.getChildCount(),child);
+ }
+
+ // connection
+ if (job.getConnectionName() != null)
+ {
+ child = new ConfigurationNode(JOBNODE_CONNECTIONNAME);
+ child.setValue(job.getConnectionName());
+ jobNode.addChild(jobNode.getChildCount(),child);
+ }
+
+ // output connection
+ if (job.getOutputConnectionName() != null)
+ {
+ child = new ConfigurationNode(JOBNODE_OUTPUTNAME);
+ child.setValue(job.getOutputConnectionName());
+ jobNode.addChild(jobNode.getChildCount(),child);
+ }
+
+ // Document specification
+ DocumentSpecification ds = job.getSpecification();
+ child = new ConfigurationNode(JOBNODE_DOCUMENTSPECIFICATION);
+ j = 0;
+ while (j < ds.getChildCount())
+ {
+ ConfigurationNode cn = ds.getChild(j++);
+ child.addChild(child.getChildCount(),cn);
+ }
+ jobNode.addChild(jobNode.getChildCount(),child);
+
+ // Output specification
+ OutputSpecification os = job.getOutputSpecification();
+ child = new ConfigurationNode(JOBNODE_OUTPUTSPECIFICATION);
+ j = 0;
+ while (j < os.getChildCount())
+ {
+ ConfigurationNode cn = os.getChild(j++);
+ child.addChild(child.getChildCount(),cn);
+ }
+ jobNode.addChild(jobNode.getChildCount(),child);
+
+ // Start mode
+ child = new ConfigurationNode(JOBNODE_STARTMODE);
+ child.setValue(startModeMap(job.getStartMethod()));
+ jobNode.addChild(jobNode.getChildCount(),child);
+
+ // Run mode
+ child = new ConfigurationNode(JOBNODE_RUNMODE);
+ child.setValue(runModeMap(job.getType()));
+ jobNode.addChild(jobNode.getChildCount(),child);
+
+ // Hopcount mode
+ child = new ConfigurationNode(JOBNODE_HOPCOUNTMODE);
+ child.setValue(hopcountModeMap(job.getHopcountMode()));
+ jobNode.addChild(jobNode.getChildCount(),child);
+
+ // Priority
+ child = new ConfigurationNode(JOBNODE_PRIORITY);
+ child.setValue(Integer.toString(job.getPriority()));
+ jobNode.addChild(jobNode.getChildCount(),child);
+
+ // Recrawl interval
+ if (job.getInterval() != null)
+ {
+ child = new ConfigurationNode(JOBNODE_RECRAWLINTERVAL);
+ child.setValue(job.getInterval().toString());
+ jobNode.addChild(jobNode.getChildCount(),child);
+ }
+
+ // Expiration interval
+ if (job.getExpiration() != null)
+ {
+ child = new ConfigurationNode(JOBNODE_EXPIRATIONINTERVAL);
+ child.setValue(job.getExpiration().toString());
+ jobNode.addChild(jobNode.getChildCount(),child);
+ }
+
+ // Reseed interval
+ if (job.getReseedInterval() != null)
+ {
+ child = new ConfigurationNode(JOBNODE_RESEEDINTERVAL);
+ child.setValue(job.getReseedInterval().toString());
+ jobNode.addChild(jobNode.getChildCount(),child);
+ }
+
+ // Schedule records
+ child = new ConfigurationNode(JOBNODE_SCHEDULE);
+ j = 0;
+ while (j < job.getScheduleRecordCount())
+ {
+ ScheduleRecord sr = job.getScheduleRecord(j++);
+ ConfigurationNode recordNode = new ConfigurationNode(JOBNODE_RECORD);
+ ConfigurationNode recordChild;
+
+ // timezone
+ if (sr.getTimezone() != null)
+ {
+ recordChild = new ConfigurationNode(JOBNODE_TIMEZONE);
+ recordChild.setValue(sr.getTimezone());
+ recordNode.addChild(recordNode.getChildCount(),recordChild);
+ }
+
+ // duration
+ if (sr.getDuration() != null)
+ {
+ recordChild = new ConfigurationNode(JOBNODE_DURATION);
+ recordChild.setValue(sr.getDuration().toString());
+ recordNode.addChild(recordNode.getChildCount(),recordChild);
+ }
+
+ // Schedule specification values
+
+ // day of week
+ if (sr.getDayOfWeek() != null)
+ formatEnumeratedValues(recordNode,JOBNODE_DAYOFWEEK,sr.getDayOfWeek());
+ if (sr.getMonthOfYear() != null)
+ formatEnumeratedValues(recordNode,JOBNODE_MONTHOFYEAR,sr.getMonthOfYear());
+ if (sr.getDayOfMonth() != null)
+ formatEnumeratedValues(recordNode,JOBNODE_DAYOFMONTH,sr.getDayOfMonth());
+ if (sr.getYear() != null)
+ formatEnumeratedValues(recordNode,JOBNODE_YEAR,sr.getYear());
+ if (sr.getHourOfDay() != null)
+ formatEnumeratedValues(recordNode,JOBNODE_HOUROFDAY,sr.getHourOfDay());
+ if (sr.getMinutesOfHour() != null)
+ formatEnumeratedValues(recordNode,JOBNODE_MINUTESOFHOUR,sr.getMinutesOfHour());
+
+ child.addChild(child.getChildCount(),recordNode);
+ }
+ jobNode.addChild(jobNode.getChildCount(),child);
+
+ return jobNode;
+ }
+
+ protected static void formatEnumeratedValues(ConfigurationNode recordNode, String childType, EnumeratedValues value)
+ {
+ ConfigurationNode child = new ConfigurationNode(childType);
+ Iterator iter = value.getValues();
+ while (iter.hasNext())
+ {
+ Integer theValue = (Integer)iter.next();
+ ConfigurationNode valueNode = new ConfigurationNode(JOBNODE_ENUMVALUE);
+ valueNode.setValue(theValue.toString());
+ child.addChild(child.getChildCount(),valueNode);
+ }
+ recordNode.addChild(recordNode.getChildCount(),child);
+ }
+
+ protected static EnumeratedValues processEnumeratedValues(ConfigurationNode fieldNode)
+ throws LCFException
+ {
+ ArrayList values = new ArrayList();
+ int i = 0;
+ while (i < fieldNode.getChildCount())
+ {
+ ConfigurationNode cn = fieldNode.findChild(i++);
+ if (cn.getType().equals(JOBNODE_ENUMVALUE))
+ {
+ try
+ {
+ values.add(new Integer(cn.getValue()));
+ }
+ catch (NumberFormatException e)
+ {
+ throw new LCFException("Error processing enumerated value node: "+e.getMessage(),e);
+ }
+ }
+ else
+ throw new LCFException("Error processing enumerated value nodes: Unrecognized node type '"+cn.getType()+"'");
+ }
+ return new EnumeratedValues(values);
+ }
+
+ protected static String presentInterval(Long interval)
+ {
+ if (interval == null)
+ return "infinite";
+ return interval.toString();
+ }
+
+ protected static Long interpretInterval(String interval)
+ throws LCFException
+ {
+ if (interval == null || interval.equals("infinite"))
+ return null;
+ else
+ return new Long(interval);
+ }
+
+ protected static String startModeMap(int startMethod)
+ {
+ switch (startMethod)
+ {
+ case IJobDescription.START_WINDOWBEGIN:
+ return "schedule window start";
+ case IJobDescription.START_WINDOWINSIDE:
+ return "schedule window anytime";
+ case IJobDescription.START_DISABLE:
+ return "manual";
+ default:
+ return "unknown";
+ }
+ }
+
+ protected static int mapToStartMode(String startMethod)
+ throws LCFException
+ {
+ if (startMethod.equals("schedule window start"))
+ return IJobDescription.START_WINDOWBEGIN;
+ else if (startMethod.equals("schedule window anytime"))
+ return IJobDescription.START_WINDOWINSIDE;
+ else if (startMethod.equals("manual"))
+ return IJobDescription.START_DISABLE;
+ else
+ throw new LCFException("Unrecognized start method: '"+startMethod+"'");
+ }
+
+ protected static String runModeMap(int type)
+ {
+ switch (type)
+ {
+ case IJobDescription.TYPE_CONTINUOUS:
+ return "continuous";
+ case IJobDescription.TYPE_SPECIFIED:
+ return "scan once";
+ default:
+ return "unknown";
+ }
+ }
+
+ protected static int mapToRunMode(String mode)
+ throws LCFException
+ {
+ if (mode.equals("continuous"))
+ return IJobDescription.TYPE_CONTINUOUS;
+ else if (mode.equals("scan once"))
+ return IJobDescription.TYPE_SPECIFIED;
+ else
+ throw new LCFException("Unrecognized run method: '"+mode+"'");
+ }
+
+ protected static String hopcountModeMap(int mode)
+ {
+ switch (mode)
+ {
+ case IJobDescription.HOPCOUNT_ACCURATE:
+ return "accurate";
+ case IJobDescription.HOPCOUNT_NODELETE:
+ return "no delete";
+ case IJobDescription.HOPCOUNT_NEVERDELETE:
+ return "never delete";
+ default:
+ return "unknown";
+ }
+ }
+
+ protected static int mapToHopcountMode(String mode)
+ throws LCFException
+ {
+ if (mode.equals("accurate"))
+ return IJobDescription.HOPCOUNT_ACCURATE;
+ else if (mode.equals("no delete"))
+ return IJobDescription.HOPCOUNT_NODELETE;
+ else if (mode.equals("never delete"))
+ return IJobDescription.HOPCOUNT_NEVERDELETE;
+ else
+ throw new LCFException("Unrecognized hopcount method: '"+mode+"'");
+ }
+
+ protected static ConfigurationNode findConfigurationNode(Configuration input, String argumentName)
+ {
+ // Look for argument among the children
+ int i = 0;
+ while (i < input.getChildCount())
+ {
+ ConfigurationNode cn = input.findChild(i++);
+ if (cn.getType().equals(argumentName))
+ return cn;
+ }
+ return null;
+
+ }
+
+ protected static String getRootArgument(Configuration input, String argumentName)
+ {
+ ConfigurationNode node = findConfigurationNode(input,argumentName);
+ if (node == null)
+ return null;
+ return node.getValue();
+ }
+
+ protected static class ResponseValue extends Configuration
+ {
+ /** Constructor.
+ */
+ public ResponseValue()
+ {
+ super();
+ }
+
+ /** Return the root node type.
+ *@return the node type name.
+ */
+ protected String getRootNodeLabel()
+ {
+ return "response";
+ }
+
+ /** Create a new object of the appropriate class.
+ */
+ protected Configuration createNew()
+ {
+ return new ResponseValue();
+ }
+
+ }
+
}
Added: incubator/lcf/trunk/modules/json/org/json/CDL.java
URL: http://svn.apache.org/viewvc/incubator/lcf/trunk/modules/json/org/json/CDL.java?rev=964035&view=auto
==============================================================================
--- incubator/lcf/trunk/modules/json/org/json/CDL.java (added)
+++ incubator/lcf/trunk/modules/json/org/json/CDL.java Wed Jul 14 12:55:26 2010
@@ -0,0 +1,279 @@
+package org.json;
+
+/*
+Copyright (c) 2002 JSON.org
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+The Software shall be used for Good, not Evil.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+*/
+
+/**
+ * This provides static methods to convert comma delimited text into a
+ * JSONArray, and to covert a JSONArray into comma delimited text. Comma
+ * delimited text is a very popular format for data interchange. It is
+ * understood by most database, spreadsheet, and organizer programs.
+ * <p>
+ * Each row of text represents a row in a table or a data record. Each row
+ * ends with a NEWLINE character. Each row contains one or more values.
+ * Values are separated by commas. A value can contain any character except
+ * for comma, unless is is wrapped in single quotes or double quotes.
+ * <p>
+ * The first row usually contains the names of the columns.
+ * <p>
+ * A comma delimited list can be converted into a JSONArray of JSONObjects.
+ * The names for the elements in the JSONObjects can be taken from the names
+ * in the first row.
+ * @author JSON.org
+ * @version 2009-09-11
+ */
+public class CDL {
+
+ /**
+ * Get the next value. The value can be wrapped in quotes. The value can
+ * be empty.
+ * @param x A JSONTokener of the source text.
+ * @return The value string, or null if empty.
+ * @throws JSONException if the quoted string is badly formed.
+ */
+ private static String getValue(JSONTokener x) throws JSONException {
+ char c;
+ char q;
+ StringBuffer sb;
+ do {
+ c = x.next();
+ } while (c == ' ' || c == '\t');
+ switch (c) {
+ case 0:
+ return null;
+ case '"':
+ case '\'':
+ q = c;
+ sb = new StringBuffer();
+ for (;;) {
+ c = x.next();
+ if (c == q) {
+ break;
+ }
+ if (c == 0 || c == '\n' || c == '\r') {
+ throw x.syntaxError("Missing close quote '" + q + "'.");
+ }
+ sb.append(c);
+ }
+ return sb.toString();
+ case ',':
+ x.back();
+ return "";
+ default:
+ x.back();
+ return x.nextTo(',');
+ }
+ }
+
+ /**
+ * Produce a JSONArray of strings from a row of comma delimited values.
+ * @param x A JSONTokener of the source text.
+ * @return A JSONArray of strings.
+ * @throws JSONException
+ */
+ public static JSONArray rowToJSONArray(JSONTokener x) throws JSONException {
+ JSONArray ja = new JSONArray();
+ for (;;) {
+ String value = getValue(x);
+ char c = x.next();
+ if (value == null ||
+ (ja.length() == 0 && value.length() == 0 && c != ',')) {
+ return null;
+ }
+ ja.put(value);
+ for (;;) {
+ if (c == ',') {
+ break;
+ }
+ if (c != ' ') {
+ if (c == '\n' || c == '\r' || c == 0) {
+ return ja;
+ }
+ throw x.syntaxError("Bad character '" + c + "' (" +
+ (int)c + ").");
+ }
+ c = x.next();
+ }
+ }
+ }
+
+ /**
+ * Produce a JSONObject from a row of comma delimited text, using a
+ * parallel JSONArray of strings to provides the names of the elements.
+ * @param names A JSONArray of names. This is commonly obtained from the
+ * first row of a comma delimited text file using the rowToJSONArray
+ * method.
+ * @param x A JSONTokener of the source text.
+ * @return A JSONObject combining the names and values.
+ * @throws JSONException
+ */
+ public static JSONObject rowToJSONObject(JSONArray names, JSONTokener x)
+ throws JSONException {
+ JSONArray ja = rowToJSONArray(x);
+ return ja != null ? ja.toJSONObject(names) : null;
+ }
+
+ /**
+ * Produce a JSONArray of JSONObjects from a comma delimited text string,
+ * using the first row as a source of names.
+ * @param string The comma delimited text.
+ * @return A JSONArray of JSONObjects.
+ * @throws JSONException
+ */
+ public static JSONArray toJSONArray(String string) throws JSONException {
+ return toJSONArray(new JSONTokener(string));
+ }
+
+ /**
+ * Produce a JSONArray of JSONObjects from a comma delimited text string,
+ * using the first row as a source of names.
+ * @param x The JSONTokener containing the comma delimited text.
+ * @return A JSONArray of JSONObjects.
+ * @throws JSONException
+ */
+ public static JSONArray toJSONArray(JSONTokener x) throws JSONException {
+ return toJSONArray(rowToJSONArray(x), x);
+ }
+
+ /**
+ * Produce a JSONArray of JSONObjects from a comma delimited text string
+ * using a supplied JSONArray as the source of element names.
+ * @param names A JSONArray of strings.
+ * @param string The comma delimited text.
+ * @return A JSONArray of JSONObjects.
+ * @throws JSONException
+ */
+ public static JSONArray toJSONArray(JSONArray names, String string)
+ throws JSONException {
+ return toJSONArray(names, new JSONTokener(string));
+ }
+
+ /**
+ * Produce a JSONArray of JSONObjects from a comma delimited text string
+ * using a supplied JSONArray as the source of element names.
+ * @param names A JSONArray of strings.
+ * @param x A JSONTokener of the source text.
+ * @return A JSONArray of JSONObjects.
+ * @throws JSONException
+ */
+ public static JSONArray toJSONArray(JSONArray names, JSONTokener x)
+ throws JSONException {
+ if (names == null || names.length() == 0) {
+ return null;
+ }
+ JSONArray ja = new JSONArray();
+ for (;;) {
+ JSONObject jo = rowToJSONObject(names, x);
+ if (jo == null) {
+ break;
+ }
+ ja.put(jo);
+ }
+ if (ja.length() == 0) {
+ return null;
+ }
+ return ja;
+ }
+
+
+ /**
+ * Produce a comma delimited text row from a JSONArray. Values containing
+ * the comma character will be quoted. Troublesome characters may be
+ * removed.
+ * @param ja A JSONArray of strings.
+ * @return A string ending in NEWLINE.
+ */
+ public static String rowToString(JSONArray ja) {
+ StringBuffer sb = new StringBuffer();
+ for (int i = 0; i < ja.length(); i += 1) {
+ if (i > 0) {
+ sb.append(',');
+ }
+ Object o = ja.opt(i);
+ if (o != null) {
+ String s = o.toString();
+ if (s.length() > 0 && (s.indexOf(',') >= 0 || s.indexOf('\n') >= 0 ||
+ s.indexOf('\r') >= 0 || s.indexOf(0) >= 0 ||
+ s.charAt(0) == '"')) {
+ sb.append('"');
+ int length = s.length();
+ for (int j = 0; j < length; j += 1) {
+ char c = s.charAt(j);
+ if (c >= ' ' && c != '"') {
+ sb.append(c);
+ }
+ }
+ sb.append('"');
+ } else {
+ sb.append(s);
+ }
+ }
+ }
+ sb.append('\n');
+ return sb.toString();
+ }
+
+ /**
+ * Produce a comma delimited text from a JSONArray of JSONObjects. The
+ * first row will be a list of names obtained by inspecting the first
+ * JSONObject.
+ * @param ja A JSONArray of JSONObjects.
+ * @return A comma delimited text.
+ * @throws JSONException
+ */
+ public static String toString(JSONArray ja) throws JSONException {
+ JSONObject jo = ja.optJSONObject(0);
+ if (jo != null) {
+ JSONArray names = jo.names();
+ if (names != null) {
+ return rowToString(names) + toString(names, ja);
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Produce a comma delimited text from a JSONArray of JSONObjects using
+ * a provided list of names. The list of names is not included in the
+ * output.
+ * @param names A JSONArray of strings.
+ * @param ja A JSONArray of JSONObjects.
+ * @return A comma delimited text.
+ * @throws JSONException
+ */
+ public static String toString(JSONArray names, JSONArray ja)
+ throws JSONException {
+ if (names == null || names.length() == 0) {
+ return null;
+ }
+ StringBuffer sb = new StringBuffer();
+ for (int i = 0; i < ja.length(); i += 1) {
+ JSONObject jo = ja.optJSONObject(i);
+ if (jo != null) {
+ sb.append(rowToString(jo.toJSONArray(names)));
+ }
+ }
+ return sb.toString();
+ }
+}
Propchange: incubator/lcf/trunk/modules/json/org/json/CDL.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: incubator/lcf/trunk/modules/json/org/json/CDL.java
------------------------------------------------------------------------------
svn:keywords = Id
Added: incubator/lcf/trunk/modules/json/org/json/Cookie.java
URL: http://svn.apache.org/viewvc/incubator/lcf/trunk/modules/json/org/json/Cookie.java?rev=964035&view=auto
==============================================================================
--- incubator/lcf/trunk/modules/json/org/json/Cookie.java (added)
+++ incubator/lcf/trunk/modules/json/org/json/Cookie.java Wed Jul 14 12:55:26 2010
@@ -0,0 +1,169 @@
+package org.json;
+
+/*
+Copyright (c) 2002 JSON.org
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+The Software shall be used for Good, not Evil.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+*/
+
+/**
+ * Convert a web browser cookie specification to a JSONObject and back.
+ * JSON and Cookies are both notations for name/value pairs.
+ * @author JSON.org
+ * @version 2008-09-18
+ */
+public class Cookie {
+
+ /**
+ * Produce a copy of a string in which the characters '+', '%', '=', ';'
+ * and control characters are replaced with "%hh". This is a gentle form
+ * of URL encoding, attempting to cause as little distortion to the
+ * string as possible. The characters '=' and ';' are meta characters in
+ * cookies. By convention, they are escaped using the URL-encoding. This is
+ * only a convention, not a standard. Often, cookies are expected to have
+ * encoded values. We encode '=' and ';' because we must. We encode '%' and
+ * '+' because they are meta characters in URL encoding.
+ * @param string The source string.
+ * @return The escaped result.
+ */
+ public static String escape(String string) {
+ char c;
+ String s = string.trim();
+ StringBuffer sb = new StringBuffer();
+ int len = s.length();
+ for (int i = 0; i < len; i += 1) {
+ c = s.charAt(i);
+ if (c < ' ' || c == '+' || c == '%' || c == '=' || c == ';') {
+ sb.append('%');
+ sb.append(Character.forDigit((char)((c >>> 4) & 0x0f), 16));
+ sb.append(Character.forDigit((char)(c & 0x0f), 16));
+ } else {
+ sb.append(c);
+ }
+ }
+ return sb.toString();
+ }
+
+
+ /**
+ * Convert a cookie specification string into a JSONObject. The string
+ * will contain a name value pair separated by '='. The name and the value
+ * will be unescaped, possibly converting '+' and '%' sequences. The
+ * cookie properties may follow, separated by ';', also represented as
+ * name=value (except the secure property, which does not have a value).
+ * The name will be stored under the key "name", and the value will be
+ * stored under the key "value". This method does not do checking or
+ * validation of the parameters. It only converts the cookie string into
+ * a JSONObject.
+ * @param string The cookie specification string.
+ * @return A JSONObject containing "name", "value", and possibly other
+ * members.
+ * @throws JSONException
+ */
+ public static JSONObject toJSONObject(String string) throws JSONException {
+ String n;
+ JSONObject o = new JSONObject();
+ Object v;
+ JSONTokener x = new JSONTokener(string);
+ o.put("name", x.nextTo('='));
+ x.next('=');
+ o.put("value", x.nextTo(';'));
+ x.next();
+ while (x.more()) {
+ n = unescape(x.nextTo("=;"));
+ if (x.next() != '=') {
+ if (n.equals("secure")) {
+ v = Boolean.TRUE;
+ } else {
+ throw x.syntaxError("Missing '=' in cookie parameter.");
+ }
+ } else {
+ v = unescape(x.nextTo(';'));
+ x.next();
+ }
+ o.put(n, v);
+ }
+ return o;
+ }
+
+
+ /**
+ * Convert a JSONObject into a cookie specification string. The JSONObject
+ * must contain "name" and "value" members.
+ * If the JSONObject contains "expires", "domain", "path", or "secure"
+ * members, they will be appended to the cookie specification string.
+ * All other members are ignored.
+ * @param o A JSONObject
+ * @return A cookie specification string
+ * @throws JSONException
+ */
+ public static String toString(JSONObject o) throws JSONException {
+ StringBuffer sb = new StringBuffer();
+
+ sb.append(escape(o.getString("name")));
+ sb.append("=");
+ sb.append(escape(o.getString("value")));
+ if (o.has("expires")) {
+ sb.append(";expires=");
+ sb.append(o.getString("expires"));
+ }
+ if (o.has("domain")) {
+ sb.append(";domain=");
+ sb.append(escape(o.getString("domain")));
+ }
+ if (o.has("path")) {
+ sb.append(";path=");
+ sb.append(escape(o.getString("path")));
+ }
+ if (o.optBoolean("secure")) {
+ sb.append(";secure");
+ }
+ return sb.toString();
+ }
+
+ /**
+ * Convert <code>%</code><i>hh</i> sequences to single characters, and
+ * convert plus to space.
+ * @param s A string that may contain
+ * <code>+</code> <small>(plus)</small> and
+ * <code>%</code><i>hh</i> sequences.
+ * @return The unescaped string.
+ */
+ public static String unescape(String s) {
+ int len = s.length();
+ StringBuffer b = new StringBuffer();
+ for (int i = 0; i < len; ++i) {
+ char c = s.charAt(i);
+ if (c == '+') {
+ c = ' ';
+ } else if (c == '%' && i + 2 < len) {
+ int d = JSONTokener.dehexchar(s.charAt(i + 1));
+ int e = JSONTokener.dehexchar(s.charAt(i + 2));
+ if (d >= 0 && e >= 0) {
+ c = (char)(d * 16 + e);
+ i += 2;
+ }
+ }
+ b.append(c);
+ }
+ return b.toString();
+ }
+}
Propchange: incubator/lcf/trunk/modules/json/org/json/Cookie.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: incubator/lcf/trunk/modules/json/org/json/Cookie.java
------------------------------------------------------------------------------
svn:keywords = Id