This experimental tool uses the DDMSence library to validate Unclassified DDMS 2.0, 3.0, 3.1, 4.0.1, 4.1, and 5.0 records. Records can be submitted by pasting XML text or referencing a URL.
Starred fields (*) are required.
Compilable source code for this tool is not bundled with DDMSence, because it has dependencies on the Spring Framework (v6.1.2). However, all of the pieces you need create a similar web application are shown below. A basic understanding of Spring MVC will be necessary to understand the code.
validator.uri
.
The type
parameter is used to determine what sort of form should be displayed -- changing
the "Record Location" drop-down selection redraws the form.package buri.urizone.web.control.ddmsence; import buri.ddmsence.ddms.IDDMSComponent; import buri.ddmsence.ddms.InvalidDDMSException; import buri.ddmsence.ddms.Resource; import buri.ddmsence.ddms.UnsupportedVersionException; import buri.ddmsence.ddms.ValidationMessage; import buri.ddmsence.ddms.security.ism.SecurityAttributes; import buri.ddmsence.util.DDMSReader; import buri.ddmsence.util.DDMSVersion; import buri.ddmsence.util.PropertyReader; import jakarta.servlet.http.HttpServletRequest; import nu.xom.Document; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.validation.BindingResult; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.SessionAttributes; import org.springframework.web.bind.support.SessionStatus; import org.xml.sax.XMLReader; import org.xml.sax.helpers.XMLReaderFactory; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.LineNumberReader; import java.io.Reader; import java.io.StringReader; import java.net.URL; import java.net.URLConnection; import java.util.Date; import java.util.HashSet; import java.util.Set; /** * Controller class for validating DDMS Records * * @author Brian Uri! */ @Controller @SessionAttributes({ "record" }) public class ValidatorControl extends AbstractControl { /** * Entry point for creating a new form */ @RequestMapping(value = "/validator.uri", method = RequestMethod.GET) public String newForm( @RequestParam(value = "type", required = false, defaultValue = ValidatorRecord.DEFAULT_TYPE) String type, Model model) { model.addAttribute("record", new ValidatorRecord(type)); return ("validator"); } /** * Entry point for validating the form contents */ @RequestMapping(value = "/validator.uri", method = RequestMethod.POST) public String validate(@ModelAttribute("record") ValidatorRecord record, BindingResult result, SessionStatus status, Model model, HttpServletRequest request) { String stringRepresentation = null; try { if (ValidatorRecord.TYPE_TEXT.equals(record.getType())) { stringRepresentation = record.getStringRecord(); } else if (ValidatorRecord.TYPE_URL.equals(record.getType())) { String fullUrl = "http://" + record.getUrl(); try { URL url = new URL(fullUrl); URLConnection uc = url.openConnection(); stringRepresentation = readStream(new BufferedReader(new InputStreamReader(uc.getInputStream()))); } catch (IOException e) { throw new IOException("Could not connect to URL: " + fullUrl); } } model.addAttribute("xml", stringRepresentation); DDMSVersion version = guessVersion(stringRepresentation); PropertyReader.setProperty("output.json.prettyPrint", "true"); PropertyReader.setProperty("output.indexLevel", "1"); Resource resource = new DDMSReader(version).getDDMSResource(stringRepresentation); if (isUnclassified(resource)) { model.addAttribute("warnings", resource.getValidationWarnings()); model.addAttribute("html", resource.toHTML()); model.addAttribute("text", resource.toText()); model.addAttribute("json", resource.toJSON()); } else { model.addAttribute("xml", null); throw new InvalidDDMSException("This tool can only be used on Unclassified data."); } } catch (InvalidDDMSException e) { ValidationMessage message = ValidationMessage.newError(e.getMessage(), e.getLocator()); model.addAttribute("error", message); } catch (Exception e) { ValidationMessage message = ValidationMessage.newError(e.getMessage(), null); model.addAttribute("error", message); } return ("validatorResult"); } /** * Helper method to attempt to guess which version of DDMS to use, based * upon the namespace URI of the root element, via a non-validating builder. * * @param potentialResource a String containing the resource * @return the version * @throws UnsupportedVersionException if the version could not be guessed. * @throws InvalidDDMSException if the file could not be parsed. */ private DDMSVersion guessVersion(String potentialResource) throws InvalidDDMSException { try { XMLReader reader = XMLReaderFactory.createXMLReader(PropertyReader.getProperty("xml.reader.class")); nu.xom.Builder builder = new nu.xom.Builder(reader, false); Document doc = builder.build(new StringReader(potentialResource)); String namespace = doc.getRootElement().getNamespaceURI(); return (DDMSVersion.getVersionForNamespace(namespace)); } catch (Exception e) { throw new InvalidDDMSException("Could not create a valid element from potential resource: " + e.getMessage()); } } /** * Converts the contents of a stream into a String * * @param streamReader the reader around the original input stream * @return a String * @throws IOException */ private String readStream(Reader streamReader) throws IOException { LineNumberReader reader = new LineNumberReader(streamReader); StringBuffer buffer = new StringBuffer(); String currentLine = reader.readLine(); while (currentLine != null) { buffer.append(currentLine).append("\n"); currentLine = reader.readLine(); } return (buffer.toString()); } /** * Prevents classified data from being validated here. * * @param resource the DDMS Resource */ private boolean isUnclassified(Resource resource) throws InvalidDDMSException { Set<SecurityAttributes> allAttributes = new HashSet<SecurityAttributes>(); allAttributes.add(resource.getSecurityAttributes()); for (IDDMSComponent component : resource.getTopLevelComponents()) { if (component.getSecurityAttributes() != null) allAttributes.add(component.getSecurityAttributes()); } for (SecurityAttributes attr : allAttributes) { if (!"U".equals(attr.getClassification()) && !"".equals(attr.getClassification())) return (false); } return (true); } }
newForm()
method.
This is a simple data class which supports the form you see on this page.package buri.urizone.web.control.ddmsence; import buri.ddmsence.util.Util; /** * Form bean for online DDMS validation * * @author Brian Uri! */ public class ValidatorRecord { public static final String TYPE_TEXT = "text"; public static final String TYPE_URL = "url"; public static final String DEFAULT_TYPE = TYPE_TEXT; private String _type; private String _stringRecord; private String _url; /** * Constructor * * @param type the type of record being submitted. */ public ValidatorRecord(String type) { if (Util.isEmpty(type)) type = DEFAULT_TYPE; _type = type; } /** * Accessor for the string version of the record. */ public String getStringRecord() { return _stringRecord; } /** * Accessor for the string version of the record. */ public void setStringRecord(String stringRecord) { _stringRecord = stringRecord; } /** * Accessor for the type (url, text) */ public String getType() { return _type; } /** * Accessor for the url */ public String getUrl() { return _url; } /** * Accessor for the url */ public void setUrl(String url) { _url = url; } }
validate()
method of the ValidatorControl is called. This method checks to see whether the DDMS
Resource is coming in as text or a URL. URLs are loaded and converted into text.getDDMSResource()
attempts to build the entire DDMS Resource.
It will fail immediately with an InvalidDDMSException
if the Resource is invalid.model
,
is then used to render the Validation Results page.