http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/244cc21a/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/AtomFeedResource.java ---------------------------------------------------------------------- diff --git a/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/AtomFeedResource.java b/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/AtomFeedResource.java new file mode 100755 index 0000000..46f9006 --- /dev/null +++ b/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/AtomFeedResource.java @@ -0,0 +1,106 @@ +/*************************************************************************************************************************** + * 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.juneau.server.samples; + +import static javax.xml.bind.DatatypeConverter.*; +import static org.apache.juneau.html.HtmlDocSerializerContext.*; +import static org.apache.juneau.jena.RdfCommonContext.*; +import static org.apache.juneau.jena.RdfSerializerContext.*; + +import java.net.*; + +import org.apache.juneau.dto.atom.*; +import org.apache.juneau.dto.atom.Content; +import org.apache.juneau.encoders.*; +import org.apache.juneau.microservice.*; +import org.apache.juneau.server.annotation.*; + +/** + * Sample resource that shows how to generate ATOM feeds. + */ +@RestResource( + path="/atom", + messages="nls/AtomFeedResource", + properties={ + @Property(name=SERIALIZER_quoteChar, value="'"), + @Property(name=RDF_rdfxml_tab, value="5"), + @Property(name=RDF_addRootProperty, value="true"), + @Property(name=HTMLDOC_links, value="{up:'$R{requestParentURI}',options:'?method=OPTIONS',source:'$R{servletParentURI}/source?classes=(org.apache.juneau.server.samples.AtomFeedResource)'}") + }, + encoders=GzipEncoder.class +) +public class AtomFeedResource extends ResourceJena { + private static final long serialVersionUID = 1L; + + private Feed feed; // The root resource object + + @Override /* Servlet */ + public void init() { + + try { + feed = new Feed() + .setTitle(new Text("text", "Juneau ATOM specification")) + .setSubTitle(new Text("html", "A <em>lot</em> of effort went into making this effortless")) + .setUpdated(parseDateTime("2013-05-08T12:29:29Z")) + .setId(new Id("tag:juneau.sample.com,2013:1")) + .addLinks( + new Link("alternate", "text/html", "http://www.sample.com/").setHreflang("en"), + new Link("self", "application/atom+xml", "http://www.sample.com/feed.atom") + ) + .setRights(new Text("Copyright (c) 2013, IBM")) + .setGenerator(new Generator("Juneau").setUri(new URI("http://juneau.ibm.com/")).setVersion("1.0")) + .addEntries( + new Entry() + .setTitle(new Text("Juneau ATOM specification snapshot")) + .addLinks( + new Link("alternate", "text/html", "http://www.sample.com/2012/05/08/juneau.atom"), + new Link("enclosure", "audio/mpeg", "http://www.sample.com/audio/juneau_podcast.mp3").setLength(12345) + ) + .setId(new Id("tag:juneau.sample.com,2013:1.2345")) + .setUpdated(parseDateTime("2013-05-08T12:29:29Z")) + .setPublished(parseDateTime("2013-05-08T12:29:29Z")) + .addAuthors(new Person("James Bognar").setUri(new URI("http://www.sample.com/")).setEmail("[email protected]")) + .addContributors( + new Person("Barry M. Caceres") + ) + .setContent( + new Content() + .setLang("en") + .setBase(new URI("http://www.ibm.com/")) + .setType("xhtml") + .setText("<div xmlns=\"http://www.w3.org/1999/xhtml\"><p><i>[Update: Juneau supports ATOM.]</i></p></div>") + ) + ); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + /** + * GET request handler + */ + @RestMethod(name="GET", path="/") + public Feed getFeed() throws Exception { + return feed; + } + + /** + * PUT request handler. + * Replaces the feed with the specified content, and then mirrors it as the response. + */ + @RestMethod(name="PUT", path="/") + public Feed setFeed(@org.apache.juneau.server.annotation.Content Feed feed) throws Exception { + this.feed = feed; + return feed; + } +}
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/244cc21a/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/CodeFormatterResource.html ---------------------------------------------------------------------- diff --git a/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/CodeFormatterResource.html b/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/CodeFormatterResource.html new file mode 100755 index 0000000..2523daa --- /dev/null +++ b/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/CodeFormatterResource.html @@ -0,0 +1,48 @@ +<!DOCTYPE HTML> +<html> +<head> + <style type='text/css'> + @import '$R{servletURI}/style.css'; + </style> + <script> + // Quick and dirty function to allow tabs in textarea. + function checkTab(e) { + if (e.keyCode == 9) { + var t = e.target; + var ss = t.selectionStart, se = t.selectionEnd; + t.value = t.value.slice(0,ss).concat('\t').concat(t.value.slice(ss,t.value.length)); + e.preventDefault(); + } + } + // Load results from IFrame into this document. + function loadResults(buff) { + var doc = buff.contentDocument || buff.contentWindow.document; + var buffBody = doc.getElementById('data'); + if (buffBody != null) { + document.getElementById('results').innerHTML = buffBody.innerHTML; + } + } + </script> +</head> +<body> + <h3 class='title'>Code Formatter</h3> + <div class='data'> + <form id='form' action='codeFormatter' method='POST' target='buff'> + <table> + <tr> + <th>Language: </th> + <td><input name='lang' value='java'></td> + <td><button type='submit'>Submit</button><button type='reset'>Reset</button></td> + </tr> + <tr> + <td colspan='3'><textarea name='code' style='width:100%;height:200px;font-family:Courier;font-size:9pt;' onkeydown='checkTab(event)'></textarea></td> + </tr> + </table> + </form> + <div id='results' class='monospace'> + </div> + </div> + <iframe name='buff' style='display:none' onload="parent.loadResults(this)"></iframe> +</body> +</html> + http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/244cc21a/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/CodeFormatterResource.java ---------------------------------------------------------------------- diff --git a/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/CodeFormatterResource.java b/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/CodeFormatterResource.java new file mode 100755 index 0000000..b225f96 --- /dev/null +++ b/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/CodeFormatterResource.java @@ -0,0 +1,50 @@ +/*************************************************************************************************************************** + * 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.juneau.server.samples; + +import static org.apache.juneau.html.HtmlDocSerializerContext.*; + +import java.io.*; + +import org.apache.juneau.microservice.*; +import org.apache.juneau.server.*; +import org.apache.juneau.server.annotation.*; + +/** + * Service at <code>/jazz/rawSql</code>. + * Used for executing SQL queries against the repository database. + */ +@RestResource( + path="/codeFormatter", + messages="nls/CodeFormatterResource", + properties={ + @Property(name=HTMLDOC_title, value="Code Formatter"), + @Property(name=HTMLDOC_description, value="Add syntax highlighting tags to source code"), + @Property(name=HTMLDOC_links, value="{options:'?method=OPTIONS',source:'$R{servletParentURI}/source?classes=(org.apache.juneau.server.samples.CodeFormatterResource)'}"), + } +) +@SuppressWarnings("serial") +public class CodeFormatterResource extends Resource { + + /** [GET /] - Display query entry page. */ + @RestMethod(name="GET", path="/") + public ReaderResource getQueryEntryPage(RestRequest req) throws IOException { + return req.getReaderResource("CodeFormatterResource.html", true); + } + + /** [POST /] - Execute SQL query. */ + @RestMethod(name="POST", path="/") + public String executeQuery(@Param("code") String code, @Param("lang") String lang) throws Exception { + return SourceResource.highlight(code, lang); + } +} http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/244cc21a/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/Constants.java ---------------------------------------------------------------------- diff --git a/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/Constants.java b/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/Constants.java new file mode 100755 index 0000000..6af83a5 --- /dev/null +++ b/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/Constants.java @@ -0,0 +1,29 @@ +/*************************************************************************************************************************** + * 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.juneau.server.samples; + + +public class Constants { + + private static String juneauSampleUrl = System.getProperty("JUNO_SAMPLE_URL"); + + /** + * Returns the value of the "JUNO_SAMPLE_URL" system property, or throws a {@link RuntimeException} + * if it's not set. + */ + public static String getSampleUrl() { + if (juneauSampleUrl == null) + return "http://localhost:10000"; + return juneauSampleUrl; + } +} http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/244cc21a/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/DirectoryResource.java ---------------------------------------------------------------------- diff --git a/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/DirectoryResource.java b/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/DirectoryResource.java new file mode 100755 index 0000000..9dc71f2 --- /dev/null +++ b/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/DirectoryResource.java @@ -0,0 +1,234 @@ +/*************************************************************************************************************************** + * 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.juneau.server.samples; + +import static java.util.logging.Level.*; +import static javax.servlet.http.HttpServletResponse.*; +import static org.apache.juneau.html.HtmlDocSerializerContext.*; +import static org.apache.juneau.server.RestServletContext.*; + +import java.io.*; +import java.net.*; +import java.util.*; +import java.util.logging.*; + +import javax.servlet.*; + +import org.apache.juneau.*; +import org.apache.juneau.microservice.*; +import org.apache.juneau.server.*; +import org.apache.juneau.server.annotation.*; +import org.apache.juneau.server.annotation.Properties; +import org.apache.juneau.server.converters.*; +import org.apache.juneau.utils.*; + +/** + * Sample REST resource for exploring local file systems. + */ +@RestResource( + messages="nls/DirectoryResource", + properties={ + @Property(name=HTML_uriAnchorText, value=PROPERTY_NAME), + @Property(name=HTMLDOC_links, value="{up:'$R{requestParentURI}',options:'?method=OPTIONS',source:'$R{servletParentURI}/source?classes=(org.apache.juneau.server.samples.DirectoryResource)'}"), + @Property(name=REST_allowMethodParam, value="*"), + @Property(name="rootDir", value="$S{java.io.tmpdir}"), + @Property(name="allowViews", value="false"), + @Property(name="allowDeletes", value="false"), + @Property(name="allowPuts", value="false") + } +) +public class DirectoryResource extends Resource { + private static final long serialVersionUID = 1L; + + protected File rootDir; // The root directory + + // Settings enabled through servlet init parameters + protected boolean allowDeletes, allowPuts, allowViews; + + private static Logger logger = Logger.getLogger(DirectoryResource.class.getName()); + + @Override /* Servlet */ + public void init() throws ServletException { + ObjectMap p = getProperties(); + rootDir = new File(p.getString("rootDir")); + allowViews = p.getBoolean("allowViews", false); + allowDeletes = p.getBoolean("allowDeletes", false); + allowPuts = p.getBoolean("allowPuts", false); + } + + /** Returns the root directory defined by the 'rootDir' init parameter */ + protected File getRootDir() { + if (rootDir == null) { + rootDir = new File(getProperties().getString("rootDir")); + if (! rootDir.exists()) + if (! rootDir.mkdirs()) + throw new RuntimeException("Could not create root dir"); + } + return rootDir; + } + + /** GET request handler */ + @RestMethod(name="GET", path="/*", converters={Queryable.class}) + public Object doGet(RestRequest req, @Properties ObjectMap properties) throws Exception { + + String pathInfo = req.getPathInfo(); + File f = pathInfo == null ? rootDir : new File(rootDir.getAbsolutePath() + pathInfo); + + if (!f.exists()) + throw new RestException(SC_NOT_FOUND, "File not found"); + + properties.put("path", f.getAbsolutePath()); + + if (f.isDirectory()) { + List<FileResource> l = new LinkedList<FileResource>(); + for (File fc : f.listFiles()) { + URL fUrl = new URL(req.getRequestURL().append("/").append(fc.getName()).toString()); + l.add(new FileResource(fc, fUrl)); + } + return l; + } + + return new FileResource(f, new URL(req.getRequestURL().toString())); + } + + /** DELETE request handler */ + @RestMethod(name="DELETE", path="/*", guards=AdminGuard.class) + public Object doDelete(RestRequest req) throws Exception { + + if (! allowDeletes) + throw new RestException(SC_METHOD_NOT_ALLOWED, "DELETE not enabled"); + + File f = new File(rootDir.getAbsolutePath() + req.getPathInfo()); + deleteFile(f); + + if (req.getHeader("Accept").contains("text/html")) + return new Redirect(); + return "File deleted"; + } + + /** PUT request handler */ + @RestMethod(name="PUT", path="/*", guards=AdminGuard.class) + public Object doPut(RestRequest req) throws Exception { + + if (! allowPuts) + throw new RestException(SC_METHOD_NOT_ALLOWED, "PUT not enabled"); + + File f = new File(rootDir.getAbsolutePath() + req.getPathInfo()); + String parentSubPath = f.getParentFile().getAbsolutePath().substring(rootDir.getAbsolutePath().length()); + BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(f)); + IOPipe.create(req.getInputStream(), bos).closeOut().run(); + if (req.getContentType().contains("html")) + return new Redirect(parentSubPath); + return "File added"; + } + + /** VIEW request handler (overloaded GET for viewing file contents) */ + @RestMethod(name="VIEW", path="/*") + public void doView(RestRequest req, RestResponse res) throws Exception { + + if (! allowViews) + throw new RestException(SC_METHOD_NOT_ALLOWED, "VIEW not enabled"); + + File f = new File(rootDir.getAbsolutePath() + req.getPathInfo()); + + if (!f.exists()) + throw new RestException(SC_NOT_FOUND, "File not found"); + + if (f.isDirectory()) + throw new RestException(SC_METHOD_NOT_ALLOWED, "VIEW not available on directories"); + + res.setOutput(new FileReader(f)).setContentType("text/plain"); + } + + /** DOWNLOAD request handler (overloaded GET for downloading file contents) */ + @RestMethod(name="DOWNLOAD") + public void doDownload(RestRequest req, RestResponse res) throws Exception { + + if (! allowViews) + throw new RestException(SC_METHOD_NOT_ALLOWED, "DOWNLOAD not enabled"); + + File f = new File(rootDir.getAbsolutePath() + req.getPathInfo()); + + if (!f.exists()) + throw new RestException(SC_NOT_FOUND, "File not found"); + + if (f.isDirectory()) + throw new RestException(SC_METHOD_NOT_ALLOWED, "DOWNLOAD not available on directories"); + + res.setOutput(new FileReader(f)).setContentType("application"); + } + + /** File POJO */ + public class FileResource { + private File f; + private URL url; + + /** Constructor */ + public FileResource(File f, URL url) { + this.f = f; + this.url = url; + } + + // Bean property getters + + public URL getUrl() { + return url; + } + + public String getType() { + return (f.isDirectory() ? "dir" : "file"); + } + + public String getName() { + return f.getName(); + } + + public long getSize() { + return f.length(); + } + + public Date getLastModified() { + return new Date(f.lastModified()); + } + + public URL getView() throws Exception { + if (allowViews && f.canRead() && ! f.isDirectory()) + return new URL(url + "?method=VIEW"); + return null; + } + + public URL getDownload() throws Exception { + if (allowViews && f.canRead() && ! f.isDirectory()) + return new URL(url + "?method=DOWNLOAD"); + return null; + } + + public URL getDelete() throws Exception { + if (allowDeletes && f.canWrite()) + return new URL(url + "?method=DELETE"); + return null; + } + } + + /** Utility method */ + private void deleteFile(File f) { + try { + if (f.isDirectory()) + for (File fc : f.listFiles()) + deleteFile(fc); + f.delete(); + } catch (Exception e) { + logger.log(WARNING, "Cannot delete file '" + f.getAbsolutePath() + "'", e); + } + } +} http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/244cc21a/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/DockerRegistryResource.java ---------------------------------------------------------------------- diff --git a/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/DockerRegistryResource.java b/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/DockerRegistryResource.java new file mode 100755 index 0000000..6380794 --- /dev/null +++ b/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/DockerRegistryResource.java @@ -0,0 +1,88 @@ +/*************************************************************************************************************************** + * 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.juneau.server.samples; + +import static org.apache.juneau.html.HtmlDocSerializerContext.*; + +import java.util.*; + +import javax.servlet.*; + +import org.apache.juneau.client.*; +import org.apache.juneau.json.*; +import org.apache.juneau.microservice.*; +import org.apache.juneau.server.*; +import org.apache.juneau.server.annotation.*; +import org.apache.juneau.server.labels.*; + +/** + * Sample resource that shows how to mirror query results from a Docker registry. + */ +@RestResource( + path="/docker", + label="Sample Docker resource", + properties={ + @Property(name=HTMLDOC_links, value="{up:'$R{requestParentURI}',options:'?method=OPTIONS',source:'$R{servletParentURI}/source?classes=(org.apache.juneau.server.samples.AtomFeedResource)'}") + } +) +public class DockerRegistryResource extends Resource { + private static final long serialVersionUID = 1L; + + // Get registry URL from samples.cfg file. + private String registryUrl = getConfig().getString("DockerRegistry/url"); + + RestClient rc; + + @Override /* Servlet */ + public void init() throws ServletException { + super.init(); + rc = new RestClient(JsonSerializer.DEFAULT, JsonParser.DEFAULT); + } + + @Override /* Servlet */ + public void destroy() { + rc.closeQuietly(); + super.destroy(); + } + + /** [GET /] - Show child resources. */ + @SuppressWarnings("nls") + @RestMethod(name="GET", path="/") + public ResourceDescription[] getChildren(RestRequest req) { + return new ResourceDescription[] { + new ResourceDescription(req, "search", "Search Registry") + }; + } + + /** + * PUT request handler. + * Replaces the feed with the specified content, and then mirrors it as the response. + */ + @RestMethod(name="GET", path="/search") + public QueryResults query(@Param("q") String q) throws Exception { + String url = registryUrl + "/search" + (q == null ? "" : "?q=" + q); + synchronized(rc) { + return rc.doGet(url).getResponse(QueryResults.class); + } + } + + public static class QueryResults { + public int num_results; + public String query; + public List<DockerImage> results; + } + + public static class DockerImage { + public String name, description; + } +} http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/244cc21a/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/HelloWorldResource.java ---------------------------------------------------------------------- diff --git a/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/HelloWorldResource.java b/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/HelloWorldResource.java new file mode 100755 index 0000000..bb42b89 --- /dev/null +++ b/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/HelloWorldResource.java @@ -0,0 +1,38 @@ +/*************************************************************************************************************************** + * 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.juneau.server.samples; + +import static org.apache.juneau.html.HtmlDocSerializerContext.*; + +import org.apache.juneau.microservice.*; +import org.apache.juneau.server.annotation.*; + +/** + * Sample REST resource that prints out a simple "Hello world!" message. + */ +@RestResource( + messages="nls/HelloWorldResource", + path="/helloWorld", + properties={ + @Property(name=HTMLDOC_links, value="{up:'$R{requestParentURI}',options:'?method=OPTIONS'}") + } +) +public class HelloWorldResource extends Resource { + private static final long serialVersionUID = 1L; + + /** GET request handler */ + @RestMethod(name="GET", path="/*") + public String sayHello() { + return "Hello world!"; + } +} http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/244cc21a/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/JsonSchemaResource.java ---------------------------------------------------------------------- diff --git a/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/JsonSchemaResource.java b/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/JsonSchemaResource.java new file mode 100755 index 0000000..4e66ed4 --- /dev/null +++ b/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/JsonSchemaResource.java @@ -0,0 +1,74 @@ +/*************************************************************************************************************************** + * 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.juneau.server.samples; + +import static org.apache.juneau.html.HtmlDocSerializerContext.*; + +import org.apache.juneau.dto.jsonschema.*; +import org.apache.juneau.microservice.*; +import org.apache.juneau.server.annotation.*; + +/** + * Sample resource that shows how to serialize JSON-Schema documents. + */ +@RestResource( + path="/jsonSchema", + messages="nls/JsonSchemaResource", + properties={ + @Property(name=HTMLDOC_title, value="Sample JSON-Schema document"), + @Property(name=HTMLDOC_links, value="{up:'$R{requestParentURI}',options:'?method=OPTIONS',source:'$R{servletParentURI}/source?classes=(org.apache.juneau.server.samples.JsonSchemaResource)'}") + } +) +public class JsonSchemaResource extends ResourceJena { + private static final long serialVersionUID = 1L; + + private Schema schema; // The schema document + + @Override /* Servlet */ + public void init() { + + try { + schema = new Schema() + .setId("http://example.com/sample-schema#") + .setSchemaVersionUri("http://json-schema.org/draft-04/schema#") + .setTitle("Example Schema") + .setType(JsonType.OBJECT) + .addProperties( + new SchemaProperty("firstName", JsonType.STRING), + new SchemaProperty("lastName", JsonType.STRING), + new SchemaProperty("age", JsonType.INTEGER) + .setDescription("Age in years") + .setMinimum(0) + ) + .addRequired("firstName", "lastName"); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + /** GET request handler */ + @RestMethod(name="GET", path="/") + public Schema getSchema() throws Exception { + return schema; + } + + /** + * PUT request handler. + * Replaces the schema document with the specified content, and then mirrors it as the response. + */ + @RestMethod(name="PUT", path="/") + public Schema setSchema(@Content Schema schema) throws Exception { + this.schema = schema; + return schema; + } +} http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/244cc21a/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/MethodExampleResource.java ---------------------------------------------------------------------- diff --git a/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/MethodExampleResource.java b/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/MethodExampleResource.java new file mode 100755 index 0000000..176e874 --- /dev/null +++ b/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/MethodExampleResource.java @@ -0,0 +1,91 @@ +/*************************************************************************************************************************** + * 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.juneau.server.samples; + +import static org.apache.juneau.html.HtmlDocSerializerContext.*; + +import java.util.*; + +import org.apache.juneau.microservice.*; +import org.apache.juneau.server.*; +import org.apache.juneau.server.annotation.*; + +/** + * Sample REST resource that shows how to define REST methods and OPTIONS pages + */ +@RestResource( + path="/methodExample", + messages="nls/MethodExampleResource", + properties={ + @Property(name=HTMLDOC_links, value="{up:'$R{requestParentURI}',options:'?method=OPTIONS',source:'$R{servletParentURI}/source?classes=(org.apache.juneau.server.samples.MethodExampleResource)'}") + } +) +public class MethodExampleResource extends Resource { + private static final long serialVersionUID = 1L; + + /** Example GET request that redirects to our example method */ + @RestMethod(name="GET", path="/") + public Redirect doGetExample() throws Exception { + return new Redirect("example1/xxx/123/{0}/xRemainder?p1=123&p2=yyy", UUID.randomUUID()); + } + + /** Example GET request using annotated attributes */ + @RestMethod(name="GET", path="/example1/{a1}/{a2}/{a3}/*", rc={200}) + public String doGetExample1( + @Method String method, + @Attr String a1, + @Attr int a2, + @Attr UUID a3, + @Param("p1") int p1, + @Param("p2") String p2, + @Param("p3") UUID p3, + @PathRemainder String remainder, + @Header("Accept-Language") String lang, + @Header("Accept") String accept, + @Header("DNT") int doNotTrack + ) { + String output = String.format( + "method=%s, a1=%s, a2=%d, a3=%s, remainder=%s, p1=%d, p2=%s, p3=%s, lang=%s, accept=%s, dnt=%d", + method, a1, a2, a3, remainder, p1, p2, p3, lang, accept, doNotTrack); + return output; + } + + /** Example GET request using methods on RestRequest and RestResponse */ + @RestMethod(name="GET", path="/example2/{a1}/{a2}/{a3}/*", rc={200}) + public void doGetExample2(RestRequest req, RestResponse res) throws Exception { + String method = req.getMethod(); + + // Attributes (from URL pattern variables) + String a1 = req.getAttribute("a1", String.class); + int a2 = req.getAttribute("a2", int.class); + UUID a3 = req.getAttribute("a3", UUID.class); + + // Optional GET parameters + int p1 = req.getParameter("p1", int.class, 0); + String p2 = req.getParameter("p2", String.class); + UUID p3 = req.getParameter("p3", UUID.class); + + // URL pattern post-match + String remainder = req.getPathRemainder(); + + // Headers + String lang = req.getHeader("Accept-Language"); + int doNotTrack = req.getHeader("DNT", int.class); + + // Send back a simple String response + String output = String.format( + "method=%s, a1=%s, a2=%d, a3=%s, remainder=%s, p1=%d, p2=%s, p3=%s, lang=%s, dnt=%d", + method, a1, a2, a3, remainder, p1, p2, p3, lang, doNotTrack); + res.setOutput(output); + } +} http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/244cc21a/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/PhotosResource.java ---------------------------------------------------------------------- diff --git a/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/PhotosResource.java b/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/PhotosResource.java new file mode 100755 index 0000000..74573fb --- /dev/null +++ b/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/PhotosResource.java @@ -0,0 +1,142 @@ +/*************************************************************************************************************************** + * 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.juneau.server.samples; + +import static javax.servlet.http.HttpServletResponse.*; +import static org.apache.juneau.html.HtmlDocSerializerContext.*; + +import java.awt.image.*; +import java.io.*; +import java.net.*; +import java.net.URI; +import java.util.*; + +import javax.imageio.*; + +import org.apache.juneau.*; +import org.apache.juneau.annotation.*; +import org.apache.juneau.microservice.*; +import org.apache.juneau.parser.*; +import org.apache.juneau.serializer.*; +import org.apache.juneau.server.*; +import org.apache.juneau.server.annotation.*; + +/** + * Sample resource that allows images to be uploaded and retrieved. + */ +@RestResource( + path="/photos", + messages="nls/PhotosResource", + properties={ + @Property(name=HTMLDOC_title, value="Photo REST service"), + @Property(name=HTMLDOC_description, value="Use a tool like Poster to upload and retrieve jpeg and png images."), + @Property(name=HTMLDOC_links, value="{up:'$R{requestParentURI}',options:'$R{servletURI}?method=OPTIONS',source:'$R{servletParentURI}/source?classes=(org.apache.juneau.server.samples.PhotosResource)'}"), + // Resolve all relative URIs so that they're relative to this servlet! + @Property(name=SERIALIZER_relativeUriBase, value="$R{servletURI}"), + } +) +public class PhotosResource extends Resource { + private static final long serialVersionUID = 1L; + + // Our cache of photos + private Map<Integer,Photo> photos = new TreeMap<Integer,Photo>(); + + @Override /* Servlet */ + public void init() { + try { + // Preload an image. + InputStream is = getClass().getResourceAsStream("averycutedog.jpg"); + BufferedImage image = ImageIO.read(is); + Photo photo = new Photo(0, image); + photos.put(photo.id, photo); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + /** Our bean class for storing photos */ + public static class Photo { + int id; + BufferedImage image; + + Photo(int id, BufferedImage image) { + this.id = id; + this.image = image; + } + + public URI getURI() throws URISyntaxException { + return new URI(""+id); + } + } + + /** GET request handler for list of all photos */ + @RestMethod(name="GET", path="/") + public Collection<Photo> getAllPhotos() throws Exception { + return photos.values(); + } + + /** GET request handler for single photo */ + @RestMethod(name="GET", path="/{id}", serializers=ImageSerializer.class) + public BufferedImage getPhoto(@Attr int id) throws Exception { + Photo p = photos.get(id); + if (p == null) + throw new RestException(SC_NOT_FOUND, "Photo not found"); + return p.image; + } + + /** PUT request handler */ + @RestMethod(name="PUT", path="/{id}", parsers=ImageParser.class) + public String addPhoto(@Attr int id, @Content BufferedImage image) throws Exception { + photos.put(id, new Photo(id, image)); + return "OK"; + } + + /** POST request handler */ + @RestMethod(name="POST", path="/", parsers=ImageParser.class) + public Photo setPhoto(@Content BufferedImage image) throws Exception { + int id = photos.size(); + Photo p = new Photo(id, image); + photos.put(id, p); + return p; + } + + /** DELETE request handler */ + @RestMethod(name="DELETE", path="/{id}") + public String deletePhoto(@Attr int id) throws Exception { + Photo p = photos.remove(id); + if (p == null) + throw new RestException(SC_NOT_FOUND, "Photo not found"); + return "OK"; + } + + /** Serializer for converting images to byte streams */ + @Produces({"image/png","image/jpeg"}) + public static class ImageSerializer extends OutputStreamSerializer { + @Override /* Serializer */ + protected void doSerialize(SerializerSession session, Object o) throws Exception { + RenderedImage image = (RenderedImage)o; + String mediaType = session.getProperties().getString("mediaType"); + ImageIO.write(image, mediaType.substring(mediaType.indexOf('/')+1), session.getOutputStream()); + } + } + + /** Parser for converting byte streams to images */ + @Consumes({"image/png","image/jpeg"}) + public static class ImageParser extends InputStreamParser { + @Override /* Parser */ + @SuppressWarnings("unchecked") + protected <T> T doParse(ParserSession session, ClassMeta<T> type) throws Exception { + return (T)ImageIO.read(session.getInputStream()); + } + } +} http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/244cc21a/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/RequestEchoResource.java ---------------------------------------------------------------------- diff --git a/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/RequestEchoResource.java b/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/RequestEchoResource.java new file mode 100755 index 0000000..c940ed1 --- /dev/null +++ b/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/RequestEchoResource.java @@ -0,0 +1,58 @@ +/*************************************************************************************************************************** + * 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.juneau.server.samples; + +import static org.apache.juneau.html.HtmlDocSerializerContext.*; + +import javax.servlet.*; +import javax.servlet.http.*; + +import org.apache.juneau.*; +import org.apache.juneau.microservice.*; +import org.apache.juneau.server.*; +import org.apache.juneau.server.annotation.*; +import org.apache.juneau.server.converters.*; +import org.apache.juneau.transforms.*; + +/** + * Sample REST resource for echoing HttpServletRequests back to the browser. + */ +@RestResource( + path="/echo", + messages="nls/RequestEchoResource", + properties={ + @Property(name=SERIALIZER_maxDepth, value="5"), + @Property(name=SERIALIZER_detectRecursions, value="true"), + @Property(name=HTMLDOC_links, value="{up:'$R{requestParentURI}',options:'?method=OPTIONS',source:'$R{servletParentURI}/source?classes=(org.apache.juneau.server.samples.RequestEchoResource)'}") + }, + transforms={ + // Interpret these as their parent classes, not subclasses + HttpServletRequest.class, HttpSession.class, ServletContext.class, + // Add a special filter for Enumerations + EnumerationTransform.class + } +) +public class RequestEchoResource extends Resource { + private static final long serialVersionUID = 1L; + + /** GET request handler */ + @RestMethod(name="GET", path="/*", converters={Traversable.class,Queryable.class}) + public HttpServletRequest doGet(RestRequest req, @Properties ObjectMap properties) { + // Set the HtmlDocSerializer title programmatically. + // This sets the value for this request only. + properties.put(HTMLDOC_title, "Contents of HttpServletRequest object"); + + // Just echo the request back as the response. + return req; + } +} http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/244cc21a/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/RootResources.java ---------------------------------------------------------------------- diff --git a/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/RootResources.java b/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/RootResources.java new file mode 100755 index 0000000..9de8bf2 --- /dev/null +++ b/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/RootResources.java @@ -0,0 +1,54 @@ +/*************************************************************************************************************************** + * 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.juneau.server.samples; + +import static org.apache.juneau.html.HtmlDocSerializerContext.*; + +import org.apache.juneau.microservice.*; +import org.apache.juneau.microservice.resources.*; +import org.apache.juneau.server.annotation.*; +import org.apache.juneau.server.samples.addressbook.*; + +/** + * Sample REST resource showing how to implement a "router" resource page. + */ +@RestResource( + path="/", + messages="nls/RootResources", + properties={ + @Property(name=HTMLDOC_links, value="{options:'$R{servletURI}?method=OPTIONS',source:'$R{servletURI}/source?classes=(org.apache.juneau.server.samples.RootResources)'}") + }, + children={ + HelloWorldResource.class, + MethodExampleResource.class, + RequestEchoResource.class, + TempDirResource.class, + AddressBookResource.class, + SampleRemoteableServlet.class, + PhotosResource.class, + AtomFeedResource.class, + JsonSchemaResource.class, + SqlQueryResource.class, + TumblrParserResource.class, + CodeFormatterResource.class, + UrlEncodedFormResource.class, + SourceResource.class, + ConfigResource.class, + LogsResource.class, + DockerRegistryResource.class, + ShutdownResource.class + } +) +public class RootResources extends ResourceGroup { + private static final long serialVersionUID = 1L; +} http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/244cc21a/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/SampleRemoteableServlet.java ---------------------------------------------------------------------- diff --git a/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/SampleRemoteableServlet.java b/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/SampleRemoteableServlet.java new file mode 100755 index 0000000..2f62f11 --- /dev/null +++ b/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/SampleRemoteableServlet.java @@ -0,0 +1,57 @@ +/*************************************************************************************************************************** + * 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.juneau.server.samples; + +import static org.apache.juneau.html.HtmlDocSerializerContext.*; +import static org.apache.juneau.server.RestServletContext.*; + +import java.util.*; + +import org.apache.juneau.samples.addressbook.*; +import org.apache.juneau.server.annotation.*; +import org.apache.juneau.server.remoteable.*; + +/** + * Class showing the functionality of the RemoteableServlet class. + * + * @author James Bognar ([email protected]) + */ +@SuppressWarnings("serial") +@RestResource( + path="/remoteable", + messages="nls/SampleRemoteableServlet", + properties={ + @Property(name=HTMLDOC_title, value="Remoteable Service Proxy API"), + @Property(name=HTMLDOC_description, value="Sample class showing how to use remoteable proxies. The list below are exposed services that can be retrieved using RestClient.getProxyInterface(Class)."), + @Property(name=HTMLDOC_links, value="{up:'$R{requestParentURI}',options:'$R{servletURI}?method=OPTIONS',source:'$R{servletParentURI}/source?classes=(org.apache.juneau.server.samples.SampleRemoteableServlet)'}"), + // Allow us to use method=POST from a browser. + @Property(name=REST_allowMethodParam, value="*") + }, + stylesheet="styles/devops.css" +) +public class SampleRemoteableServlet extends RemoteableServlet { + + AddressBook addressBook = new AddressBook(); + + @Override /* RemoteableServlet */ + protected Map<Class<?>,Object> getServiceMap() throws Exception { + Map<Class<?>,Object> m = new LinkedHashMap<Class<?>,Object>(); + + // In this simplified example, we expose the same POJO service under two different interfaces. + // One is IAddressBook which only exposes methods defined on that interface, and + // the other is AddressBook itself which exposes all methods defined on the class itself. + m.put(IAddressBook.class, addressBook); + m.put(AddressBook.class, addressBook); + return m; + } +} http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/244cc21a/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/SourceResource.java ---------------------------------------------------------------------- diff --git a/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/SourceResource.java b/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/SourceResource.java new file mode 100755 index 0000000..2ea08aa --- /dev/null +++ b/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/SourceResource.java @@ -0,0 +1,114 @@ +/*************************************************************************************************************************** + * 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.juneau.server.samples; + +import static org.apache.juneau.html.HtmlDocSerializerContext.*; + +import java.io.*; +import java.util.*; + +import org.apache.juneau.html.annotation.*; +import org.apache.juneau.internal.*; +import org.apache.juneau.microservice.*; +import org.apache.juneau.server.annotation.*; + +/** + * Servlet for viewing source code on classes whose Java files are present on the classpath. + * <p> + * This class is by no means perfect but is pretty much the best you can get using only regular expression matching. + * + * @author James Bognar ([email protected]) + */ +@SuppressWarnings("serial") +@RestResource( + path="/source", + messages="nls/SourceResource", + properties={ + @Property(name=HTMLDOC_title, value="Source code viewer"), + @Property(name=HTMLDOC_cssImports, value="$R{servletURI}/htdocs/code-highlighting.css"), + @Property(name=HTMLDOC_links, value="{up:'$R{requestParentURI}',options:'$R{servletURI}?method=OPTIONS',source:'$R{servletParentURI}/source?classes=(org.apache.juneau.server.samples.SourceResource)'}"), + } +) +public class SourceResource extends Resource { + + /** View source on the specified classes. */ + @RestMethod(name="GET", path="/") + public Object getSource(@Param("classes") String[] classes) throws Exception { + if (classes == null) + return "Specify classes using ?classes=(class1,class2,....) attribute"; + List<Object> l = new LinkedList<Object>(); + for (String c : classes) { + try { + l.add(new Source(Class.forName(c))); + } catch (ClassNotFoundException e) { + l.add("Class " + c + " not found"); + } catch (Exception e) { + l.add(e.getLocalizedMessage()); + } + } + return l; + } + + /** + * POJO that allows us to serialize HTML directly to the output. + */ + @Html(asPlainText=true) + public static class Source { + private Class<?> c; + private Source(Class<?> c) { + this.c = c; + } + @Override /* Object */ + public String toString() { + String filename = c.getSimpleName() + ".java"; + InputStream is = c.getResourceAsStream('/' + c.getPackage().getName().replace('.','/') + '/' + filename); + if (is == null) + return "Source for class " + c.getName() + " not found"; + StringBuilder sb = new StringBuilder(); + try { + sb.append("<h3>").append(c.getSimpleName()).append(".java").append("</h3>"); + sb.append("<p class='bcode'>"); + sb.append(highlight(IOUtils.read(is), "java")); + sb.append("</p>"); + } catch (Exception e) { + return e.getLocalizedMessage(); + } + return sb.toString(); + } + } + + public static String highlight(String code, String lang) throws Exception { + if (lang.equalsIgnoreCase("xml")) { + code = code.replaceAll("&", "&"); + code = code.replaceAll("<", "<"); + code = code.replaceAll(">", ">"); + code = code.replaceAll("(<[^\\s&]+>)", "<xt>$1</xt>"); + code = code.replaceAll("(<[^\\s&]+)(\\s)", "<xt>$1</xt>$2"); + code = code.replaceAll("(['\"])(/?>)", "$1<xt>$2</xt>"); + code = code.replaceAll("([\\S]+)=", "<xa>$1</xa>="); + code = code.replaceAll("=(['\"][^'\"]+['\"])", "=<xs>$1</xs>"); + } else if (lang.equalsIgnoreCase("java")) { + code = code.replaceAll("&", "&"); + code = code.replaceAll("<", "<"); + code = code.replaceAll(">", ">"); + code = code.replaceAll("(?s)(\\/\\*\\*.*?\\*\\/)", "<jd>$1</jd>"); // javadoc comments + code = code.replaceAll("(@\\w+)", "<ja>$1</ja>"); // annotations + code = code.replaceAll("(?s)(?!\\/)(\\/\\*.*?\\*\\/)", "<jc>$1</jc>"); // C style comments + code = code.replaceAll("(?m)(\\/\\/.*)", "<jc>$1</jc>"); // C++ style comments + code = code.replaceAll("(?m)('[^'\n]*'|\"[^\"\n]*\")", "<js>$1</js>"); // quotes + code = code.replaceAll("(?<!@)(import|package|boolean|byte|char|double|float|final|static|transient|synchronized|private|protected|public|int|long|short|abstract|class|interface|extends|implements|null|true|false|void|break|case|catch|continue|default|do|else|finally|for|goto|if|instanceof|native|new|return|super|switch|this|threadsafe|throws|throw|try|while)(?=\\W)", "<jk>$1</jk>"); // quotes + code = code.replaceAll("<\\/jk>(\\s+)<jk>", "$1"); // quotes + } + return code; + } +} http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/244cc21a/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/SqlQueryResource.html ---------------------------------------------------------------------- diff --git a/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/SqlQueryResource.html b/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/SqlQueryResource.html new file mode 100755 index 0000000..4235d94 --- /dev/null +++ b/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/SqlQueryResource.html @@ -0,0 +1,51 @@ +<!DOCTYPE HTML> +<html> +<head> + <style type='text/css'> + @import '$R{servletURI}/style.css'; + </style> + <script> + // Quick and dirty function to allow tabs in textarea. + function checkTab(e) { + if (e.keyCode == 9) { + var t = e.target; + var ss = t.selectionStart, se = t.selectionEnd; + t.value = t.value.slice(0,ss).concat('\t').concat(t.value.slice(ss,t.value.length)); + e.preventDefault(); + } + } + // Load results from IFrame into this document. + function loadResults(b) { + var doc = b.contentDocument || b.contentWindow.document; + var data = doc.getElementById('data') || doc.getElementsByTagName('body')[0]; + document.getElementById('results').innerHTML = data.innerHTML; + } + </script> +</head> +<body> + <h3 class='title'>SQL Query API</h3> + <div class='data'> + <form action='sqlQuery' method='POST' target='buf'> + <table> + <tr> + <th>Position (1-10000):</th> + <td><input name='pos' type='number' value='1'></td> + <th>Limit (1-10000):</th> + <td><input name='limit' type='number' value='100'></td> + <td><button type='submit'>Submit</button><button type='reset'>Reset</button></td> + </tr> + <tr> + <td colspan="5"> + <textarea name='sql' style='width:100%;height:200px;font-family:Courier;font-size:9pt;' onkeydown='checkTab(event)'></textarea> + </td> + </tr> + </table> + </form> + <br> + <div id='results'> + </div> + </div> + <iframe name='buf' style='display:none' onload="parent.loadResults(this)"></iframe> +</body> +</html> + http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/244cc21a/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/SqlQueryResource.java ---------------------------------------------------------------------- diff --git a/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/SqlQueryResource.java b/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/SqlQueryResource.java new file mode 100755 index 0000000..586a233 --- /dev/null +++ b/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/SqlQueryResource.java @@ -0,0 +1,128 @@ +/*************************************************************************************************************************** + * 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.juneau.server.samples; + +import static javax.servlet.http.HttpServletResponse.*; +import static org.apache.juneau.html.HtmlDocSerializerContext.*; + +import java.io.*; +import java.sql.*; +import java.util.*; + +import org.apache.juneau.dto.*; +import org.apache.juneau.ini.*; +import org.apache.juneau.internal.*; +import org.apache.juneau.microservice.*; +import org.apache.juneau.server.*; +import org.apache.juneau.server.annotation.*; + +/** + * Sample resource that shows how Juneau can serialize ResultSets. + */ +@RestResource( + path="/sqlQuery", + messages="nls/SqlQueryResource", + properties={ + @Property(name=HTMLDOC_title, value="SQL query service"), + @Property(name=HTMLDOC_description, value="Executes queries against the local derby '$C{SqlQueryResource/connectionUrl}' database"), + @Property(name=HTMLDOC_links, value="{up:'$R{requestParentURI}',options:'$R{servletURI}?method=OPTIONS',source:'$R{servletParentURI}/source?classes=(org.apache.juneau.server.samples.SqlQueryResource)'}"), + } +) +public class SqlQueryResource extends Resource { + private static final long serialVersionUID = 1L; + + private ConfigFile cf = getConfig(); + + private String driver = cf.getString("SqlQueryResource/driver"); + private String connectionUrl = cf.getString("SqlQueryResource/connectionUrl"); + private boolean + allowUpdates = cf.getBoolean("SqlQueryResource/allowUpdates", false), + allowTempUpdates = cf.getBoolean("SqlQueryResource/allowTempUpdates", false), + includeRowNums = cf.getBoolean("SqlQueryResource/includeRowNums", false); + + @Override /* Servlet */ + public void init() { + try { + Class.forName(driver).newInstance(); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + /** GET request handler - Display the query entry page. */ + @RestMethod(name="GET", path="/") + public ReaderResource doGet(RestRequest req) throws IOException { + return req.getReaderResource("SqlQueryResource.html", true); + } + + /** POST request handler - Execute the query. */ + @RestMethod(name="POST", path="/") + public List<Object> doPost(@Content PostInput in) throws Exception { + + List<Object> results = new LinkedList<Object>(); + + // Don't try to submit empty input. + if (StringUtils.isEmpty(in.sql)) + return results; + + if (in.pos < 1 || in.pos > 10000) + throw new RestException(SC_BAD_REQUEST, "Invalid value for position. Must be between 1-10000"); + if (in.limit < 1 || in.limit > 10000) + throw new RestException(SC_BAD_REQUEST, "Invalid value for limit. Must be between 1-10000"); + + // Create a connection and statement. + // If these fais, let the exception filter up as a 500 error. + Connection c = DriverManager.getConnection(connectionUrl); + c.setAutoCommit(false); + Statement st = c.createStatement(); + String sql = null; + + try { + for (String s : in.sql.split(";")) { + sql = s.trim(); + if (! sql.isEmpty()) { + Object o = null; + if (allowUpdates || (allowTempUpdates && ! sql.matches("(?:i)commit.*"))) { + if (st.execute(sql)) { + ResultSet rs = st.getResultSet(); + o = new ResultSetList(rs, in.pos, in.limit, includeRowNums); + } else { + o = st.getUpdateCount(); + } + } else { + ResultSet rs = st.executeQuery(sql); + o = new ResultSetList(rs, in.pos, in.limit, includeRowNums); + } + results.add(o); + } + } + if (allowUpdates) + c.commit(); + else if (allowTempUpdates) + c.rollback(); + } catch (SQLException e) { + c.rollback(); + throw new RestException(SC_BAD_REQUEST, "Invalid query: {0}", sql).initCause(e); + } finally { + c.close(); + } + + return results; + } + + /** The parsed form post */ + public static class PostInput { + public String sql; + public int pos = 1, limit = 100; + } +} http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/244cc21a/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/TempDirResource.java ---------------------------------------------------------------------- diff --git a/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/TempDirResource.java b/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/TempDirResource.java new file mode 100755 index 0000000..fc99d0b --- /dev/null +++ b/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/TempDirResource.java @@ -0,0 +1,77 @@ +/*************************************************************************************************************************** + * 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.juneau.server.samples; + +import static org.apache.juneau.html.HtmlDocSerializerContext.*; + +import java.io.*; + +import org.apache.commons.fileupload.*; +import org.apache.commons.fileupload.servlet.*; +import org.apache.juneau.server.*; +import org.apache.juneau.server.annotation.*; +import org.apache.juneau.utils.*; + +/** + * Sample resource that extends {@link DirectoryResource} to open up the temp directory as a REST resource. + */ +@RestResource( + path="/tempDir", + messages="nls/TempDirResource", + properties={ + @Property(name="rootDir", value="$S{java.io.tmpdir}"), + @Property(name="allowViews", value="true"), + @Property(name="allowDeletes", value="true"), + @Property(name="allowPuts", value="false"), + @Property(name=HTMLDOC_links, value="{up:'$R{requestParentURI}',options:'$R{servletURI}?method=OPTIONS',upload:'upload',source:'$R{servletParentURI}/source?classes=(org.apache.juneau.server.samples.TempDirResource,org.apache.juneau.server.samples.DirectoryResource)'}"), + }, + stylesheet="styles/devops.css" +) +public class TempDirResource extends DirectoryResource { + private static final long serialVersionUID = 1L; + + /** + * [GET /upload] - Display the form entry page for uploading a file to the temp directory. + */ + @RestMethod(name="GET", path="/upload") + public ReaderResource getUploadPage(RestRequest req) throws IOException { + return req.getReaderResource("TempDirUploadPage.html", true); + } + + /** + * [POST /upload] - Upload a file as a multipart form post. + * Shows how to use the Apache Commons ServletFileUpload class for handling multi-part form posts. + */ + @RestMethod(name="POST", path="/upload", matchers=TempDirResource.MultipartFormDataMatcher.class) + public Redirect uploadFile(RestRequest req) throws Exception { + ServletFileUpload upload = new ServletFileUpload(); + FileItemIterator iter = upload.getItemIterator(req); + while (iter.hasNext()) { + FileItemStream item = iter.next(); + if (item.getFieldName().equals("contents")) { //$NON-NLS-1$ + File f = new File(getRootDir(), item.getName()); + IOPipe.create(item.openStream(), new FileOutputStream(f)).closeOut().run(); + } + } + return new Redirect(); // Redirect to the servlet root. + } + + /** Causes a 404 if POST isn't multipart/form-data */ + public static class MultipartFormDataMatcher extends RestMatcher { + @Override /* RestMatcher */ + public boolean matches(RestRequest req) { + String contentType = req.getContentType(); + return contentType != null && contentType.startsWith("multipart/form-data"); //$NON-NLS-1$ + } + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/244cc21a/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/TempDirUploadPage.html ---------------------------------------------------------------------- diff --git a/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/TempDirUploadPage.html b/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/TempDirUploadPage.html new file mode 100755 index 0000000..6410bdf --- /dev/null +++ b/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/TempDirUploadPage.html @@ -0,0 +1,34 @@ +<!DOCTYPE HTML> +<!-- +/*************************************************************************************************************************** + * 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. + * + ***************************************************************************************************************************/ + --> +<html> +<head> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> + <style type='text/css'> + @import '$R{servletURI}/style.css'; + </style> +</head> +<body> + <h3 class='title'>$R{servletLabel}</h3> + <h5 class="description">$R{servletDescription}</h5> + <div class='data'> + <form id='form' action='$R{servletURI}/upload' method='POST' target='buff' enctype="multipart/form-data"> + <input name="contents" type="file"><button type="submit">Submit</button> + </form> + </div> +</body> +</html> + http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/244cc21a/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/TumblrParserResource.java ---------------------------------------------------------------------- diff --git a/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/TumblrParserResource.java b/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/TumblrParserResource.java new file mode 100755 index 0000000..414a164 --- /dev/null +++ b/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/TumblrParserResource.java @@ -0,0 +1,87 @@ +/*************************************************************************************************************************** + * 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.juneau.server.samples; + +import static org.apache.juneau.html.HtmlDocSerializerContext.*; + +import java.lang.Object; + +import org.apache.juneau.*; +import org.apache.juneau.client.*; +import org.apache.juneau.dto.Link; +import org.apache.juneau.html.dto.*; +import org.apache.juneau.json.*; +import org.apache.juneau.microservice.*; +import org.apache.juneau.server.annotation.*; + +@RestResource( + path="/tumblrParser", + messages="nls/TumblrParserResource", + properties={ + @Property(name=HTMLDOC_links, value="{up:'$R{requestParentURI}',options:'?method=OPTIONS',source:'$R{servletParentURI}/source?classes=(org.apache.juneau.server.samples.TumblrParserResource)'}"), + @Property(name=HTMLDOC_title, value="Tumblr parser service"), + @Property(name=HTMLDOC_description, value="Specify a URL to a Tumblr blog and parse the results.") + } +) +public class TumblrParserResource extends Resource { + private static final long serialVersionUID = 1L; + + @RestMethod(name="GET", path="/") + public String getInstructions() throws Exception { + return "Append the Tumblr blog name to the URL above (e.g. /juneau/sample/tumblrParser/mytumblrblog)"; + } + + @RestMethod(name="GET", path="/{blogName}") + public ObjectList parseBlog(@Attr String blogName) throws Exception { + ObjectList l = new ObjectList(); + RestClient rc = new RestClient(JsonSerializer.class, JsonParser.class); + try { + String site = "http://" + blogName + ".tumblr.com/api/read/json"; + ObjectMap m = rc.doGet(site).getResponse(ObjectMap.class); + int postsTotal = m.getInt("posts-total"); + for (int i = 0; i < postsTotal; i += 20) { + m = rc.doGet(site + "?start=" + i + "&num=20&filter=text").getResponse(ObjectMap.class); + ObjectList ol = m.getObjectList("posts"); + for (int j = 0; j < ol.size(); j++) { + ObjectMap om = ol.getObjectMap(j); + String type = om.getString("type"); + Entry e = new Entry(); + e.date = om.getString("date"); + if (type.equals("link")) + e.entry = new Link(om.getString("link-text"), om.getString("link-url")); + else if (type.equals("audio")) + e.entry = new ObjectMap().append("type","audio").append("audio-caption", om.getString("audio-caption")); + else if (type.equals("video")) + e.entry = new ObjectMap().append("type","video").append("video-caption", om.getString("video-caption")); + else if (type.equals("quote")) + e.entry = new ObjectMap().append("type","quote").append("quote-source", om.getString("quote-source")).append("quote-text", om.getString("quote-text")); + else if (type.equals("regular")) + e.entry = om.getString("regular-body"); + else if (type.equals("photo")) + e.entry = new Img(om.getString("photo-url-250")); + else + e.entry = new ObjectMap().append("type", type); + l.add(e); + } + } + } finally { + rc.closeQuietly(); + } + return l; + } + + public static class Entry { + public String date; + public Object entry; + } +} http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/244cc21a/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/UrlEncodedForm.html ---------------------------------------------------------------------- diff --git a/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/UrlEncodedForm.html b/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/UrlEncodedForm.html new file mode 100755 index 0000000..c530764 --- /dev/null +++ b/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/UrlEncodedForm.html @@ -0,0 +1,62 @@ +<!DOCTYPE HTML> +<!-- +/*************************************************************************************************************************** + * 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. + * + ***************************************************************************************************************************/ + --> +<html> +<head> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> + <style type='text/css'> + @import '$R{servletURI}/style.css'; + </style> + <script type="text/javascript"> + // Load results from IFrame into this document. + function loadResults(buff) { + var doc = buff.contentDocument || buff.contentWindow.document; + var buffBody = doc.getElementById('data'); + document.getElementById('results').innerHTML = buffBody.innerHTML; + } + </script> +</head> +<body> + <h3 class='title'>$R{servletLabel}</h3> + <h5 class="description">$R{servletDescription}</h5> + <div class='data'> + <form id='form' action='$R{servletURI}' method='POST' target='buff'> + <table> + <tr> + <th>$L{aString}</th> + <td><input name="aString" type="text"></td> + </tr> + <tr> + <th>$L{aNumber}</th> + <td><input name="aNumber" type="number"></td> + </tr> + <tr> + <th>$L{aDate}</th> + <td><input name="aDate" type="datetime"> (ISO8601, e.g. "<code>2001-07-04T15:30:45Z</code>")</td> + </tr> + <tr> + <td colspan='2' align='right'><button type="submit">$L{submit}</button></td> + </tr> + </table> + </form> + <br> + <div id='results'> + </div> + </div> + <iframe name='buff' style='display:none' onload="parent.loadResults(this)"></iframe> +</body> +</html> + http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/244cc21a/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/UrlEncodedFormResource.java ---------------------------------------------------------------------- diff --git a/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/UrlEncodedFormResource.java b/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/UrlEncodedFormResource.java new file mode 100755 index 0000000..e30cb7a --- /dev/null +++ b/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/UrlEncodedFormResource.java @@ -0,0 +1,53 @@ +/*************************************************************************************************************************** + * 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.juneau.server.samples; + +import java.io.*; +import java.util.*; + +import org.apache.juneau.annotation.*; +import org.apache.juneau.microservice.*; +import org.apache.juneau.server.*; +import org.apache.juneau.server.annotation.*; +import org.apache.juneau.transforms.*; + +/** + * Sample REST resource for loading URL-Encoded form posts into POJOs. + */ +@RestResource( + path="/urlEncodedForm", + messages="nls/UrlEncodedFormResource" +) +public class UrlEncodedFormResource extends Resource { + private static final long serialVersionUID = 1L; + + /** GET request handler */ + @RestMethod(name="GET", path="/") + public ReaderResource doGet(RestRequest req) throws IOException { + return req.getReaderResource("UrlEncodedForm.html", true); + } + + /** POST request handler */ + @RestMethod(name="POST", path="/") + public Object doPost(@Content FormInputBean input) throws Exception { + // Just mirror back the request + return input; + } + + public static class FormInputBean { + public String aString; + public int aNumber; + @BeanProperty(transform=CalendarTransform.ISO8601DT.class) + public Calendar aDate; + } +}
