All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.leibnizcenter.rechtspraak.SearchRequest Maven / Gradle / Ivy

There is a newer version: 2.0.4
Show newest version
package org.leibnizcenter.rechtspraak;

import com.google.common.base.Preconditions;
import com.squareup.okhttp.HttpUrl;
import com.squareup.okhttp.OkHttpClient;
import com.squareup.okhttp.Request;
import com.squareup.okhttp.Response;
import org.jsoup.HttpStatusException;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import java.io.IOException;
import java.io.StringReader;
import java.security.InvalidParameterException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * A search request to rechtspraak.nl. Retrieves a list of judgments and their metadata.
 * 

* See https://www.rechtspraak.nl/Uitspraken-en-Registers/Uitspraken/Open-Data/Documents/Technische-documentatie-Open-Data-van-de-Rechtspraak.pdf for documentation on the Rechtspraak.nl web service *

* Created by maarten on 31-7-15. */ public class SearchRequest { final SAXParserFactory factory = SAXParserFactory.newInstance(); private final Request mRequest; /** * Client for doing HTTP requests */ private final OkHttpClient sHttpClient = new OkHttpClient(); private final Builder builder; private SearchRequest(Builder b) { this.builder = b; mRequest = new Request.Builder() .url(b.urlBuilder.build()) .build(); } public Builder getBuilder() { return builder; } public Request getRequest() { return mRequest; } public Response getResponse() throws IOException { return sHttpClient.newCall(mRequest).execute(); } public SearchResult execute() throws IOException, ParserConfigurationException, SAXException { // System.out.println(getResponse().body().string().toString()); Response resp = getResponse(); if (resp.code() == 200) { String str = getResponse().body().string(); SAXParser saxParser = factory.newSAXParser(); ResultHandler handler = new ResultHandler(); try { saxParser.parse(new InputSource(new StringReader(str)), handler); } catch (SAXException e) { System.err.println(str); throw e; } return new SearchResult(this, handler.judgments); } else { throw new HttpStatusException("Code was not 200 but " + resp.code(), resp.code(), getRequest().url().toString()); } } public enum ReturnType {META, DOC} public enum Sort {ASC, DESC} public enum Type {Conclusie, Uitspraak} /** * See https://www.rechtspraak.nl/Uitspraken-en-Registers/Uitspraken/Open-Data/Documents/Technische-documentatie-Open-Data-van-de-Rechtspraak.pdf for documentation on the Rechtspraak.nl web service */ public static class Builder { public static final DateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd"); public static final DateFormat MODIFIED_FORMAT = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss"); private final HttpUrl.Builder urlBuilder; private int offset = 0; public Builder() { urlBuilder = initBuilder(); } /** * @param returnType Whether to return only documents with content, * or documents that have at least metadata. The later is the default, * but it is more likely that you are looking for the former. */ public Builder(ReturnType returnType) { urlBuilder = initBuilder(); urlBuilder.addQueryParameter("return", returnType.toString()); } private HttpUrl.Builder initBuilder() { HttpUrl.Builder mBuilder; mBuilder = new HttpUrl.Builder() .scheme("http") .host("data.rechtspraak.nl") .addPathSegment("uitspraken") .addPathSegment("zoeken"); return mBuilder; } /** * @param max Maximum number of results to return. Cannot be larger than 1000. */ public Builder max(int max) { if (max > 1000 | max < 1) { throw new InvalidParameterException("Return limit needs to be a number between 1 and 1000 inclusive"); } urlBuilder.addQueryParameter("max", max + ""); return this; } /** * @param type The type of content to return (only metadata or metadata+document) */ public Builder returnType(ReturnType type) { urlBuilder.addQueryParameter("return", type.toString()); return this; } /** * @param from Offset in results, used for pagination. */ public Builder from(int from) { if (from < 0) { from = 0; } this.offset = from; urlBuilder.addQueryParameter("from", from + ""); return this; } /** * @param sort Sort results on modification date ascending or descending. Default is ascending (oldest first). */ public Builder sort(Sort sort) { urlBuilder.addQueryParameter("sort", sort.toString()); return this; } /** * @param replaces Returns ECLI judgments that replace given LJN number */ public Builder replaces(String replaces) { urlBuilder.addQueryParameter("replaces", replaces); return this; } /** * @param date the particular date to return judgments taken on * @see #date(Date, Date) */ public Builder date(Date date) { urlBuilder.addQueryParameter("date", DATE_FORMAT.format(date)); return this; } /** * Returns judgments taken between given two dates * * @param date1 search window start date, inclusive * @param date2 search window end date, inclusive */ public Builder date(Date date1, Date date2) { urlBuilder.addQueryParameter("date", DATE_FORMAT.format(date1)); urlBuilder.addQueryParameter("date", DATE_FORMAT.format(date2)); return this; } /** * @param modified return judgment documents that where modified on this date or after * @see #modified(Date, Date) */ public Builder modified(Date modified) { urlBuilder.addQueryParameter("modified", MODIFIED_FORMAT.format(modified)); return this; } /** * return judgment documents that where modified between given dates * * @param modified1 search window start date * @param modified2 search window end date * @see #modified(Date, Date) */ public Builder modified(Date modified1, Date modified2) { urlBuilder.addQueryParameter("modified", MODIFIED_FORMAT.format(modified1)); urlBuilder.addQueryParameter("modified", MODIFIED_FORMAT.format(modified2)); return this; } /** * @param type The type of document to return ('uitspraak' or 'conclusie') */ public Builder type(Type type) { urlBuilder.addQueryParameter("type", type.toString()); return this; } /** * @param subject Subject URI for a legal field */ public Builder subject(String subject) { urlBuilder.addQueryParameter("subject", subject); return this; } @Override public String toString() { return urlBuilder.toString(); } public SearchRequest build() { return new SearchRequest(this); } public HttpUrl.Builder getBuilder() { return urlBuilder; } public int getFrom() { return offset; } public int getOffset() { return offset; } } public static class ResultHandler extends DefaultHandler { private static final Pattern SUBTITLE_PATTERN = Pattern.compile("([0-9]*)\\s*\\.?\\s*$"); public final List judgments = new ArrayList<>(); private final Stack elementStack = new Stack<>(); public int results = -1; private String id; private String title; private String summary; private String updated; private String linkRel; private String linkType; private String linkHref; private String subtitle; public void startElement(String uri, String localName, String qName, Attributes attributes) { this.elementStack.push(qName); switch (qName) { case "entry": case "id": case "title": case "summary": case "updated": break; case "link": linkRel = attributes.getValue("rel"); linkType = attributes.getValue("type"); linkHref = attributes.getValue("href"); break; default: break; } } @SuppressWarnings("RedundantStringToString") // Because we want to ensure they're not null public void endElement(String uri, String localName, String qName) { this.elementStack.pop(); if ("entry".equals(qName)) { JudgmentMetadata judgment = new JudgmentMetadata( id, title, summary, Date.from( javax.xml.bind.DatatypeConverter.parseDateTime(updated.toString()) .toInstant()), new JudgmentMetadata.Link( linkRel, linkType, linkHref ) ); id = null; title = null; summary = null; updated = null; linkRel = null; linkType = null; linkHref = null; judgments.add(judgment); } if ("subtitle".equals(qName)) { Matcher match = SUBTITLE_PATTERN.matcher(subtitle.toString()); if (match.find()) { String number = match.group(1); results = Integer.parseInt(number); } subtitle = null; } } public void characters(char ch[], int start, int length) { String value = new String(ch, start, length).trim(); if (value.length() == 0) return; // ignore white space if (Objects.equals(currentElementParent(), "entry")) { switch (currentElement()) { case "id": id = (id != null ? id : "") + value; break; case "title": title = (title != null ? title : "") + value; break; case "summary": summary = (summary != null ? summary : "") + value; break; case "updated": updated = (updated != null ? updated : "") + value; break; default: break; } } switch (currentElement()) { case "subtitle": subtitle = (subtitle != null ? subtitle : "") + value; break; } } private String currentElement() { return this.elementStack.peek(); } private String currentElementParent() { if (this.elementStack.size() < 2) return null; return this.elementStack.get(this.elementStack.size() - 2); } } public static class JudgmentMetadata { public final String id; public final String title; public final String summary; public final Date updated; public final Link link; public JudgmentMetadata(String id, String title, String summary, Date updated, Link link) { Preconditions.checkArgument(id != null && id.length() > 0); Preconditions.checkNotNull(title, id + ": null pointer for title"); // if (summary == null) { // System.out.println("Summary was null: " + summary); // } // if (updated == null) { // System.out.println("Updated was null: " + updated); // } Preconditions.checkNotNull(link, id + ": null pointer for link"); this.id = id; this.title = title; this.summary = summary; this.updated = updated; this.link = link; } @Override public String toString() { return "JudgmentMetadata{" + "\n id='" + id + '\'' + ", \n title='" + title + '\'' + ", \n summary='" + summary + '\'' + ", \n updated=" + updated + ", \n link=" + link + "\n}"; } public static class Link { public final String rel; public final String type; public final String href; public Link(String rel, String type, String href) { Preconditions.checkNotNull(rel); Preconditions.checkNotNull(type); Preconditions.checkNotNull(href); this.rel = rel; this.type = type; this.href = href; } @Override public String toString() { return "Link{" + "\n rel='" + rel + '\'' + ", \n type='" + type + '\'' + ", \n href='" + href + '\'' + "\n}"; } } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy