blob: d895e3e33509bf7f939bcafd76a23d8917bb0733 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.tika.server.core.resource;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.HEAD;
import javax.ws.rs.OPTIONS;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import org.apache.cxf.jaxrs.lifecycle.ResourceProvider;
import org.apache.tika.Tika;
import org.apache.tika.server.core.HTMLHelper;
/**
* <p>Provides a basic welcome to the Apache Tika Server.</p>
*/
@Path("/")
public class TikaWelcome {
private static final String DOCS_URL = "https://wiki.apache.org/tika/TikaJAXRS";
private static final Map<Class<? extends Annotation>, String> HTTP_METHODS =
new HashMap<>();
static {
HTTP_METHODS.put(DELETE.class, "DELETE");
HTTP_METHODS.put(GET.class, "GET");
HTTP_METHODS.put(HEAD.class, "HEAD");
HTTP_METHODS.put(OPTIONS.class, "OPTIONS");
HTTP_METHODS.put(POST.class, "POST");
HTTP_METHODS.put(PUT.class, "PUT");
}
private Tika tika;
private HTMLHelper html;
private List<Class<?>> endpoints = new LinkedList<>();
public TikaWelcome(List<ResourceProvider> rCoreProviders) {
this.tika = new Tika(TikaResource.getConfig());
this.html = new HTMLHelper();
for (ResourceProvider rp : rCoreProviders) {
this.endpoints.add(rp.getResourceClass());
}
}
protected List<Endpoint> identifyEndpoints() {
List<Endpoint> found = new ArrayList<>();
for (Class<?> endpoint : endpoints) {
Path p = endpoint.getAnnotation(Path.class);
String basePath = null;
if (p != null) {
basePath =
p.value().endsWith("/") ? p.value().substring(0, p.value().length() - 2) :
p.value();
}
for (Method m : endpoint.getMethods()) {
String httpMethod = null;
String methodPath = null;
String[] produces = null;
for (Annotation a : m.getAnnotations()) {
for (Class<? extends Annotation> httpMethAnn : HTTP_METHODS.keySet()) {
if (httpMethAnn.isInstance(a)) {
httpMethod = HTTP_METHODS.get(httpMethAnn);
}
}
if (a instanceof Path) {
methodPath = ((Path) a).value();
}
if (a instanceof Produces) {
produces = ((Produces) a).value();
}
}
if (httpMethod != null) {
String mPath = basePath;
if (mPath == null) {
mPath = "";
}
if (methodPath != null) {
if (methodPath.startsWith("/")) {
mPath += methodPath;
} else {
mPath += "/" + methodPath;
}
}
if (produces == null) {
produces = new String[0];
}
found.add(new Endpoint(endpoint, m, mPath, httpMethod, produces));
}
}
}
found.sort(Comparator.comparing((Endpoint e) -> e.path).thenComparing(e -> e.methodName));
return found;
}
@GET
@Produces("text/html")
public String getWelcomeHTML() {
TikaResource.checkIsOperating();
StringBuffer h = new StringBuffer();
String tikaVersion = tika.toString();
html.generateHeader(h, "Welcome to the " + tikaVersion + " Server");
h.append("<p>For endpoints, please see <a href=\"");
h.append(DOCS_URL);
h.append("\">");
h.append(DOCS_URL);
h.append("</a>");
// TIKA-1269 -- Miredot documentation
// As the SNAPSHOT endpoints are updated, please update the website by running
// the server tests and doing step 12.6 of https://wiki.apache.org/tika/ReleaseProcess.
Pattern p = Pattern.compile("\\d+\\.\\d+");
Matcher m = p.matcher(tikaVersion);
if (m.find()) {
String versionNumber = m.group();
String miredot = "https://tika.apache.org/" + versionNumber + "/miredot/index.html";
h.append(" and <a href=\"").append(miredot).append("\">").append(miredot)
.append("</a>");
}
h.append("</p>\n");
h.append("<ul>\n");
for (Endpoint e : identifyEndpoints()) {
h.append("<li><b>");
h.append(e.httpMethod);
h.append("</b> <i><a href=\"");
h.append(e.path);
h.append("\">");
h.append(e.path);
h.append("</a></i><br />");
h.append("Class: ");
h.append(e.className);
h.append("<br />Method: ");
h.append(e.methodName);
for (String produces : e.produces) {
h.append("<br />Produces: ");
h.append(produces);
}
h.append("</li>\n");
}
h.append("</ul>\n");
html.generateFooter(h);
return h.toString();
}
@GET
@Produces("text/plain")
public String getWelcomePlain() {
TikaResource.checkIsOperating();
StringBuffer text = new StringBuffer();
text.append(tika.toString());
text.append("\n");
text.append("For endpoints, please see ");
text.append(DOCS_URL);
text.append("\n\n");
for (Endpoint e : identifyEndpoints()) {
text.append(e.httpMethod);
text.append(" ");
text.append(e.path);
text.append("\n");
for (String produces : e.produces) {
text.append(" => ");
text.append(produces);
text.append("\n");
}
}
return text.toString();
}
protected static class Endpoint {
public final String className;
public final String methodName;
public final String path;
public final String httpMethod;
public final List<String> produces;
protected Endpoint(Class<?> endpoint, Method method, String path, String httpMethod,
String[] produces) {
this.className = endpoint.getCanonicalName();
this.methodName = method.getName();
this.path = path;
this.httpMethod = httpMethod;
this.produces = Collections.unmodifiableList(Arrays.asList(produces));
}
}
}