├── .gitignore ├── RDFValidator ├── ARPServlet.tmp │ └── .keep └── renderDot ├── README.md ├── build.sbt ├── project ├── build.properties ├── build.sbt └── plugins.sbt ├── src ├── main │ ├── java │ │ └── org │ │ │ └── w3c │ │ │ └── rdfvalidator │ │ │ └── ARPServlet.java │ ├── resources │ │ └── log4j.xml │ ├── scala │ │ └── JettyMain.scala │ └── webapp │ │ ├── WEB-INF │ │ └── web.xml │ │ └── index.html └── test │ └── scala │ └── RDFValidatorTest.scala └── w3c.json /.gitignore: -------------------------------------------------------------------------------- 1 | target 2 | lib_managed 3 | src_managed 4 | lift_example 5 | projectboot 6 | .classpath 7 | .project 8 | .manager 9 | *~ 10 | *.class 11 | *.log 12 | *\# 13 | sbt-launch*.jar 14 | .scala_dependencies 15 | *.orig 16 | .cache 17 | .settings 18 | .idea 19 | .idea_modules 20 | bin 21 | .ensime 22 | *.egp 23 | RDFValidator -------------------------------------------------------------------------------- /RDFValidator/ARPServlet.tmp/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/w3c/rdfvalidator-ng/90f29ae3fdfe3a777d0fe5661eccbe4886ecbcc3/RDFValidator/ARPServlet.tmp/.keep -------------------------------------------------------------------------------- /RDFValidator/renderDot: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Example parameters: 4 | # -Tpng \ 5 | # /usr/share/jetty/webapps/RDFValidator/ARPServlet.tmp/servlet_35684.png \ 6 | # /usr/share/jetty/webapps/RDFValidator/ARPServlet.tmp/servlet_35683.dot 7 | 8 | # Dot files are automagically removed. If you want to catch them, put 9 | # in something like: $(cp $3 /tmp) 10 | 11 | # I haven't seen any evidence that dot still pays attention to DOTFONTPATH. 12 | DOTFONTPATH=/usr/X11R6/lib/X11/fonts/misc 13 | export DOTFONTPATH 14 | 15 | #integers only because shell stinks at math 16 | load_limit=5 17 | dot_limit=10 18 | 19 | load=`cat /proc/loadavg | cut -f 1 -d' ' | sed -e 's/\..*//'` 20 | dots=`ps wwaux | grep dot | egrep -v '(dotty|grep)' | wc -l` 21 | swapfree=`grep SwapFree /proc/meminfo | sed -e 's/.*: *//' -e 's/ .*//'` 22 | swaptotal=`grep SwapTotal /proc/meminfo | sed -e 's/.*: *//' -e 's/ .*//'` 23 | 24 | #check our load threshold or see if there is any swapping 25 | if [ $dots -gt $dot_limit ] || [ $load -gt $load_limit ] ; then 26 | #taking out swap test for now, replace later with swap amount limit 27 | # || [ $swapfree -ne $swaptotal ] ; then 28 | timestamp=`date +%Y%m%d.%H:%M:%S` 29 | echo "$timestamp dots $dots load $load swap $swapfree / $swaptotal" >> /tmp/dotlog 30 | #from sysexits.h, to trap inside of servlet 31 | #define EX_TEMPFAIL 75 /* temp failure; user is invited to retry */ 32 | exit 75 33 | fi 34 | 35 | #ulimits for dot 36 | 37 | ulimit -n 16 38 | ulimit -t 120 39 | ulimit -f 4096 40 | ulimit -m 51200 41 | 42 | /usr/bin/dot $1 -o $2 $3 43 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | RDFValidator-NG 2 | =============== 3 | 4 | Check and Visualize your RDF documents. 5 | 6 | RDFValidator-NG is basically the code at [http://dev.w3.org/cvsweb/java/classes/org/w3c/rdf/examples/ARPServlet.java](http://dev.w3.org/cvsweb/java/classes/org/w3c/rdf/examples/ARPServlet.java) (which currently runs [http://www.w3.org/RDF/Validator/](http://www.w3.org/RDF/Validator/). This version makes very easy to run the service locally. 7 | 8 | How to start geeking 9 | -------------------- 10 | 11 | You only a recent version of Java (tested with Java 8). If you want to generate images for the graphs you provide, please install GraphViz. You'll also need a recent version of [sbt](https://github.com/paulp/sbt-extras). 12 | 13 | ```bash 14 | git clone git://github.com/w3c/rdfvalidator-ng.git 15 | cd rdfvalidator-ng 16 | sbt assembly 17 | java -jar target/scala-2.11/rdf-validator.jar 8080 18 | ``` 19 | 20 | Then you can go to [http://localhost:8080](http://localhost:8080). 21 | 22 | Licence 23 | ------- 24 | 25 | This source code is made available under the [W3C Licence](http://opensource.org/licenses/W3C). 26 | -------------------------------------------------------------------------------- /build.sbt: -------------------------------------------------------------------------------- 1 | val jettyVersion = "8.1.16.v20140903" 2 | val servletVersion = "3.0.0.v201112011016" 3 | 4 | lazy val rdfValidator = project.in(file(".")) 5 | .settings( 6 | organization := "org.w3", 7 | version := "1.1", 8 | scalaVersion := "2.12.5", 9 | scalacOptions ++= Seq("-deprecation"), 10 | javacOptions ++= Seq("-Xlint:unchecked"), 11 | assembly / mainClass := Some("org.w3.rdfvalidator.JettyMain"), 12 | assembly / assemblyJarName := "rdf-validator.jar", 13 | assembly / test := {}, 14 | // assemblyMergeStrategy in assembly <<= (assemblyMergeStrategy in assembly) { 15 | // val fs = System.getProperty("file.separator") 16 | // (old) => { 17 | // case r if r.endsWith("about.html") => MergeStrategy.discard 18 | // case r if r.startsWith(List("javax", "xml", "stream").mkString(fs)) => MergeStrategy.concat 19 | // case x => old(x) 20 | // } 21 | // }, 22 | resolvers += "Typesafe Repository" at "https://repo.typesafe.com/typesafe/releases/", 23 | resolvers += "Sonatype snapshots" at "https://oss.sonatype.org/content/repositories/snapshots", 24 | resolvers += "apache-repo-releases" at "https://repository.apache.org/content/repositories/releases/", 25 | libraryDependencies += "javax.mail" % "mail" % "1.4.7", 26 | // the newest versions of Jena break the code :-/ 27 | // libraryDependencies += "org.apache.jena" % "jena-arq" % "2.12.1", 28 | libraryDependencies += "org.apache.jena" % "jena-arq" % "2.11.2", 29 | libraryDependencies += "org.eclipse.jetty" % "jetty-webapp" % jettyVersion % "compile" intransitive(), 30 | libraryDependencies += "org.eclipse.jetty" % "jetty-util" % jettyVersion % "compile" intransitive(), 31 | libraryDependencies += "org.eclipse.jetty" % "jetty-server" % jettyVersion % "compile" intransitive(), 32 | libraryDependencies += "org.eclipse.jetty" % "jetty-io" % jettyVersion % "compile" intransitive(), 33 | libraryDependencies += "org.eclipse.jetty" % "jetty-http" % jettyVersion % "compile" intransitive(), 34 | libraryDependencies += "org.eclipse.jetty" % "jetty-security" % jettyVersion % "compile" intransitive(), 35 | libraryDependencies += "org.eclipse.jetty" % "jetty-continuation" % jettyVersion % "compile" intransitive(), 36 | libraryDependencies += "org.eclipse.jetty" % "jetty-xml" % jettyVersion % "compile" intransitive(), 37 | libraryDependencies += "org.eclipse.jetty" % "jetty-servlet" % jettyVersion % "compile" intransitive(), 38 | libraryDependencies += "org.eclipse.jetty" % "jetty-servlets" % jettyVersion % "compile" intransitive(), 39 | libraryDependencies += "org.eclipse.jetty.orbit" % "javax.servlet" % servletVersion % "compile" artifacts (Artifact("javax.servlet", "jar", "jar")) intransitive(), 40 | ivyXML := 41 | 42 | 43 | 44 | ) 45 | 46 | 47 | -------------------------------------------------------------------------------- /project/build.properties: -------------------------------------------------------------------------------- 1 | sbt.version=1.9.8 2 | -------------------------------------------------------------------------------- /project/build.sbt: -------------------------------------------------------------------------------- 1 | scalacOptions ++= Seq("-unchecked", "-deprecation") 2 | -------------------------------------------------------------------------------- /project/plugins.sbt: -------------------------------------------------------------------------------- 1 | addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.14.6") 2 | -------------------------------------------------------------------------------- /src/main/java/org/w3c/rdfvalidator/ARPServlet.java: -------------------------------------------------------------------------------- 1 | /*********************************************************************** 2 | * 3 | * ARPServlet - this servlet implements an RDF Validation service. As 4 | * of this writing, the following RDF validation service used this 5 | * servlet: 6 | * 7 | * http://www.w3.org/RDF/Validator/ 8 | * 9 | *********************************************************************** 10 | * 11 | * Copyright (c) World Wide Web Consortium, (Massachusetts Institute of 12 | * Technology, Institut National de Recherche en Informatique et en 13 | * Automatique, Keio University). 14 | * 15 | * All Rights Reserved. 16 | * 17 | * Please see the full Copyright clause at 18 | * 19 | * 20 | *********************************************************************** 21 | * 22 | * This servlet is a wrapper for the ARP RDF parser. See the following 23 | * for information about the ARP RDF parser: 24 | * 25 | * http://www.hpl.hp.co.uk/people/jjc/arp/ 26 | * 27 | *********************************************************************** 28 | * 29 | * Implementation notes: 30 | * 31 | * o This servlet supports the HTTP POST operation; it does not 32 | * support the HTTP GET operation 33 | * 34 | * o Depending upon the parameters given to the servlet it may 35 | * invoke a GraphViz suprocess to generate a graph of the RDF. 36 | * See the following for more information about GraphViz: 37 | * 38 | * http://www.research.att.com/sw/tools/graphviz/ 39 | * 40 | * The servlet assumes version 1.7.4 of GraphViz. 41 | * 42 | * o Depending upon the parameters given to the servlet, the RDF 43 | * to be validated may be copied to a file. The name of the file 44 | * is automatically generated via Java's temporary file APIs. The 45 | * location of the directory where the file is stored is configured 46 | * via the serverlet's init() method. See below for more information. 47 | * 48 | * o See the section on Server Initialization for more information. 49 | * 50 | *********************************************************************** 51 | * 52 | * HTTP POST parameters - the servlet expects/assumes the following 53 | * variables are defined via the HTTP POST request: 54 | * 55 | * RDF - the RDF (assumed to be in RDF/XML syntax) to be validated 56 | * 57 | * SAVE_DOT_FILE - if "on", the GraphViz DOT file is saved and a 58 | * link to the file is returned; otherwise the DOT file is not saved 59 | * 60 | * SAVE_RDF - if "on", the RDF will be copied to a file; otherwise 61 | * the RDF is not copied to a file 62 | * 63 | * EMBEDDED_RDF - if "on", then the RDF is not enclosed in ... 64 | * tags; otherwise it assumed that the RDF is enclosed in these tags. 65 | * 66 | * URI - the URI of the RDF to validate 67 | * 68 | * PARSE - if "Parse RDF", then parse RDF from the textarea; 69 | * else download from URI; if not present, prefer URI, 70 | * but if URI is empty, parse RDF (old behavior). 71 | * 72 | * ORIENTATION - the graph's orientation (left to right or top to 73 | * bottom); default is left to right 74 | * 75 | * FONT_SIZE - the font size to use (10, 12, 14, 16 and 20 are 76 | * supported); the default is 10 77 | * 78 | * NODE_COLOR - the color of nodes; default is black 79 | * 80 | * NODE_TEXT_COLOR - the color of the text in nodes; default is blue 81 | * 82 | * EDGE_COLOR - the color of edges; default is darkgreen 83 | * 84 | * EDGE_TEXT_COLOR - the color of the text on edges; default is red 85 | * 86 | * ANON_NODES_EMPTY - if "on", anonymous nodes are not labeled; otherwise 87 | * anonymous nodes are labeled; 88 | * 89 | * TRIPLES_AND_GRAPH - support values are: 90 | * 91 | * PRINT_BOTH - display triples and a graph (the default) 92 | * PRINT_TRIPLES - only display the triples 93 | * PRINT_GRAPH - only display the graph 94 | * 95 | * FORMAT - the graph's output format. Supported values are: 96 | * 97 | * GIF_EMBED - embed the graph as a GIF 98 | * GIF_LINK - don't embed the GIF but create a link for it 99 | * SVG_LINK - create the graph in SVG format and create a link to the file 100 | * SVG_EMBED - create the graph in SVG format and embed it in an object tag 101 | * ISV_ZVTM - IsaViz/ZVTM (Dynamic View - requires Java Plug-in 1.4) 102 | * PNG_EMBED - create the graph in PNG format and embed the graph in the 103 | * document that is returned (the default) 104 | * PNG_LINK - create the graph in PNG format and create a link to the file 105 | * PS_LINK - create a PostScript image of the file and a link to the file 106 | * HP_PCL_LINK - create a HPGL/2 - PCL (Laserwriter) image of the file 107 | * and a link to the file 108 | * HP_GL_LINK - create a HPGL - PCL (pen plotter) image of the file and 109 | * a link to the file 110 | * 111 | * NTRIPLES if "on" the tabular output will be in the NTriples format; 112 | * otherwise a table of Subject, Predicate, Objects will be generated 113 | * 114 | *********************************************************************** 115 | * 116 | * Server Initialization - this servlet requires the following 117 | * parameters be set in the servlet's init() method - via the 118 | * ServletConfig object: 119 | * 120 | * BITMAPPED_FONT - the absolute path of the top-level directory containing 121 | * GraphViz's binary distribution 122 | * 123 | * VECTOR_FONT - absolute or relative (based on GRAPH_VIZ_ROOT) path of 124 | * the DOT executable (e.g. dotneato/dot) - the program used to generate 125 | * a graph from a DOT file. 126 | * 127 | * SERVLET_TMP_DIR - the absolute path of the directory to be used to 128 | * store temporary files used by the servlet and GraphViz. This 129 | * directory must be writable by the servlet. 130 | * 131 | * NOTE - Some files created by the servlet are not removed by 132 | * servlet (e.g. graph image files). 133 | * 134 | * If any of these parameters are not defined, the servlet will NOT 135 | * validate the RDF. 136 | * 137 | *********************************************************************** 138 | * 139 | * Dependencies - this servlet requires the following Java packages 140 | * as well as GraphViz (described above): 141 | * 142 | * ARP RDF parser: http://www.hpl.hp.co.uk/people/jjc/arp/download.html 143 | * 144 | * SAX-based XML parser: e.g. Xerces at http://xml.apache.org/ 145 | * 146 | * Java servlet package: http://java.sun.com/products/servlet/archive.html 147 | * 148 | * Apache Regular Expression: http://jakarta.apache.org/builds/jakarta-regexp/release/v1.2/ 149 | * 150 | *********************************************************************** 151 | * 152 | * Author: Art Barstow 153 | * Author (internationalization): Martin J. Duerst 154 | * Author (maintenance): Emmanuel Pietriga 155 | * 156 | * $Id: ARPServlet.java,v 1.5 2006/09/17 23:43:32 ted Exp $ 157 | * 158 | ***********************************************************************/ 159 | 160 | // http://dev.w3.org/cvsweb/java/classes/org/w3c/rdf/examples/ 161 | package org.w3c.rdfvalidator; 162 | 163 | import java.io.*; 164 | import java.net.MalformedURLException; 165 | import java.net.URL; 166 | import java.net.URLConnection; 167 | import java.util.StringTokenizer; 168 | import java.util.Enumeration; 169 | import java.util.Hashtable; 170 | 171 | // http://java.sun.com/products/servlet/2.2/javadoc/javax/servlet/package-summary.html 172 | import javax.servlet.*; 173 | import javax.servlet.http.*; 174 | import javax.mail.internet.ContentType; 175 | 176 | // http://xml.apache.org/apiDocs/org/xml/sax/package-summary.html 177 | import org.xml.sax.InputSource; 178 | //import org.xml.sax.Parser; 179 | import org.xml.sax.SAXException; 180 | import org.xml.sax.SAXParseException; 181 | import org.xml.sax.ErrorHandler; 182 | import org.xml.sax.helpers.*; 183 | 184 | // http://jakarta.apache.org/regexp/apidocs/org/apache/regexp/RE.html 185 | import java.util.regex.*; 186 | 187 | // http://www.hpl.hp.co.uk/people/jjc/arp/apidocs/index.html 188 | import com.hp.hpl.jena.rdf.arp.*; 189 | import com.hp.hpl.jena.rdf.arp.impl.RDFXMLParser; 190 | 191 | import java.security.Security; 192 | 193 | public class ARPServlet extends HttpServlet 194 | { 195 | final static public String REVISION = "$Id: ARPServlet.java,v 1.5 2006/09/17 23:43:32 ted Exp $"; 196 | 197 | // The email address for bug reports 198 | private static final String MAIL_TO = "www-rdf-validator@w3.org"; 199 | 200 | // Names of the POST parameters (described above) and their 201 | // defaults (if applicable) 202 | private static final String TEXT = "RDF"; 203 | private static final String SAVE_DOT_FILE = "SAVE_DOT_FILE"; 204 | private static final String SAVE_RDF = "SAVE_RDF"; 205 | private static final String EMBEDDED_RDF = "EMBEDDED_RDF"; 206 | private static final String URI = "URI"; 207 | private static final String PARSE = "PARSE"; 208 | private static final String NTRIPLES = "NTRIPLES"; 209 | private static final String ANON_NODES_EMPTY = "ANON_NODES_EMPTY"; 210 | 211 | private static final String NODE_COLOR = "NODE_COLOR"; 212 | private static final String DEFAULT_NODE_COLOR = "black"; 213 | 214 | private static final String NODE_TEXT_COLOR = "NODE_TEXT_COLOR"; 215 | private static final String DEFAULT_NODE_TEXT_COLOR = "blue"; 216 | 217 | private static final String EDGE_COLOR = "EDGE_COLOR"; 218 | private static final String DEFAULT_EDGE_COLOR = "darkgreen"; 219 | 220 | private static final String EDGE_TEXT_COLOR = "EDGE_TEXT_COLOR"; 221 | private static final String DEFAULT_EDGE_TEXT_COLOR = "red"; 222 | 223 | private static final String ORIENTATION = "ORIENTATION"; 224 | private static final String DEFAULT_ORIENTATION = "LR"; // Left to Right 225 | 226 | private static final String FONT_SIZE = "FONT_SIZE"; 227 | private static final String DEFAULT_FONT_SIZE = "10"; 228 | 229 | // Print graph and/or triples 230 | private static final String TRIPLES_AND_GRAPH = "TRIPLES_AND_GRAPH"; 231 | private static final String PRINT_BOTH = "PRINT_BOTH"; 232 | private static final String PRINT_TRIPLES = "PRINT_TRIPLES"; 233 | private static final String PRINT_GRAPH = "PRINT_GRAPH"; 234 | 235 | // Graph formats 236 | private static final String FORMAT = "FORMAT"; 237 | private static final String FORMAT_GIF_EMBED = "GIF_EMBED"; 238 | private static final String FORMAT_GIF_LINK = "GIF_LINK"; 239 | private static final String FORMAT_SVG_LINK = "SVG_LINK"; 240 | private static final String FORMAT_SVG_EMBED = "SVG_EMBED"; 241 | private static final String FORMAT_ISV_ZVTM = "ISV_ZVTM"; 242 | private static final String FORMAT_PNG_EMBED = "PNG_EMBED"; 243 | private static final String FORMAT_PNG_LINK = "PNG_LINK"; 244 | private static final String FORMAT_PS_LINK = "PS_LINK"; 245 | private static final String FORMAT_HP_PCL_LINK = "HP_PCL_LINK"; 246 | private static final String FORMAT_HP_GL_LINK = "HP_GL_LINK"; 247 | private static final String DEFAULT_FORMAT = "PNG_EMBED"; 248 | 249 | // Take a guess at what fonts to use of BITMAPPED_FONT and 250 | // VECTOR_FONT are not set. 251 | private static String m_BitmappedFont = "cyberbit"; 252 | private static String m_VectorFont = "Courier"; 253 | 254 | // Names of the servlet's parameters - for Jigsaw web server 255 | private static final String SERVLET_TMP_DIR = "SERVLET_TMP_DIR"; 256 | 257 | private static String m_RenderDot = null; 258 | 259 | // Variables for the servlet's parameters 260 | private static String m_ServletTmpDir = null; 261 | 262 | // Names of environment variable needed by GraphVis 263 | private static String LD_LIBRARY_PATH = "LD_LIBRARY_PATH"; 264 | 265 | // Names used for temporary files 266 | private static final String TMP_FILE_PREFIX = "servlet_"; 267 | private static final String SUFFIX_TMP_DIR = ".tmp"; 268 | private static final String SUFFIX_DOT = ".dot"; 269 | private static final String SUFFIX_RDF = ".rdf"; 270 | 271 | // Names used for file suffixes and for GraphViz's command line 272 | // option 273 | private static final String NAME_GIF = "gif"; 274 | private static final String NAME_HPGL = "hpgl"; 275 | private static final String NAME_PCL = "pcl"; 276 | private static final String NAME_PNG = "png"; 277 | private static final String NAME_PS = "ps"; 278 | private static final String NAME_SVG = "svg"; 279 | 280 | // Default GraphViz parameter names and their default values 281 | // Servlet name 282 | private static final String SERVLET_NAME = "ARPServlet"; 283 | 284 | // Name for the DOT file title 285 | private static final String DOT_TITLE = "dotfile"; 286 | 287 | // The string to use to prefix anonymous nodes. 288 | private static final String ANON_NODE = "genid:"; 289 | 290 | // The string to use for a namespace name when no 291 | // namespace is available - e.g. for the RDF that is 292 | // directly entered into the input form. 293 | private static final String DEFAULT_NAMESPACE = "http://www.w3.org/RDF/Validator/run/"; 294 | 295 | //used to detect whether the provided document contains at least one triple, or if it is not RDF at all 296 | //necessary because ARP does not report any error when parsing an XML document which does not contain any 297 | //RDF statement 298 | static boolean AT_LEAST_ONE_TRIPLE=false; 299 | 300 | // Setting this to {1, true, yes} prints messages to STDERR 301 | static Pattern LogALotPattern = Pattern.compile("^[ \\t\\n\\r]?(1|t.*|y.*)?"); 302 | static boolean LogALot = false; 303 | 304 | // Regular expression for parsing an XML prolog to look for the charset. 305 | static Pattern XMLProlog = Pattern.compile("<\\?xml[ \\t\\n\\r]+version[ \\t\\n\\r]?=[ \\t\\n\\r]?(['\"])([a-zA-Z0-9_:]|\\.|-)+\\1[ \\t\\n\\r]+encoding[ \\t\\n\\r]?=[ \\t\\n\\r]?(['\"])([A-Za-z]([A-Za-z0-9._]|-)*)\\3"); 306 | 307 | //colors for ISV-plugin texts (resources, properties and literals) 308 | private static float resTBh=0.33333334f; 309 | private static float resTBs=0.37142858f; 310 | private static float resTBv=0.4117647f; 311 | private static float prpTh=0.6680911f; 312 | private static float prpTs=0.56796116f; 313 | private static float prpTv=0.80784315f; 314 | private static float litTBh=0.12878788f; 315 | private static float litTBs=0.5f; 316 | private static float litTBv=0.5176471f; 317 | 318 | // exception used by getRDFfromURI 319 | private class getRDFException extends Exception { 320 | public getRDFException (String s) { 321 | super (s); 322 | } 323 | } 324 | 325 | /* 326 | * Create a File object from the given directory and file names 327 | * 328 | *@param directory the file's directory 329 | *@param prefix the file's prefix name (not its directory) 330 | *@param suffix the file's suffix or extension name 331 | *@return a File object if a temporary file is created; null otherwise 332 | */ 333 | private File createTempFile (String directory, String prefix, String suffix) 334 | { 335 | File f; 336 | try { 337 | File d = new File(directory); 338 | f = File.createTempFile(prefix, suffix, d); 339 | } catch (Exception e) { 340 | return null; 341 | } 342 | return f; 343 | } 344 | 345 | /* 346 | * Given a URI string, open it, read its contents into a String 347 | * and return the String 348 | * 349 | *@param uri the URI to open 350 | *@return the content at the URI or null if any error occurs 351 | */ 352 | private String getRDFfromURI (String uri) throws getRDFException 353 | { 354 | /* add something like this code here, to allow reading from a file: 355 | (if we really want to allow this!) 356 | File ff = new File(uri); 357 | in = new FileInputStream(ff); 358 | */ 359 | 360 | // System.setProperty("java.protocol.handler.pkgs", "com.sun.net.ssl.internal.www.protocol"); 361 | // Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider()); 362 | 363 | URL url = null; 364 | try { 365 | url = new URL(uri); 366 | } catch (MalformedURLException e) { 367 | throw new getRDFException("Malformed URI."); 368 | } 369 | 370 | URLConnection con = null; 371 | try { 372 | con = url.openConnection(); 373 | con.setRequestProperty("Accept", "application/rdf+xml"); 374 | con.connect(); 375 | } catch (Exception e) { 376 | throw new getRDFException("Unable to open connection."); 377 | } 378 | String contentT = con.getContentType(); 379 | String HTTPcharset = null; 380 | if (contentT != null) { 381 | ContentType contentType = null; 382 | try { 383 | contentType = new ContentType(con.getContentType()); 384 | } catch (javax.mail.internet.ParseException e) { 385 | throw new getRDFException("Unparsable content type."); 386 | } 387 | HTTPcharset = contentType.getParameter("charset"); 388 | } 389 | 390 | // need buffer for lookahead for encoding detection 391 | BufferedInputStream bis = null; 392 | try { 393 | bis = new BufferedInputStream(con.getInputStream()); 394 | } catch (IOException e) { 395 | throw new getRDFException("Cannot open stream."); 396 | } 397 | bis.mark(200); // mark start so that we can get back to it 398 | String s = ""; 399 | 400 | try { // read start of file as bytes 401 | int c; 402 | int numRead = 0; 403 | while ((c = bis.read()) != -1) { 404 | s += (char)c; 405 | if (numRead++ >= 195) break; 406 | } 407 | } catch (IOException e) { 408 | throw new getRDFException("IOException while starting reading."); 409 | } 410 | 411 | if (s.equals("")) 412 | // Nothing was returned 413 | throw new getRDFException("Empty document, ignored."); 414 | 415 | // A server could return content but not the RDF/XML that 416 | // we need. Check the beginning of s and if it looks like 417 | // a generic HTML message, return an error. 418 | if (s.startsWith("",">"); 720 | msg = replaceString(msg,"\"","""); 721 | msg = replaceString(msg,"'","'"); 722 | return msg + "[Line = " + e.getLineNumber() + ", Column = " + e.getColumnNumber() + "]"; 723 | } 724 | 725 | /* 726 | * Handle a parse error 727 | * 728 | *@param e the SAX Parse Exception 729 | */ 730 | public void error(org.xml.sax.SAXParseException e) 731 | throws org.xml.sax.SAXException 732 | { 733 | if (this.silent) return; 734 | 735 | if (e instanceof com.hp.hpl.jena.rdf.arp.ParseException){ 736 | com.hp.hpl.jena.rdf.arp.ParseException pe=(com.hp.hpl.jena.rdf.arp.ParseException)e; 737 | // if (pe.getErrorNumber()==com.hp.hpl.jena.rdf.arp.ARP.WARN_NOT_SUPPORTED && pe.getMessage().indexOf("datatyping")!=-1){ 738 | // datatypeErrors+=String.valueOf(pe.getLineNumber())+", "; 739 | // } 740 | // else { 741 | this.errors += "Error: " + format(e) + "
"; 742 | // } 743 | } 744 | else {this.errors += "Error: " + format(e) + "
";} 745 | } 746 | 747 | /* 748 | * Handle a fatal parse error 749 | * 750 | *@param e the SAX Parse Exception 751 | */ 752 | public void fatalError(org.xml.sax.SAXParseException e) 753 | throws org.xml.sax.SAXException 754 | { 755 | if (this.silent) return; 756 | 757 | this.fatalErrors += "FatalError: " + format(e) + "
"; 758 | } 759 | 760 | /* 761 | * Handle a parse warning 762 | * 763 | *@param e the SAX Parse Exception 764 | */ 765 | public void warning(org.xml.sax.SAXParseException e) 766 | throws org.xml.sax.SAXException 767 | { 768 | if (this.silent) return; 769 | 770 | if (e instanceof com.hp.hpl.jena.rdf.arp.ParseException){ 771 | // com.hp.hpl.jena.rdf.arp.ParseException pe=(com.hp.hpl.jena.rdf.arp.ParseException)e; 772 | // if (pe.getErrorNumber()==com.hp.hpl.jena.rdf.arp.ARP.WARN_NOT_SUPPORTED && pe.getMessage().indexOf("datatyping")!=-1){ 773 | // datatypeErrors+=String.valueOf(pe.getLineNumber())+", "; 774 | // } 775 | // else { 776 | this.warnings += "Warning: " + format(e) + "
"; 777 | // } 778 | } 779 | else {this.errors += "Warning: " + format(e) + "
";} 780 | } 781 | 782 | /* 783 | * Return the error messages 784 | * 785 | *@return the error messages or an empty string if there are 786 | * no messages 787 | */ 788 | public String getErrors() 789 | { 790 | return this.errors; 791 | } 792 | 793 | public String getDatatypeErrors() 794 | { 795 | return this.datatypeErrors; 796 | } 797 | 798 | /* 799 | * Return the fatal error messages 800 | * 801 | *@return the fatal error messages or an empty string if there are 802 | * no messages 803 | */ 804 | public String getFatalErrors() 805 | { 806 | return this.fatalErrors; 807 | } 808 | 809 | /* 810 | * Return the warning messages 811 | * 812 | *@return the warning messages or an empty string if there are 813 | * no messages 814 | */ 815 | public String getWarnings() 816 | { 817 | return this.warnings; 818 | } 819 | } 820 | 821 | /* 822 | * Generate a graph of the RDF data model 823 | * 824 | *@param out the servlet's output Writer 825 | *@param pw the graph file's PrintWriter 826 | *@param dotFile the File handle for the graph file 827 | *@param rdf the RDF text 828 | *@param req a Servlet request 829 | *@param graphFormat the graph's format 830 | *@param saveRDF the RDF can be cached [saved to the file system] 831 | *@param saveDOTFile the DOT file should be cached 832 | */ 833 | private void generateGraph(PrintWriter out, PrintWriter pw, 834 | File dotFile, String rdf, HttpServletRequest req, String graphFormat, 835 | boolean saveRDF, boolean saveDOTFile) 836 | { 837 | try { 838 | out.println("
"); 839 | out.println("

" + 840 | "Graph of the data model

"); 841 | 842 | // The temporary directory 843 | String tmpDir = m_ServletTmpDir; 844 | 845 | // Add the graph footer 846 | pw.println( " }"); 847 | 848 | // Close the DOT input file so the GraphViz can 849 | // open and read it 850 | pw.close(); 851 | 852 | // Generate a unique file name for the output file 853 | // that will be created 854 | String suffix = getFormatName(graphFormat, true); 855 | File outputFile = createTempFile(tmpDir, TMP_FILE_PREFIX, suffix); 856 | if (outputFile == null) { 857 | out.println("Failed to create a temporary file for the graph. A graph cannot be generated."); 858 | dotFile.delete(); 859 | return; 860 | } 861 | 862 | // Pass the DOT data file to the GraphViz dot program 863 | // so it can create a graph image of the data model 864 | String dotFileName = dotFile.getAbsolutePath(); 865 | String outputFileName = outputFile.getAbsolutePath(); 866 | int grapvizExitValue=generateGraphFile(dotFileName, outputFileName, graphFormat); 867 | if (grapvizExitValue != 0) { 868 | //from sysexits.h, sent by renderDot http://dev.w3.org/cvsweb/~checkout~/2006/RDFValidator/renderDot 869 | //#define EX_TEMPFAIL75/* temp failure; user is invited to retry */ 870 | if (grapvizExitValue == 75) { 871 | out.println("We're sorry but the server load of the RDF validator is too high at the moment, and generation of the graph image files has been canceled. Please try again later."); 872 | } 873 | else if (grapvizExitValue > 150) { 874 | out.println("The resources necessary to create this graph exceed size, cpu or memory restraints imposed for graphics generation on this server."); 875 | } 876 | else { 877 | out.println("An attempt to create a graph failed."); 878 | } 879 | dotFile.delete(); 880 | outputFile.delete(); 881 | return; 882 | } 883 | // Handle the DOT file 884 | if (saveDOTFile) { 885 | // Make the DOT file link'able if so requested 886 | String dotPath = SERVLET_NAME + SUFFIX_TMP_DIR + 887 | File.separator + dotFile.getName(); 888 | out.println("Download the DOT file.

"); 889 | } 890 | else { 891 | // Delete it ... 892 | dotFile.delete(); 893 | } 894 | 895 | // NOTE: Cannot delete the output file here because its 896 | // pathname is returned to the client 897 | String imagePath = SERVLET_NAME + SUFFIX_TMP_DIR + File.separator + 898 | outputFile.getName(); 899 | 900 | // Handle the embedded image formats first 901 | if (graphFormat.equals(FORMAT_GIF_EMBED) || 902 | graphFormat.equals(FORMAT_PNG_EMBED)) { 903 | if (outputFile.length() > 0) 904 | out.println("graph representation of RDF data"); 906 | else 907 | out.println("The graph image file is empty."); 908 | } 909 | else if (graphFormat.equals(FORMAT_SVG_EMBED)){ 910 | if (outputFile.length() > 0){ 911 | out.println("Your browser does not support the <object> tag. The SVG representation of the model cannot be embedded in this page. You can use SVG - link or update your browser to a version supporting the <object> tag."); 912 | } 913 | else 914 | out.println("The graph image file is empty."); 915 | } 916 | else if (graphFormat.equals(FORMAT_ISV_ZVTM)){ 917 | if (outputFile.length() > 0){ 918 | out.println(""); 921 | out.println(""); 922 | out.println(""); 923 | out.println(""); 924 | out.println(""); 925 | out.println(""); 926 | out.println(""); 927 | } 928 | else 929 | out.println("The graph image file is empty."); 930 | } 931 | else { 932 | if (outputFile.length() > 0) 933 | out.println("Get/view the graph's image file (" + suffix + ").

"); 934 | else 935 | out.println("The graph image file is empty."); 936 | } 937 | 938 | // One last thing to do before exiting - copy the RDF to a file 939 | if (saveRDF) 940 | copyRDFStringToFile(tmpDir, rdf); 941 | 942 | } catch (Exception e) { 943 | System.err.println("Exception generating graph: " + e.getMessage()); 944 | } 945 | } 946 | 947 | /* 948 | * Search the given string for substring "key" 949 | * and if it is found, replace it with string "replacement" 950 | * 951 | *@param input the input string 952 | *@param key the string to search for 953 | *@param replacement the string to replace all occurences of "key" 954 | *@return if no substitutions are done, input is returned; otherwise 955 | * a new string is returned. 956 | */ 957 | public static String replaceString(String input, String key, 958 | String replacement) 959 | { 960 | return input.replaceAll(key, replacement); 961 | } 962 | 963 | /* 964 | * Print the document's header info 965 | * 966 | *@param out the servlet's output Writer 967 | */ 968 | private void printDocumentHeader (PrintWriter out) 969 | { 970 | try { 971 | 972 | out.println( ""+ 973 | ""+ 974 | ""+ 975 | ""+ 976 | ""+ 977 | "W3C RDF Validation Results"+ 978 | ""+ 979 | "\n" + 987 | ""+ 991 | "
"+ 997 | "
Jump To:"+ 998 | "
"); 1006 | 1007 | 1008 | } catch (Exception e) { 1009 | System.err.println("Exception (printDocumentHeader): " + e.getMessage()); 1010 | } 1011 | } 1012 | 1013 | /* 1014 | * Print the rdf listing 1015 | * 1016 | *@param out the servlet's output Writer 1017 | *@param rdf the RDF code 1018 | *@param needCR if true, add a CarriageReturn to the output; if false, 1019 | * do not add it 1020 | */ 1021 | private void printListing (PrintWriter out, String rdf, 1022 | boolean needCR) 1023 | { 1024 | try { 1025 | out.println("
" + 1026 | "

" + 1027 | "The original RDF/XML document

" + 1028 | "
");
1029 | 
1030 |             String s = replaceString(rdf, "&", "&");
1031 |             s = replaceString(s, "<", "<");
1032 |             
1033 |             // Now output the RDF one line at a time with line numbers
1034 |             int lineNum = 1;
1035 |             int nl = 0;
1036 |             String terminator = needCR?"\n":"";
1037 |             do {
1038 |                 String tok;
1039 |                 nl = s.indexOf('\n');
1040 |                 if ( nl == -1 ) {
1041 |                     tok = s;
1042 |                 } else {
1043 |                     tok = s.substring(0,nl);
1044 |                     s = s.substring(nl+1);
1045 |                 }
1046 |                 out.print("" + lineNum +
1047 |                           ": " + tok + terminator);
1048 |                 lineNum++;
1049 |             } while ( nl != -1 );
1050 | 
1051 |             out.println("
"); 1052 | } catch (Exception e) { 1053 | System.err.println("Exception (printListing): " + e.getMessage()); 1054 | } 1055 | } 1056 | 1057 | /* 1058 | * Print the header for the triple listing 1059 | * 1060 | *@param out the servlet's output Writer 1061 | *@param nTriples if true, output is N-Triples syntax 1062 | */ 1063 | private void printTripleTableHeader (PrintWriter out, boolean nTriples) 1064 | { 1065 | try { 1066 | if (nTriples) { 1067 | out.println("

" + 1068 | "Triples of the Data Model in " + 1069 | "" + 1070 | "N-Triples Format (Sub, Pred, Obj)

" + 1071 | "
");
1072 |             } else {
1073 |                 out.println("
"); 1074 | out.println("

" + 1075 | "Triples of the Data Model

"); 1076 | out.println("" + 1077 | "" + 1078 | "" + 1079 | "" + 1080 | "" + 1081 | ""); 1082 | } 1083 | } catch (Exception e) { 1084 | System.err.println("Exception (printTripleTableHeader): " + e.getMessage()); 1085 | } 1086 | } 1087 | 1088 | /* 1089 | * Print the footer info for the triple listing 1090 | * 1091 | *@param out the servlet's output Writer 1092 | *@param nTriples if true, output is N-Triples syntax 1093 | */ 1094 | private void printTripleTableFooter (PrintWriter out, 1095 | boolean nTriples) 1096 | { 1097 | try { 1098 | if (nTriples) 1099 | out.println(""); 1100 | else 1101 | out.println("
NumberSubjectPredicateObject
"); 1102 | } catch (Exception e) { 1103 | System.err.println("Exception (printTripleTableFooter): " + e.getMessage()); 1104 | } 1105 | } 1106 | 1107 | /* 1108 | * Print the document's footer info 1109 | * 1110 | *@param out the servlet's output Writer 1111 | *@param rdf the RDF code 1112 | */ 1113 | private void printDocumentFooter (PrintWriter out, String rdf) 1114 | { 1115 | try { 1116 | 1117 | String s; 1118 | 1119 | s = "
" + 1120 | "

Feedback

" + 1121 | "

If you suspect the parser is in error, please enter an explanation below and then press the Submit problem report button, to mail the report (and listing) to " + MAIL_TO + "

" + 1122 | "
" + 1123 | ""; 1124 | out.println(s); 1125 | 1126 | out.println("", ">"); 1136 | s1 = replaceString(s1, "\"", """); 1137 | out.println(s1); 1138 | } 1139 | out.println("\" />"); 1140 | 1141 | out.println("" + 1142 | "
"); 1143 | 1144 | out.println("
"); 1145 | 1146 | } catch (Exception e) { 1147 | System.err.println("Exception (printDocumentFooter): " + e.getMessage()); 1148 | } 1149 | } 1150 | 1151 | /* 1152 | * Create a formatted string from the exception's message 1153 | * 1154 | *@param e any exception other than a SAXParseException 1155 | *@return a formatted string 1156 | */ 1157 | private static String formatOtherThanSAXParseEx(Exception e) 1158 | { 1159 | String msg = e.getMessage(); 1160 | if (msg == null) 1161 | msg = e.toString(); 1162 | msg = replaceString(msg,"&","&"); 1163 | msg = replaceString(msg,"<","<"); 1164 | msg = replaceString(msg,">",">"); 1165 | msg = replaceString(msg,"\"","""); 1166 | msg = replaceString(msg,"'","'"); 1167 | return msg; 1168 | } 1169 | 1170 | /* 1171 | * Servlet's get info method 1172 | */ 1173 | public String getServletInfo () { 1174 | return "Servlet wrapper for the ARP RDF parser. This is revision " + REVISION; 1175 | } 1176 | 1177 | /* 1178 | * Servlet's init method 1179 | * 1180 | *@param config the servlet's configuration object 1181 | *@throws ServletException 1182 | */ 1183 | public void init(ServletConfig config) throws ServletException 1184 | { 1185 | super.init (config); 1186 | 1187 | try { 1188 | String t = config.getInitParameter("LOG_A_LOT"); 1189 | Matcher m = LogALotPattern.matcher(t); 1190 | if (m.find() && m.group(1) != null) { 1191 | System.err.println("considering LOG_A_LOT value \"" + t + "\" to be true base on substring \"" + m.group(1) + "\""); 1192 | LogALot = true; 1193 | } else { 1194 | System.err.println("considering LOG_A_LOT value \"" + t + "\" to be false."); 1195 | } 1196 | } catch (Throwable t) { 1197 | } 1198 | 1199 | // Cache the required parameters ... 1200 | m_ServletTmpDir = config.getInitParameter(SERVLET_TMP_DIR); 1201 | m_RenderDot = config.getInitParameter("RENDER_DOT"); 1202 | 1203 | // ... and the optional parameters. 1204 | try { m_BitmappedFont = config.getInitParameter("BITMAPPED_FONT"); } catch (Throwable t) {} 1205 | try { m_VectorFont = config.getInitParameter("VECTOR_FONT"); } catch (Throwable t) {} 1206 | 1207 | if (m_ServletTmpDir == null) { 1208 | System.err.println ( 1209 | "" + 1210 | "

Servlet Initialization Error

" + 1211 | "

One or more of the following parameters has not been initialized: " + 1212 | SERVLET_TMP_DIR + "

"); 1213 | } 1214 | } 1215 | 1216 | /* 1217 | * Servlet's destroy info method 1218 | */ 1219 | public void destroy () { 1220 | super.destroy (); 1221 | } 1222 | 1223 | /* 1224 | * Servlet's doGet info method - supported for testing 1225 | * 1226 | *@param req the request 1227 | *@param res the response 1228 | *@throws ServletException, IOException 1229 | */ 1230 | public void doGet (HttpServletRequest req, HttpServletResponse res) 1231 | throws ServletException, IOException 1232 | { 1233 | req.setCharacterEncoding("UTF-8"); 1234 | String sRDF = req.getParameter(TEXT); 1235 | String sURI = req.getParameter(URI); 1236 | 1237 | sRDF = (sRDF == null) ? "" : sRDF; 1238 | sURI = (sURI == null) ? "" : sURI; 1239 | 1240 | // try { 1241 | // sRDF = java.net.URLDecoder.decode(sRDF, "UTF-8"); 1242 | // sURI = java.net.URLDecoder.decode(sURI, "UTF-8"); 1243 | //} catch (Exception e) { 1244 | // System.err.println("Exception: URLDecoder.decode()"); 1245 | // } 1246 | 1247 | process(req, res, sRDF, sURI); 1248 | } 1249 | 1250 | /* 1251 | * Servlet's doPost method 1252 | * 1253 | *@param req the request 1254 | *@param res the response 1255 | *@throws ServletException, IOException, java.io.UnsupportedEncodingException 1256 | */ 1257 | public void doPost (HttpServletRequest req, HttpServletResponse res) 1258 | throws ServletException, IOException 1259 | { 1260 | // String encoding = req.getCharacterEncoding(); 1261 | // if (encoding == null) { 1262 | req.setCharacterEncoding("UTF-8"); 1263 | // } 1264 | req.setCharacterEncoding("UTF-8"); 1265 | String sRDF = req.getParameter(TEXT); 1266 | String sURI = req.getParameter(URI); 1267 | 1268 | sRDF = (sRDF == null) ? "" : sRDF; 1269 | sURI = (sURI == null) ? "" : sURI; 1270 | 1271 | try { 1272 | process(req,res,sRDF, sURI); 1273 | } catch (Throwable t) { 1274 | t.printStackTrace(System.err); 1275 | } 1276 | } 1277 | 1278 | /* 1279 | * Output a Resource in NTriples syntax 1280 | * 1281 | *@param out the servlet's output Writer 1282 | *@param r the Resource to output 1283 | */ 1284 | static private void printResource(PrintWriter out, AResource r) 1285 | { 1286 | if (r.isAnonymous() ) 1287 | out.print("_:j" + r.getAnonymousID() + " "); 1288 | else 1289 | out.print("<" + r.getURI() + "> "); 1290 | } 1291 | 1292 | /* 1293 | * Convert to Hex and padd left with zeroes 1294 | * 1295 | *@param in the integer to convert and padd 1296 | *@param in the length of the result 1297 | *@return the padded string 1298 | */ 1299 | // MJD: is there an easier way to do this? 1300 | static private String hexPadd (int number, int length) 1301 | { 1302 | String t = Integer.toHexString(number).toUpperCase(); 1303 | int hexlength = t.length(); 1304 | 1305 | if ( hexlength > length ) { // too long, truncate 1306 | hexlength = length; 1307 | } 1308 | 1309 | int zerolength = length - hexlength; 1310 | String r = ""; 1311 | 1312 | for (int i=0; i < zerolength; i++) { 1313 | r += "0"; 1314 | } 1315 | for (int i=0; i < hexlength; i++) { 1316 | r += t.charAt(i); 1317 | } 1318 | return r; 1319 | } 1320 | 1321 | /* 1322 | * Output a Literal in NTriples syntax 1323 | * 1324 | *@param out the servlet's output Writer 1325 | *@param l the Literal to output 1326 | */ 1327 | static private void printNTripleLiteral(PrintWriter out, ALiteral l) 1328 | { 1329 | out.print("\""); 1330 | char ar[] = l.toString().toCharArray(); 1331 | 1332 | for (int i=0;i= 32 && ar[i] <= 127 ) 1351 | out.print(ar[i]); 1352 | else if ( ar[i] < 0xD800 || ar[i] >= 0xE000) 1353 | out.print("\\u" + hexPadd(ar[i], 4) ); 1354 | else { // deal with surrogates 1355 | // check for correct surrogate pair 1356 | // this code should probably move somewhere else: 1357 | // check when we get the input 1358 | if ( ar[i] >= 0xDC00 ) { 1359 | out.print("{{{error: lone low surrogate}}}"); 1360 | } 1361 | else if ( ++i >= ar.length ) { 1362 | out.print("{{{error: lone surrogate at end of string}}}"); 1363 | } 1364 | else if ( ar[i] < 0xDC00 || ar[i] >= 0xE000 ) { 1365 | out.print("{{{error: high surrogate not followed by low surrogate}}}"); 1366 | } 1367 | // no errors, actually print 1368 | else { 1369 | int scalarvalue = 0x10000 + (ar[i-1] * 1024) + ar[i]; 1370 | out.print("\\U" + hexPadd(scalarvalue, 8) ); 1371 | } 1372 | } 1373 | } 1374 | } 1375 | out.print("\" "); 1376 | String s1=""; 1377 | if (l.getLang()!=null && l.getLang().length()>0){//add language info if it exists 1378 | s1+="@"+l.getLang(); 1379 | } 1380 | if (l.getDatatypeURI()!=null){//add datatype info if it exists 1381 | String s2=l.getDatatypeURI(); 1382 | s2 = replaceString(s2, "<", "<"); 1383 | s2 = replaceString(s2, ">", ">"); 1384 | s2 = replaceString(s2, "&", "&"); 1385 | if (s2.length()>0){ 1386 | s1+="^^"+s2; 1387 | } 1388 | } 1389 | if (s1.length()>0){out.print(s1);} 1390 | } 1391 | 1392 | /* 1393 | * Control point for outputing an triple in NTriple syntax 1394 | * 1395 | *@param out the servlet's output Writer 1396 | *@param subj the subject 1397 | *@param pred the predicate 1398 | *@param objRes the object as a Resource (may be null) 1399 | *@param objLit the object as a Literal (may be null) 1400 | */ 1401 | static private void printNTriple(PrintWriter out, AResource subj, 1402 | AResource pred, AResource objRes, ALiteral objLit) 1403 | { 1404 | printResource(out, subj); 1405 | printResource(out, pred); 1406 | if (objRes != null) 1407 | printResource(out, objRes); 1408 | else 1409 | printNTripleLiteral(out, objLit); 1410 | out.println("."); 1411 | } 1412 | 1413 | /* 1414 | * Create a HTML anchor from the URI or anonNode of the 1415 | * given Resource 1416 | * 1417 | *@param r the Resource 1418 | *@return the string as an HTML anchor 1419 | */ 1420 | static private String addAnchor(AResource r) 1421 | { 1422 | if (r.isAnonymous()) 1423 | return ANON_NODE + r.getAnonymousID(); 1424 | else 1425 | return "" + r.getURI().replaceAll("<", "<") + ""; 1426 | } 1427 | 1428 | /* 1429 | * Output a triple as a row in HTML 1430 | * 1431 | *@param out the servlet's output Writer 1432 | *@param subj the subject 1433 | *@param pred the predicate 1434 | *@param objRes the object as a Resource (may be null) 1435 | *@param objLit the object as a Literal (may be null) 1436 | *@param num the statement number 1437 | */ 1438 | static private void printTableRow(PrintWriter out, AResource subj, 1439 | AResource pred, AResource objRes, ALiteral objLit, int num) 1440 | { 1441 | out.println("" + num + ""); 1442 | out.println("" + addAnchor(subj) + ""); 1443 | out.println("" + addAnchor(pred) + ""); 1444 | if (objRes != null) 1445 | out.println("" + addAnchor(objRes) + ""); 1446 | else { 1447 | out.println(""); 1448 | String s1 = objLit.toString().trim(); 1449 | s1 = replaceString(s1, "<", "<"); 1450 | s1 = replaceString(s1, ">", ">"); 1451 | s1 = replaceString(s1, "&", "&"); 1452 | s1 = """+s1+"""; 1453 | if (objLit.getLang()!=null && objLit.getLang().length()>0){//add language info if it exists 1454 | s1+="@"+objLit.getLang(); 1455 | } 1456 | if (objLit.getDatatypeURI()!=null){//add datatype info if it exists 1457 | String s3=objLit.getDatatypeURI(); 1458 | s3 = replaceString(s3, "<", "<"); 1459 | s3 = replaceString(s3, ">", ">"); 1460 | s3 = replaceString(s3, "&", "&"); 1461 | if (s3.length()>0){ 1462 | s1+="^^"+s3; 1463 | } 1464 | } 1465 | out.println(s1); 1466 | out.println(""); 1467 | } 1468 | out.println(""); 1469 | } 1470 | 1471 | private static class SH implements StatementHandler 1472 | { 1473 | PrintWriter out; 1474 | PrintWriter pw; 1475 | boolean isNTriples; 1476 | boolean printTriples; 1477 | boolean printGraph; 1478 | boolean anonNodesEmpty; 1479 | int numStatements; 1480 | int numLiterals; 1481 | Hashtable subjects; 1482 | int numSubjects; 1483 | String gFormat; 1484 | 1485 | /* 1486 | * Constructuor for the StatementHandler. The primary 1487 | * responsiblitly is to cache init variables 1488 | * 1489 | *@param out the servlet's output Writer 1490 | *@param pw the Dot file's PrintWriter 1491 | * syntax; otherwise use HTML syntax 1492 | *@param isNTriples if true, output using the NTriples 1493 | *@param printTriples if true, print the triples 1494 | *@param printGraph if true, create the graph file 1495 | *@param printGraph if true, anonomyous nodes should be empty 1496 | */ 1497 | public SH(PrintWriter out, PrintWriter pw, boolean isNTriples, 1498 | boolean printTriples, boolean printGraph, boolean anonNodesEmpty,String graphFormat) 1499 | { 1500 | this.out = out; 1501 | this.pw = pw; 1502 | this.isNTriples = isNTriples; 1503 | this.printTriples = printTriples; 1504 | this.printGraph = printGraph; 1505 | this.anonNodesEmpty = anonNodesEmpty; 1506 | 1507 | this.numStatements = 0; 1508 | this.numLiterals = 0; 1509 | 1510 | this.subjects = new Hashtable(); 1511 | this.numSubjects = 0; 1512 | this.gFormat=graphFormat; 1513 | } 1514 | 1515 | /* 1516 | * Generic handler for a Resource/Resource/Resource triple (S/P/O). 1517 | * Dispatches to the methods that do the real work. 1518 | * 1519 | *@param subj the subject 1520 | *@param pred the predicate 1521 | *@param obj the object (as a Resource) 1522 | */ 1523 | public void statement(AResource subj, AResource pred, AResource obj) 1524 | { 1525 | if (!ARPServlet.AT_LEAST_ONE_TRIPLE){ARPServlet.AT_LEAST_ONE_TRIPLE=true;} 1526 | if (printTriples) 1527 | statementResource(subj, pred, obj); 1528 | if (printGraph) 1529 | statementDotResource(subj, pred, obj); 1530 | } 1531 | 1532 | /* 1533 | * Generic handler for a Resource/Resource/Resource triple (S/P/O). 1534 | * Dispatches to the methods that do the real work. 1535 | * 1536 | *@param subj the subject 1537 | *@param pred the predicate 1538 | *@param obj the object (as a Literal) 1539 | */ 1540 | public void statement(AResource subj, AResource pred, ALiteral lit) 1541 | { 1542 | if (!ARPServlet.AT_LEAST_ONE_TRIPLE){ARPServlet.AT_LEAST_ONE_TRIPLE=true;} 1543 | numLiterals++; 1544 | if (printTriples) 1545 | statementLiteral(subj, pred, lit); 1546 | if (printGraph) 1547 | statementDotLiteral(subj, pred, lit); 1548 | } 1549 | 1550 | /* 1551 | * Handler for a Resource/Resource/Resource triple (S/P/O) 1552 | * Outputs the given triple using NTriples or HTML syntax. 1553 | * 1554 | *@param subj the subject 1555 | *@param pred the predicate 1556 | *@param obj the object (as a Resource) 1557 | */ 1558 | public void statementResource(AResource subj, AResource pred, AResource obj) 1559 | { 1560 | numStatements++; 1561 | 1562 | if (this.isNTriples) 1563 | printNTriple(out, subj, pred, obj, null); 1564 | else 1565 | printTableRow(out, subj, pred, obj, null, this.numStatements); 1566 | } 1567 | 1568 | /* 1569 | * Handler for a Resource/Resource/Literal triple (S/P/O) 1570 | * Outputs the given triple using NTriples or HTML syntax. 1571 | * 1572 | *@param subj the subject 1573 | *@param pred the predicate 1574 | *@param obj the object (as a Literal) 1575 | */ 1576 | public void statementLiteral(AResource subj, AResource pred, ALiteral lit) 1577 | { 1578 | numStatements++; 1579 | 1580 | if (this.isNTriples) 1581 | printNTriple(out, subj, pred, null, lit); 1582 | else 1583 | printTableRow(out, subj, pred, null, lit, this.numStatements); 1584 | } 1585 | 1586 | /* 1587 | * Print the first part of a triple's Dot file. See below for 1588 | * more info. This is the same regardless if the triple's 1589 | * object is a Resource or a Literal 1590 | * 1591 | *@param subj the subject 1592 | */ 1593 | public void printFirstPart(AResource subj) 1594 | { 1595 | if (subj.isAnonymous()) { 1596 | if (this.anonNodesEmpty) { 1597 | Integer n = (Integer) subjects.get(subj.getAnonymousID()); 1598 | if (n == null) { 1599 | this.numSubjects++; 1600 | subjects.put(subj.getAnonymousID(), new Integer(this.numSubjects)); 1601 | this.pw.println("\"" + ANON_NODE + subj.getAnonymousID() + "\" [label=\" \"];"); 1602 | } 1603 | } 1604 | this.pw.print("\"" + ANON_NODE + subj.getAnonymousID()); 1605 | } else { 1606 | if (gFormat!=null && gFormat.equals(FORMAT_ISV_ZVTM)){ 1607 | this.pw.println("\"" + subj.getURI() + "\" [fontcolor=\""+Float.toString(ARPServlet.resTBh)+","+Float.toString(ARPServlet.resTBs)+","+Float.toString(ARPServlet.resTBv)+"\",URL=\"" +subj.getURI() + "\"];"); 1608 | } 1609 | else { 1610 | this.pw.println("\"" + subj.getURI() + "\" [URL=\"" +subj.getURI() + "\"];"); 1611 | } 1612 | this.pw.print("\"" + subj.getURI()); 1613 | } 1614 | } 1615 | 1616 | /* 1617 | * Handler for a Resource/Resource/Resource triple (S/P/O). 1618 | * Outputs the given triple using Dot syntax. 1619 | * 1620 | * Each triple will be output in three lines of DOT code as 1621 | * follows (not including the complication of anon nodes 1622 | * and the possiblity that the anon nodes may be named 1623 | * with an empty string): 1624 | * 1625 | * 1. "" [URL="]; 1626 | * 2. "" -> "" [label="",URL=""]; 1627 | * 3. "" [URL=""]; 1628 | * 1629 | *@param subj the subject 1630 | *@param pred the predicate 1631 | *@param obj the object (as a Resource) 1632 | */ 1633 | public void statementDotResource(AResource subj, AResource pred, AResource obj) 1634 | { 1635 | if (this.pw == null) return; 1636 | 1637 | printFirstPart(subj); 1638 | 1639 | this.pw.print("\" -> "); 1640 | 1641 | if (obj.isAnonymous()) { 1642 | if (this.anonNodesEmpty) { 1643 | if (gFormat!=null && gFormat.equals(FORMAT_ISV_ZVTM)){ 1644 | this.pw.println("\"" + ANON_NODE +obj.getAnonymousID() + "\" [fontcolor=\""+Float.toString(ARPServlet.prpTh)+","+Float.toString(ARPServlet.prpTs)+","+Float.toString(ARPServlet.prpTv)+"\",label=\"" + pred.getURI() + "\",URL=\"" + pred.getURI() + "\"];"); 1645 | } 1646 | else { 1647 | this.pw.println("\"" + ANON_NODE +obj.getAnonymousID() + "\" [label=\"" + pred.getURI() + "\",URL=\"" + pred.getURI() + "\"];"); 1648 | } 1649 | } else { 1650 | if (gFormat!=null && gFormat.equals(FORMAT_ISV_ZVTM)){ 1651 | this.pw.println("\"" + ANON_NODE + obj.getAnonymousID() + "\" [fontcolor=\""+Float.toString(ARPServlet.prpTh)+","+Float.toString(ARPServlet.prpTs)+","+Float.toString(ARPServlet.prpTv)+"\",label=\"" + pred.getURI() + "\",URL=\"" +pred.getURI() + "\"];"); 1652 | } 1653 | else { 1654 | this.pw.println("\"" + ANON_NODE + obj.getAnonymousID() + "\" [label=\"" + pred.getURI() + "\",URL=\"" +pred.getURI() + "\"];"); 1655 | } 1656 | } 1657 | } else { 1658 | if (gFormat!=null && gFormat.equals(FORMAT_ISV_ZVTM)){ 1659 | this.pw.println("\"" + obj.getURI() + "\" [fontcolor=\""+Float.toString(ARPServlet.prpTh)+","+Float.toString(ARPServlet.prpTs)+","+Float.toString(ARPServlet.prpTv)+"\",label=\"" +pred.getURI() + "\",URL=\"" + pred.getURI() + "\"];"); 1660 | this.pw.println("\"" + obj.getURI() + "\" [fontcolor=\""+Float.toString(resTBh)+","+Float.toString(resTBs)+","+Float.toString(resTBv)+"\",URL=\"" +obj.getURI() + "\"];"); 1661 | } 1662 | else { 1663 | this.pw.println("\"" + obj.getURI() + "\" [label=\"" +pred.getURI() + "\",URL=\"" + pred.getURI() + "\"];"); 1664 | this.pw.println("\"" + obj.getURI() + "\" [URL=\"" +obj.getURI() + "\"];"); 1665 | } 1666 | } 1667 | } 1668 | 1669 | /* 1670 | * Handler for a Resource/Resource/Literal triple (S/P/O). 1671 | * Outputs the given triple using Dot syntax. 1672 | * 1673 | * Each triple will be output in three lines of DOT code as 1674 | * follows (not including the complication of anon nodes 1675 | * and the possiblity that the anon nodes may be named 1676 | * with an empty string): 1677 | * 1678 | * 1. "" [URL="]; 1679 | * 2. "" -> "" [label="",URL=""]; 1680 | * 3. "" [shape="box"]; 1681 | * 1682 | *@param subj the subject 1683 | *@param pred the predicate 1684 | *@param obj the object (as a Literal) 1685 | */ 1686 | public void statementDotLiteral(AResource subj, AResource pred, ALiteral lit) 1687 | { 1688 | if (this.pw == null) return; 1689 | 1690 | printFirstPart(subj); // Same as Res/Res/Res 1691 | 1692 | /* 1693 | * Before outputing the object (Literal) do the following: 1694 | * 1695 | * o GraphViz/DOT cannot handle embedded line terminators characters 1696 | * so they must be replaced with spaces 1697 | * o Limit the number of chars to make the graph legible 1698 | * o Escape double quotes 1699 | */ 1700 | String s1 = new String(lit.toString()); 1701 | s1 = s1.replace('\n', ' '); 1702 | s1 = s1.replace('\f', ' '); 1703 | s1 = s1.replace('\r', ' '); 1704 | if (s1.indexOf('"') != -1) 1705 | s1 = replaceString(s1, "\"", "\\\""); 1706 | 1707 | // Anything beyond 80 chars makes the graph too large 1708 | String tmpObject; 1709 | if (s1.length() >= 80) 1710 | tmpObject = s1.substring(0, 80) + " ..."; 1711 | else 1712 | tmpObject = s1.substring(0, s1.length()); 1713 | 1714 | // Create a temporary label for the literal so that if 1715 | // it is duplicated it will be unique in the graph and 1716 | // thus have its own node. 1717 | String tmpName = "Literal_" + Integer.toString(this.numLiterals); 1718 | this.pw.print("\" -> \"" + tmpName); 1719 | 1720 | if (gFormat!=null && gFormat.equals(FORMAT_ISV_ZVTM)){ 1721 | this.pw.println("\" [fontcolor=\""+Float.toString(ARPServlet.prpTh)+","+Float.toString(ARPServlet.prpTs)+","+Float.toString(ARPServlet.prpTv)+"\",label=\"" + pred.getURI() + "\",URL=\"" + pred.getURI() + "\"];"); 1722 | this.pw.println("\"" + tmpName + "\" [fontcolor=\""+Float.toString(litTBh)+","+Float.toString(litTBs)+","+Float.toString(litTBv)+"\",shape=box,label=\"" + tmpObject + "\"];"); 1723 | } 1724 | else { 1725 | this.pw.println("\" [label=\"" + pred.getURI() + "\",URL=\"" + pred.getURI() + "\"];"); 1726 | this.pw.println("\"" + tmpName + "\" [shape=box,label=\"" + tmpObject + "\"];"); 1727 | } 1728 | } 1729 | } 1730 | 1731 | private void printErrorMessages(PrintWriter out, SaxErrorHandler eh) 1732 | { 1733 | try { 1734 | String s; 1735 | boolean c = true; 1736 | 1737 | out.println("

" + 1738 | "Validation Results

"); 1739 | 1740 | s = eh.getFatalErrors(); 1741 | if (s != null && s.length() >= 1) { 1742 | out.println("

Fatal Error Messages

" + s); 1743 | c = false; 1744 | } 1745 | 1746 | s = eh.getErrors(); 1747 | if (s != null && s.length() >= 1) { 1748 | out.println("

Error Messages

" + s); 1749 | c = false; 1750 | } 1751 | 1752 | s = eh.getWarnings(); 1753 | if (s != null && s.length() >= 1) { 1754 | out.println("

Warning Messages

" + s); 1755 | c = false; 1756 | } 1757 | 1758 | if (c){ 1759 | if (AT_LEAST_ONE_TRIPLE){ 1760 | out.println("

Your RDF document validated successfully.

"); 1761 | } 1762 | else { 1763 | out.println("

Error: Your document does not contain any RDF statement.

"); 1764 | } 1765 | AT_LEAST_ONE_TRIPLE=false; 1766 | } 1767 | 1768 | /*the following should not happen anymore, as we use ARP2 which supports datatypes, but leave it there for now, just in case*/ 1769 | s = eh.getDatatypeErrors(); 1770 | if (s != null && s.length() >= 2){//2 to prevent an arrayindexoutofbounds exception 1771 | out.println("

Note about datatypes

"); 1772 | out.println("

Datatypes are used on lines "+s.substring(0,s.length()-2)+". This RDF feature is not yet supported by the RDF Validator. Literals are treated as untyped.

"); 1773 | } 1774 | 1775 | } catch (Exception e) { 1776 | System.err.println(SERVLET_NAME + ": Error printing error messages."); 1777 | } 1778 | } 1779 | 1780 | /* 1781 | * Initialize the graph output file. If an error occurs, this 1782 | * function will print an error message. 1783 | * 1784 | *@param out the servlet's output Writer 1785 | *@req the servlet request object 1786 | *@return the File object for the graph file; null if an error occurs 1787 | */ 1788 | private File initGraphFile(PrintWriter out, 1789 | HttpServletRequest req) 1790 | { 1791 | try { 1792 | // Stop if any of the parameters are missing 1793 | if (m_ServletTmpDir == null) 1794 | { 1795 | // Put the paths in a comment in the returned content 1796 | out.println(""); 1797 | 1798 | out.println("

Servlet initialization failed

"); 1799 | out.println("Please send a message to " + MAIL_TO + " and mention this problem."); 1800 | return null; 1801 | } 1802 | } catch (Exception e) { 1803 | System.err.println("Unable to create a temporary graph file. A graph cannot be generated."); 1804 | return null; 1805 | } 1806 | 1807 | File dotFile = null; 1808 | 1809 | // Must generate a unique file name that the DOT handler will use 1810 | dotFile = createTempFile(m_ServletTmpDir, TMP_FILE_PREFIX, SUFFIX_DOT); 1811 | if (dotFile == null) { 1812 | out.println("

Failed to create a temporary graph file. A graph cannot be generated.

"); 1813 | System.err.println("Failed to create temporary graph file \""+TMP_FILE_PREFIX+" "+SUFFIX_DOT+"\" in \""+m_ServletTmpDir+"\" . A graph cannot be generated."); 1814 | return null; 1815 | } 1816 | 1817 | return dotFile; 1818 | } 1819 | 1820 | /* 1821 | * Check if the given URI is supported or not 1822 | * 1823 | *@param out the servlet's output Writer 1824 | *@param uri the URI to check 1825 | *@return true if the URI is supported; false otherwise 1826 | */ 1827 | private boolean isURISupported(PrintWriter out, String uri) 1828 | { 1829 | try { 1830 | if (uri.length() >= 4 && uri.substring(0,4).equalsIgnoreCase("file")) { 1831 | out.println("

file URI Schemes are NOT Supported

"); 1832 | out.println("URIs from the 'file' URI scheme are not supported by this servlet."); 1833 | return false; 1834 | } 1835 | } catch (Exception e) { 1836 | System.err.println("Exception in isURISupported."); 1837 | return false; 1838 | } 1839 | 1840 | return true; 1841 | } 1842 | 1843 | /* 1844 | * Handle the servlets doGet or doPut request 1845 | * 1846 | *@param req the servlet's request 1847 | *@param res the servlet's response 1848 | *@throws SevletException, IOException 1849 | */ 1850 | private void process(HttpServletRequest req, HttpServletResponse res, 1851 | String sRDF, String sURI) throws ServletException, IOException 1852 | { 1853 | String sSaveRDF = req.getParameter (SAVE_RDF); 1854 | String sSaveDOTFile = req.getParameter (SAVE_DOT_FILE); 1855 | String sNTriples = req.getParameter (NTRIPLES); 1856 | String sEmbedded = req.getParameter (EMBEDDED_RDF); 1857 | String sTriplesAndGraph = req.getParameter (TRIPLES_AND_GRAPH); 1858 | String sAnonNodesEmpty = req.getParameter (ANON_NODES_EMPTY); 1859 | String sParse = req.getParameter (PARSE); 1860 | String sFormat = req.getParameter (FORMAT); 1861 | if (sFormat==null) 1862 | sFormat = DEFAULT_FORMAT; 1863 | 1864 | // Set the print flags 1865 | boolean printTriples = false; 1866 | boolean printGraph = false; 1867 | if (sTriplesAndGraph != null) { 1868 | if (sTriplesAndGraph.equals(PRINT_TRIPLES)) { 1869 | printTriples = true; 1870 | } 1871 | if (sTriplesAndGraph.equals(PRINT_GRAPH)) { 1872 | printGraph = true; 1873 | } 1874 | if (sTriplesAndGraph.equals(PRINT_BOTH)) { 1875 | printTriples = true; 1876 | printGraph = true; 1877 | } 1878 | } 1879 | 1880 | // Determine if printing the triples and/or graph 1881 | boolean anonNodesEmpty = (sAnonNodesEmpty != null) ? true : false; 1882 | boolean nTriples = (sNTriples != null) ? true : false; 1883 | 1884 | // ARP parser has embedded = true by default so if user 1885 | // wants embedding, must set it to false 1886 | boolean embedded = (sEmbedded != null) ? false : true; 1887 | 1888 | res.setContentType ("text/html;charset=utf-8"); 1889 | PrintWriter out = res.getWriter (); 1890 | 1891 | // Temporary buffer to rearrange output (placing validation 1892 | // success or failure at top 1893 | StringWriter sw = new StringWriter(); 1894 | PrintWriter outtmp = new PrintWriter(sw); 1895 | 1896 | printDocumentHeader (out); 1897 | 1898 | boolean parseRDF = true; 1899 | if (sParse != null) 1900 | parseRDF = sParse.equals("Parse RDF"); 1901 | else if (!sURI.equals("")) // continue even if PARSE is not present 1902 | parseRDF = false; 1903 | 1904 | if (parseRDF) sURI = ""; 1905 | else sRDF = ""; 1906 | 1907 | // getting encoding right: bad hack, but it works :-( 1908 | // sRDF = new String(sRDF.getBytes("iso-8859-1"), "utf-8"); 1909 | // sURI = new String(sURI.getBytes("iso-8859-1"), "utf-8"); 1910 | 1911 | if ((!parseRDF && sURI.equals("")) || (parseRDF && sRDF.equals(""))) { 1912 | out.println("

" + (parseRDF ? "RDF" : "URI") 1913 | + " was not specified.

"); 1914 | printDocumentFooter(out, null); 1915 | return; 1916 | } 1917 | 1918 | String xmlBase = null; 1919 | 1920 | if (!sURI.equals("")) { 1921 | 1922 | // First check for unsupported URIs 1923 | if (!isURISupported(out, sURI)) { 1924 | printDocumentFooter(out, null); 1925 | return; 1926 | } 1927 | 1928 | xmlBase = sURI; 1929 | try { 1930 | sRDF = getRDFfromURI(sURI); 1931 | if (sRDF == null) 1932 | throw new getRDFException("The URI may not exist or the server is down.@@"); 1933 | } catch (getRDFException e) { 1934 | out.println("

RDF Load Error

"); 1935 | out.println("An attempt to load the RDF from URI '" + sURI.replace("<", "<") + 1936 | "' failed. (" + e.getMessage() + ")"); 1937 | printDocumentFooter(out, null); 1938 | return; 1939 | } 1940 | } else { 1941 | java.util.Date d = new java.util.Date(); 1942 | xmlBase = DEFAULT_NAMESPACE + d.getTime() + '#'; 1943 | } 1944 | 1945 | PrintWriter pw = null; // The writer for the graph file 1946 | OutputStreamWriter osw = null; 1947 | File dotFile = null; // The graph file 1948 | if (printGraph) { 1949 | dotFile = initGraphFile(out, req); 1950 | if (dotFile == null) 1951 | // Assume error has been reported 1952 | return; 1953 | // Create a PrintWriter for the DOT handler 1954 | FileOutputStream fos = new FileOutputStream(dotFile); 1955 | if (fos != null) 1956 | osw = new OutputStreamWriter(fos, "utf-8"); 1957 | if (osw != null) 1958 | pw = new PrintWriter(osw); 1959 | if (pw != null) 1960 | // Add the graph header 1961 | processGraphParameters (req, pw, (sFormat.equals(FORMAT_PNG_EMBED)) || (sFormat.equals(FORMAT_PNG_LINK)) || (sFormat.equals(FORMAT_GIF_EMBED)) || (sFormat.equals(FORMAT_GIF_LINK))); 1962 | } 1963 | 1964 | // Create the StatementHandler - it will handle triples for 1965 | // the table/ntriples and the graph file 1966 | SH sh = new SH(outtmp, pw, nTriples, printTriples, printGraph, anonNodesEmpty,sFormat); 1967 | 1968 | // Create the ErrorHandler 1969 | SaxErrorHandler errorHandler = new SaxErrorHandler(out, false); 1970 | 1971 | // Create and initialize the parser 1972 | 1973 | // System.err.println("-----------------------------------------------"); 1974 | // System.err.println("Determining class for ARP"); 1975 | // String arp="com.hp.hpl.jena.rdf.arp.ARP"; 1976 | // try { 1977 | // Class c = Class.forName (arp); 1978 | // String classRes = "/"+arp.replace ('.', '/')+ 1979 | // ".class"; 1980 | // System.out.println ("Class "+arp+ 1981 | // " URL: "+c.getResource (classRes)); 1982 | // } 1983 | // catch (Throwable t) 1984 | // { 1985 | // System.out.println ("Unable to locate class "+arp); 1986 | // } 1987 | 1988 | ARP parser = new com.hp.hpl.jena.rdf.arp.ARP(); 1989 | parser.getHandlers().setErrorHandler(errorHandler); 1990 | parser.getHandlers().setStatementHandler(sh); 1991 | parser.getOptions().setEmbedding(embedded); 1992 | parser.getOptions().setStrictErrorMode(); 1993 | 1994 | try { 1995 | java.lang.reflect.Field arpfField = parser.getClass().getDeclaredField("arpf"); 1996 | arpfField.setAccessible(true); 1997 | RDFXMLParser arpf = (RDFXMLParser) arpfField.get(parser); 1998 | java.lang.reflect.Field saxParserField = arpf.getClass().getDeclaredField("saxParser"); 1999 | saxParserField.setAccessible(true); 2000 | org.apache.xerces.parsers.SAXParser saxParser = (org.apache.xerces.parsers.SAXParser) saxParserField.get(arpf); 2001 | saxParser.setFeature("http://xml.org/sax/features/external-general-entities", false); 2002 | } catch (NoSuchFieldException|IllegalAccessException|SAXException e) { 2003 | throw new RuntimeException("should not be here"); 2004 | } 2005 | 2006 | if (printTriples) 2007 | printTripleTableHeader (outtmp, nTriples); 2008 | 2009 | try { 2010 | StringReader sr = new StringReader (sRDF); 2011 | parser.load(sr, xmlBase); 2012 | } catch (Exception ex) { 2013 | out.println ("

Parser " + 2014 | "Loading Error

"); 2015 | out.println ("Exception parsing: " +formatOtherThanSAXParseEx(ex)); 2016 | printDocumentFooter(out, null); 2017 | return; 2018 | } 2019 | 2020 | if (printTriples) 2021 | printTripleTableFooter(outtmp, nTriples); 2022 | 2023 | printErrorMessages(out, errorHandler); 2024 | out.print(sw.toString()); 2025 | 2026 | printListing (out, sRDF, !parseRDF); 2027 | 2028 | res.flushBuffer(); 2029 | if (sFormat != null && printGraph) { 2030 | generateGraph(out, pw, dotFile, sRDF, req, sFormat, 2031 | (sSaveRDF != null) ? true : false, 2032 | (sSaveDOTFile != null && sSaveDOTFile.equals ("on") ? true : false)); 2033 | } 2034 | 2035 | 2036 | if (!parseRDF) 2037 | printDocumentFooter(out, null); 2038 | else 2039 | printDocumentFooter(out, sRDF); 2040 | } 2041 | } 2042 | -------------------------------------------------------------------------------- /src/main/resources/log4j.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /src/main/scala/JettyMain.scala: -------------------------------------------------------------------------------- 1 | package org.w3 2 | package rdfvalidator 3 | 4 | import org.eclipse.jetty.server.nio.SelectChannelConnector 5 | import org.eclipse.jetty.server.Server 6 | import org.eclipse.jetty.server.handler.ContextHandlerCollection 7 | import org.eclipse.jetty.webapp.WebAppContext 8 | import org.eclipse.jetty.servlet.{ DefaultServlet, ServletContextHandler, ServletHolder } 9 | 10 | object JettyMain { 11 | 12 | def main(args: Array[String]): Unit = { 13 | 14 | val port = args.headOption.map(_.toInt).getOrElse(8080) 15 | 16 | val server: Server = new Server 17 | 18 | server.setGracefulShutdown(500) 19 | server.setSendServerVersion(false) 20 | server.setSendDateHeader(true) 21 | server.setStopAtShutdown(true) 22 | 23 | val connector = new SelectChannelConnector 24 | connector.setPort(port) 25 | connector.setMaxIdleTime(90000) 26 | server.addConnector(connector) 27 | 28 | val webapp = "src/main/webapp" 29 | val webApp = new WebAppContext 30 | webApp.setContextPath("/") 31 | webApp.setResourceBase(webapp) 32 | webApp.setDescriptor(webapp + "/WEB-INF/web.xml") 33 | 34 | server.setHandler(webApp) 35 | 36 | server.start() 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/web.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | RDF Validator 4 | 5 | This is the friggin' RDF Validator 6 | 7 | 8 | 9 | RDFValidatorServlet 10 | org.w3c.rdfvalidator.ARPServlet 11 | 12 | SERVLET_TMP_DIR 13 | RDFValidator/ARPServlet.tmp 14 | 15 | 16 | BITMAPPED_FONT 17 | cyberbit 18 | 19 | 20 | VECTOR_FONT 21 | Courier 22 | 23 | 24 | RENDER_DOT 25 | RDFValidator/renderDot 26 | 27 | 28 | LOG_A_LOT 29 | 1 30 | 31 | 32 | 33 | 34 | RDFValidatorServlet 35 | /rdfval 36 | 37 | 38 | 39 | RDFValidatorServlet 40 | /ARPServlet 41 | 42 | 43 | 44 | StaticContent 45 | org.eclipse.jetty.servlet.DefaultServlet 46 | 47 | resourceBase 48 | RDFValidator 49 | 50 | 51 | dirAllowed 52 | false 53 | 54 | 55 | 56 | 57 | StaticContent 58 | /ARPServlet.tmp/* 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /src/main/webapp/index.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | W3C RDF Validation Service 8 | 9 | 12 | 13 | 14 | 15 | 16 | 17 | 23 | 30 | 31 |
32 | 33 | 34 | 35 |

Check and Visualize your RDF documents

36 |

olde servlet

37 |

Enter a URI or paste an RDF/XML document into the text field above. 38 | A 3-tuple (triple) representation of the corresponding data model as well as 39 | an optional graphical visualization of the data model will be displayed.

40 | 41 |
42 | Check by Direct Input 43 |
44 |


52 | 53 | 54 | 56 |

57 |

Display Result Options:
58 | Triples and/or Graph: 59 |
64 | Graph format: 65 | 78 |

79 |

Paste an RDF/XML document into the following text field to have it checked. 80 | More options are available in the Extended interface.

81 | 82 |
83 |
84 | 85 |
Check by URI 86 |
87 |

88 | 89 | 90 | 91 |

92 |

Display Result Options:
93 | Triples and/or Graph: 94 |
99 | Graph format: 100 | 113 |

114 |

Enter the URI for the RDF/XML document you would like to check. 115 | More options are available in the Extended interface.

116 |
117 |
118 | 119 | 120 | 121 | 122 |
123 | 124 |
125 | 128 | Last modified $Date: 2006/02/28 16:30:38 $ 129 |
130 | Eric Prud'hommeaux
131 | 132 | 133 | 134 | 135 | -------------------------------------------------------------------------------- /src/test/scala/RDFValidatorTest.scala: -------------------------------------------------------------------------------- 1 | package org.w3.rdfvalidator 2 | 3 | import org.scalatra.test.scalatest._ 4 | import org.scalatest.matchers._ 5 | 6 | class RDFValidatorTest extends ScalatraFunSuite with ShouldMatchers { 7 | 8 | addServlet(classOf[RDFValidator], "/*") 9 | 10 | def validate(uri:String, expectedUnicornStatus:String, contains:String) = 11 | test(uri) { 12 | get("/rdfvalidator?uri="+uri) { 13 | status should equal (200) 14 | val unicornStatus = (scala.xml.XML.loadString(body) \ "status" \ "@value").head.asInstanceOf[scala.xml.Text].toString 15 | unicornStatus should equal (expectedUnicornStatus) 16 | body should include (contains) 17 | } 18 | } 19 | 20 | def failed(uri:String, contains:String) = 21 | validate(uri, "failed", contains) 22 | 23 | def passed(uri:String, contains:String) = 24 | validate(uri, "passed", contains) 25 | 26 | failed("http://www.w3.org/2000/10/rdf-tests/rdfcore/rdf-containers-syntax-vs-schema/error001.rdf", "E206") 27 | failed("http://www.w3.org/2000/10/rdf-tests/rdfcore/rdf-containers-syntax-vs-schema/error002.rdf", "E204") 28 | passed("http://www.w3.org/People/Berners-Lee/card.rdf", "") 29 | 30 | } 31 | -------------------------------------------------------------------------------- /w3c.json: -------------------------------------------------------------------------------- 1 | { 2 | "contacts": ["dontcallmedom"], 3 | "repo-type": "tool" 4 | } 5 | --------------------------------------------------------------------------------