http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/e3d95284/juneau-distrib/pom.xml ---------------------------------------------------------------------- diff --git a/juneau-distrib/pom.xml b/juneau-distrib/pom.xml index a757f9f..ab3b3b6 100644 --- a/juneau-distrib/pom.xml +++ b/juneau-distrib/pom.xml @@ -112,7 +112,7 @@ <artifactItem> <outputDirectory>${project.build.directory}/src</outputDirectory> <groupId>org.apache.juneau</groupId> - <artifactId>juneau-samples</artifactId> + <artifactId>juneau-examples-rest</artifactId> <version>${project.version}</version> <type>jar</type> <classifier>sources</classifier>
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/e3d95284/juneau-examples-rest/.gitignore ---------------------------------------------------------------------- diff --git a/juneau-examples-rest/.gitignore b/juneau-examples-rest/.gitignore new file mode 100644 index 0000000..8ca27ce --- /dev/null +++ b/juneau-examples-rest/.gitignore @@ -0,0 +1,6 @@ +/logs/ +/.DS_Store +/derby.log +/target/ +/.settings/ +/.classpath http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/e3d95284/juneau-examples-rest/.project ---------------------------------------------------------------------- diff --git a/juneau-examples-rest/.project b/juneau-examples-rest/.project new file mode 100644 index 0000000..0db3537 --- /dev/null +++ b/juneau-examples-rest/.project @@ -0,0 +1,33 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + *************************************************************************************************************************** + * 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. * + *************************************************************************************************************************** +--> +<projectDescription> + <name>juneau-examples-rest</name> + <comment>Sample code packaged as a microservice. NO_M2ECLIPSE_SUPPORT: Project files created with the maven-eclipse-plugin are not supported in M2Eclipse.</comment> + <projects> + <project>juneau-microservice</project> + <project>juneau-rest</project> + <project>juneau-core</project> + <project>juneau-rest-client</project> + </projects> + <buildSpec> + <buildCommand> + <name>org.eclipse.jdt.core.javabuilder</name> + </buildCommand> + </buildSpec> + <natures> + <nature>org.eclipse.jdt.core.javanature</nature> + </natures> +</projectDescription> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/e3d95284/juneau-examples-rest/examples.cfg ---------------------------------------------------------------------- diff --git a/juneau-examples-rest/examples.cfg b/juneau-examples-rest/examples.cfg new file mode 100755 index 0000000..fd89bfa --- /dev/null +++ b/juneau-examples-rest/examples.cfg @@ -0,0 +1,145 @@ +# *************************************************************************************************************************** +# * 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. * +# *************************************************************************************************************************** + +#================================================================================ +# Basic configuration file for SaaS microservices +# Subprojects can use this as a starting point. +#================================================================================ + +#================================================================================ +# REST settings +#================================================================================ +[REST] + +resources = org.apache.juneau.examples.rest.RootResources + +port = 10000 + +# Authentication: NONE, BASIC. +authType = NONE + +# The BASIC auth username, password, and realm +loginUser = +loginPassword = +authRealm = + +# Stylesheet to use for HTML views. +# The default options are: +# - styles/juneau.css +# - styles/devops.css +# Other stylesheets can be referenced relative to the servlet package or working +# directory. +stylesheet = styles/devops.css + +# What to do when the config file is saved. +# Possible values: +# NOTHING - Don't do anything. +# RESTART_SERVER - Restart the Jetty server. +# RESTART_SERVICE - Shutdown and exit with code '3'. +saveConfigAction = RESTART_SERVER + +# Enable SSL support. +useSsl = false + +#================================================================================ +# Bean properties on the org.eclipse.jetty.util.ssl.SslSocketFactory class +#-------------------------------------------------------------------------------- +# Ignored if REST/useSsl is false. +# Specify any of the following fields: +# allowRenegotiate (boolean) +# certAlias (String) +# crlPath (String) +# enableCRLDP (boolean) +# enableOCSP (boolean) +# excludeCipherSuites (String[]) +# excludeProtocols (String[]) +# includeCipherSuites (String[]) +# includeProtocols (String...) +# keyManagerPassword (String) +# keyStore (String) +# keyStorePassword (String) +# keyStorePath (String) +# keyStoreProvider (String) +# keyStoreType (String) +# maxCertPathLength (int) +# needClientAuth (boolean) +# ocspResponderURL (String) +# protocol (String) +# provider (String) +# secureRandomAlgorithm (String) +# sessionCachingEnabled (boolean) +# sslKeyManagerFactoryAlgorithm (String) +# sslSessionCacheSize (int) +# sslSessionTimeout (int) +# trustAll (boolean) +# trustManagerFactoryAlgorithm (String) +# trustStore (String) +# trustStorePassword (String) +# trustStoreProvider (String) +# trustStoreType (String) +# validateCerts (boolean) +# validatePeerCerts (boolean) +# wantClientAuth (boolean) +#================================================================================ +[REST-SslContextFactory] +keyStorePath = client_keystore.jks +keyStorePassword* = {HRAaRQoT} +excludeCipherSuites = TLS_DHE.*, TLS_EDH.* +excludeProtocols = SSLv3 +allowRenegotiate = false + +#================================================================================ +# Logger settings +# See FileHandler Java class for details. +#================================================================================ +[Logging] +logDir = logs +logFile = sample.%g.log +dateFormat = yyyy.MM.dd hh:mm:ss +format = [{date} {level}] {msg}%n +append = false +limit = 10M +count = 5 +levels = { org.apache.juneau:'INFO' } +useStackTraceHashes = true +consoleLevel = WARNING + +#================================================================================ +# System properties +#-------------------------------------------------------------------------------- +# These are arbitrary system properties that can be set during startup. +#================================================================================ +[SystemProperties] + +# Configure Jetty for StdErrLog Logging +org.eclipse.jetty.util.log.class = org.eclipse.jetty.util.log.StrErrLog + +# Jetty logging level +org.eclipse.jetty.LEVEL = WARN + +#================================================================================ +# DockerRegistryResource properties +#================================================================================ +[DockerRegistry] +url = http://docker.apache.org:5000/v1 + +#================================================================================ +# SqlQueryResource properties +#================================================================================ +[SqlQueryResource] +driver = org.apache.derby.jdbc.EmbeddedDriver +connectionUrl = jdbc:derby:C:/testDB;create=true +allowTempUpdates = true +includeRowNums = true + + http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/e3d95284/juneau-examples-rest/pom.xml ---------------------------------------------------------------------- diff --git a/juneau-examples-rest/pom.xml b/juneau-examples-rest/pom.xml new file mode 100644 index 0000000..b8114b6 --- /dev/null +++ b/juneau-examples-rest/pom.xml @@ -0,0 +1,152 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + *************************************************************************************************************************** + * 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. * + *************************************************************************************************************************** +--> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + + <modelVersion>4.0.0</modelVersion> + <artifactId>juneau-examples-rest</artifactId> + <name>Apache Juneau REST Examples</name> + <description>Sample code packaged as a microservice.</description> + + <parent> + <groupId>org.apache.juneau</groupId> + <artifactId>juneau</artifactId> + <version>6.0.2-incubating-SNAPSHOT</version> + <relativePath>../pom.xml</relativePath> + </parent> + + <properties> + <encoding>UTF-8</encoding> + <maven.javadoc.skip>true</maven.javadoc.skip> + </properties> + + <dependencies> + <dependency> + <groupId>org.apache.juneau</groupId> + <artifactId>juneau-microservice</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.apache.jena</groupId> + <artifactId>jena-core</artifactId> + </dependency> + <dependency> + <groupId>org.apache.derby</groupId> + <artifactId>derby</artifactId> + </dependency> + <dependency> + <groupId>org.apache.httpcomponents</groupId> + <artifactId>httpmime</artifactId> + </dependency> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + </dependency> + </dependencies> + + <build> + <plugins> + + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-source-plugin</artifactId> + <version>3.0.1</version> + <executions> + <execution> + <id>attach-sources</id> + <phase>verify</phase> + <goals> + <goal>jar-no-fork</goal> + </goals> + </execution> + </executions> + </plugin> + + <!-- + This runs the _TestSuite class. + You must run within the testsuite so the REST microservice is started for the tests. + --> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-surefire-plugin</artifactId> + <version>2.19.1</version> + <configuration> + <includes> + <include> + **/_TestSuite.java + </include> + </includes> + </configuration> + </plugin> + + <!-- + This packages the samples into an executable jar. + Use: java -jar juneau-examples-uber.jar + Needs the examples.cfg copied below in the same directory. + --> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-shade-plugin</artifactId> + <version>2.4.3</version> + <configuration> + <createDependencyReducedPom>false</createDependencyReducedPom> + <minimizeJar>false</minimizeJar> + <transformers> + <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> + <manifestEntries> + <Main-Class>org.apache.juneau.microservice.RestMicroservice</Main-Class> + <Rest-Resources>org.apache.juneau.examples.rest.RootResources</Rest-Resources> + <Main-ConfigFile>examples.cfg</Main-ConfigFile> + </manifestEntries> + </transformer> + </transformers> + </configuration> + <executions> + <execution> + <phase>package</phase> + <goals> + <goal>shade</goal> + </goals> + </execution> + </executions> + </plugin> + + <!-- Attaches the examples.cfg to this artifact --> + <plugin> + <groupId>org.codehaus.mojo</groupId> + <artifactId>build-helper-maven-plugin</artifactId> + <version>1.12</version> + <executions> + <execution> + <id>attach-artifacts</id> + <phase>package</phase> + <goals> + <goal>attach-artifact</goal> + </goals> + <configuration> + <artifacts> + <artifact> + <file>examples.cfg</file> + <type>cfg</type> + <classifier>samples</classifier> + </artifact> + </artifacts> + </configuration> + </execution> + </executions> + </plugin> + </plugins> + </build> +</project> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/e3d95284/juneau-examples-rest/src/main/java/org/apache/juneau/examples/addressbook/Address.java ---------------------------------------------------------------------- diff --git a/juneau-examples-rest/src/main/java/org/apache/juneau/examples/addressbook/Address.java b/juneau-examples-rest/src/main/java/org/apache/juneau/examples/addressbook/Address.java new file mode 100755 index 0000000..c7b3685 --- /dev/null +++ b/juneau-examples-rest/src/main/java/org/apache/juneau/examples/addressbook/Address.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.examples.addressbook; + +import java.net.URI; + +import org.apache.juneau.annotation.*; +import org.apache.juneau.jena.annotation.*; +import org.apache.juneau.xml.annotation.*; + +/** + * Address bean + */ +@Xml(prefix="addr") +@Rdf(prefix="addr") +@Bean(typeName="address") +public class Address { + + private static int nextAddressId = 1; + + // Bean properties + @Rdf(beanUri=true) public URI uri; + public URI personUri; + public int id; + @Xml(prefix="mail") @Rdf(prefix="mail") public String street, city, state; + @Xml(prefix="mail") @Rdf(prefix="mail") public int zip; + public boolean isCurrent; + + /** Bean constructor - Needed for instantiating on client side */ + public Address() {} + + /** Normal constructor - Needed for instantiating on server side */ + public Address(URI addressBookUri, URI personUri, CreateAddress ca) throws Exception { + this.id = nextAddressId++; + if (addressBookUri != null) + this.uri = addressBookUri.resolve("addresses/" + id); + this.personUri = personUri; + this.street = ca.street; + this.city = ca.city; + this.state = ca.state; + this.zip = ca.zip; + this.isCurrent = ca.isCurrent; + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/e3d95284/juneau-examples-rest/src/main/java/org/apache/juneau/examples/addressbook/AddressBook.java ---------------------------------------------------------------------- diff --git a/juneau-examples-rest/src/main/java/org/apache/juneau/examples/addressbook/AddressBook.java b/juneau-examples-rest/src/main/java/org/apache/juneau/examples/addressbook/AddressBook.java new file mode 100755 index 0000000..3064809 --- /dev/null +++ b/juneau-examples-rest/src/main/java/org/apache/juneau/examples/addressbook/AddressBook.java @@ -0,0 +1,102 @@ +// *************************************************************************************************************************** +// * 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.examples.addressbook; + +import java.net.URI; +import java.text.*; +import java.util.*; + +import org.apache.juneau.annotation.*; + +/** + * Address book bean + */ +@Bean(typeName="addressBook") +public class AddressBook extends LinkedList<Person> implements IAddressBook { + private static final long serialVersionUID = 1L; + + // The URL of this resource + private URI uri; + + /** Bean constructor - Needed for instantiating on server side */ + public AddressBook() {} + + /** Bean constructor - Needed for instantiating on client side */ + public AddressBook(URI uri) throws Exception { + this.uri = uri; + } + + @Override /* IAddressBook */ + public List<Person> getPeople() { + return this; + } + + @Override /* IAddressBook */ + public Person createPerson(CreatePerson cp) throws Exception { + Person p = new Person(uri, cp); + add(p); + return p; + } + + @Override /* IAddressBook */ + public Person findPerson(int id) { + for (Person p : this) + if (p.id == id) + return p; + return null; + } + + @Override /* IAddressBook */ + public Address findAddress(int id) { + for (Person p : this) + for (Address a : p.addresses) + if (a.id == id) + return a; + return null; + } + + @Override /* IAddressBook */ + public Person findPersonWithAddress(int id) { + for (Person p : this) + for (Address a : p.addresses) + if (a.id == id) + return p; + return null; + } + + @Override /* IAddressBook */ + public List<Address> getAddresses() { + Set<Address> s = new LinkedHashSet<Address>(); + for (Person p : this) + for (Address a : p.addresses) + s.add(a); + return new ArrayList<Address>(s); + } + + @Override /* IAddressBook */ + public Person removePerson(int id) { + Person p = findPerson(id); + if (p != null) + this.remove(p); + return p; + } + + /** Utility method */ + public static Calendar toCalendar(String birthDate) throws Exception { + Calendar c = new GregorianCalendar(); + c.setTime(DateFormat.getDateInstance(DateFormat.MEDIUM, Locale.US).parse(birthDate)); + return c; + } +} + + http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/e3d95284/juneau-examples-rest/src/main/java/org/apache/juneau/examples/addressbook/CreateAddress.java ---------------------------------------------------------------------- diff --git a/juneau-examples-rest/src/main/java/org/apache/juneau/examples/addressbook/CreateAddress.java b/juneau-examples-rest/src/main/java/org/apache/juneau/examples/addressbook/CreateAddress.java new file mode 100755 index 0000000..3b36166 --- /dev/null +++ b/juneau-examples-rest/src/main/java/org/apache/juneau/examples/addressbook/CreateAddress.java @@ -0,0 +1,43 @@ +// *************************************************************************************************************************** +// * 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.examples.addressbook; + +import org.apache.juneau.annotation.*; +import org.apache.juneau.jena.annotation.*; +import org.apache.juneau.xml.annotation.*; + +/** + * POJO for creating a new address + */ +@Xml(prefix="addr") +@Rdf(prefix="addr") +@Bean(typeName="address") +public class CreateAddress { + + // Bean properties + @Xml(prefix="mail") @Rdf(prefix="mail") public String street, city, state; + @Xml(prefix="mail") @Rdf(prefix="mail") public int zip; + public boolean isCurrent; + + /** Bean constructor - Needed for instantiating on server side */ + public CreateAddress() {} + + /** Normal constructor - Needed for instantiating on client side */ + public CreateAddress(String street, String city, String state, int zip, boolean isCurrent) { + this.street = street; + this.city = city; + this.state = state; + this.zip = zip; + this.isCurrent = isCurrent; + } +} http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/e3d95284/juneau-examples-rest/src/main/java/org/apache/juneau/examples/addressbook/CreatePerson.java ---------------------------------------------------------------------- diff --git a/juneau-examples-rest/src/main/java/org/apache/juneau/examples/addressbook/CreatePerson.java b/juneau-examples-rest/src/main/java/org/apache/juneau/examples/addressbook/CreatePerson.java new file mode 100755 index 0000000..d064fd7 --- /dev/null +++ b/juneau-examples-rest/src/main/java/org/apache/juneau/examples/addressbook/CreatePerson.java @@ -0,0 +1,45 @@ +// *************************************************************************************************************************** +// * 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.examples.addressbook; + +import java.util.*; + +import org.apache.juneau.annotation.*; +import org.apache.juneau.jena.annotation.*; +import org.apache.juneau.transforms.*; +import org.apache.juneau.xml.annotation.*; + +/** + * POJO for creating a new person + */ +@Xml(prefix="per") +@Rdf(prefix="per") +@Bean(typeName="person") +public class CreatePerson { + + // Bean properties + public String name; + @BeanProperty(swap=CalendarSwap.DateMedium.class) public Calendar birthDate; + public LinkedList<CreateAddress> addresses = new LinkedList<CreateAddress>(); + + /** Bean constructor - Needed for instantiating on server side */ + public CreatePerson() {} + + /** Normal constructor - Needed for instantiating on client side */ + public CreatePerson(String name, Calendar birthDate, CreateAddress...addresses) { + this.name = name; + this.birthDate = birthDate; + this.addresses.addAll(Arrays.asList(addresses)); + } +} + http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/e3d95284/juneau-examples-rest/src/main/java/org/apache/juneau/examples/addressbook/IAddressBook.java ---------------------------------------------------------------------- diff --git a/juneau-examples-rest/src/main/java/org/apache/juneau/examples/addressbook/IAddressBook.java b/juneau-examples-rest/src/main/java/org/apache/juneau/examples/addressbook/IAddressBook.java new file mode 100755 index 0000000..b72c0a1 --- /dev/null +++ b/juneau-examples-rest/src/main/java/org/apache/juneau/examples/addressbook/IAddressBook.java @@ -0,0 +1,45 @@ +// *************************************************************************************************************************** +// * 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.examples.addressbook; + +import java.util.*; + +import org.apache.juneau.examples.rest.*; + +/** + * Interface used to help illustrate proxy interfaces. + * See {@link SampleRemoteableServlet}. + */ +public interface IAddressBook { + + /** Return all people in the address book */ + List<Person> getPeople(); + + /** Return all addresses in the address book */ + List<Address> getAddresses(); + + /** Create a person in this address book */ + Person createPerson(CreatePerson cp) throws Exception; + + /** Find a person by id */ + Person findPerson(int id); + + /** Find an address by id */ + Address findAddress(int id); + + /** Find a person by address id */ + Person findPersonWithAddress(int id); + + /** Remove a person by id */ + Person removePerson(int id); +} http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/e3d95284/juneau-examples-rest/src/main/java/org/apache/juneau/examples/addressbook/Person.java ---------------------------------------------------------------------- diff --git a/juneau-examples-rest/src/main/java/org/apache/juneau/examples/addressbook/Person.java b/juneau-examples-rest/src/main/java/org/apache/juneau/examples/addressbook/Person.java new file mode 100755 index 0000000..1d8c73c --- /dev/null +++ b/juneau-examples-rest/src/main/java/org/apache/juneau/examples/addressbook/Person.java @@ -0,0 +1,73 @@ +// *************************************************************************************************************************** +// * 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.examples.addressbook; + +import java.net.URI; +import java.util.*; + +import org.apache.juneau.annotation.*; +import org.apache.juneau.jena.annotation.*; +import org.apache.juneau.transforms.*; +import org.apache.juneau.xml.annotation.*; + +/** + * Person POJO + */ +@Xml(prefix="per") +@Rdf(prefix="per") +@Bean(typeName="person") +public class Person { + + private static int nextPersonId = 1; + + // Bean properties + @Rdf(beanUri=true) public URI uri; + public URI addressBookUri; + public int id; + public String name; + @BeanProperty(swap=CalendarSwap.DateMedium.class) public Calendar birthDate; + public LinkedList<Address> addresses = new LinkedList<Address>(); + + /** Bean constructor - Needed for instantiating on server side */ + public Person() {} + + /** Normal constructor - Needed for instantiating on client side */ + public Person(URI addressBookUri, CreatePerson cp) throws Exception { + this.id = nextPersonId++; + this.addressBookUri = addressBookUri; + if (addressBookUri != null) + this.uri = addressBookUri.resolve("people/" + id); + this.name = cp.name; + this.birthDate = cp.birthDate; + for (CreateAddress ca : cp.addresses) + this.addresses.add(new Address(addressBookUri, uri, ca)); + } + + /** Extra read-only bean property */ + public int getAge() { + return new GregorianCalendar().get(Calendar.YEAR) - birthDate.get(Calendar.YEAR); + } + + /** Convenience method - Add an address for this person */ + public Address createAddress(CreateAddress ca) throws Exception { + Address a = new Address(addressBookUri, uri, ca); + addresses.add(a); + return a; + } + + /** Extra method (for method invocation example) */ + public String sayHello(String toPerson, int age) { + return name + " says hello to " + toPerson + " who is " + age + " years old"; + } +} + http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/e3d95284/juneau-examples-rest/src/main/java/org/apache/juneau/examples/addressbook/package-info.java ---------------------------------------------------------------------- diff --git a/juneau-examples-rest/src/main/java/org/apache/juneau/examples/addressbook/package-info.java b/juneau-examples-rest/src/main/java/org/apache/juneau/examples/addressbook/package-info.java new file mode 100755 index 0000000..5d597ca --- /dev/null +++ b/juneau-examples-rest/src/main/java/org/apache/juneau/examples/addressbook/package-info.java @@ -0,0 +1,35 @@ +// *************************************************************************************************************************** +// * 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. * +// *************************************************************************************************************************** +// XML namespaces used in this package +@XmlSchema( + prefix="ab", + xmlNs={ + @XmlNs(prefix="ab", namespaceURI="http://www.apache.org/addressBook/"), + @XmlNs(prefix="per", namespaceURI="http://www.apache.org/person/"), + @XmlNs(prefix="addr", namespaceURI="http://www.apache.org/address/"), + @XmlNs(prefix="mail", namespaceURI="http://www.apache.org/mail/") + } +) +@RdfSchema( + prefix="ab", + rdfNs={ + @RdfNs(prefix="ab", namespaceURI="http://www.apache.org/addressBook/"), + @RdfNs(prefix="per", namespaceURI="http://www.apache.org/person/"), + @RdfNs(prefix="addr", namespaceURI="http://www.apache.org/address/"), + @RdfNs(prefix="mail", namespaceURI="http://www.apache.org/mail/") + } +) +package org.apache.juneau.examples.addressbook; +import org.apache.juneau.jena.annotation.*; +import org.apache.juneau.xml.annotation.*; + http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/e3d95284/juneau-examples-rest/src/main/java/org/apache/juneau/examples/addressbook/package.html ---------------------------------------------------------------------- diff --git a/juneau-examples-rest/src/main/java/org/apache/juneau/examples/addressbook/package.html b/juneau-examples-rest/src/main/java/org/apache/juneau/examples/addressbook/package.html new file mode 100755 index 0000000..21caee9 --- /dev/null +++ b/juneau-examples-rest/src/main/java/org/apache/juneau/examples/addressbook/package.html @@ -0,0 +1,42 @@ +<!-- +/*************************************************************************************************************************** + * 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> + <style type="text/css"> + /* For viewing in Page Designer */ + @IMPORT url("../../../../../../org.apache.juneau/javadoc.css"); + + /* For viewing in REST interface */ + @IMPORT url("../htdocs/javadoc.css"); + body { + margin: 20px; + } + </style> + <script> + /* Replace all @code and @link tags. */ + window.onload = function() { + document.body.innerHTML = document.body.innerHTML.replace(/\{\@code ([^\}]+)\}/g, '<code>$1</code>'); + document.body.innerHTML = document.body.innerHTML.replace(/\{\@link (([^\}]+)\.)?([^\.\}]+)\}/g, '<code>$3</code>'); + } + </script> +</head> +<body> +<p>Javadocs for Address Book Resource Example</p> +<p> + Pretend there is documentation here. +</p> +</body> +</html> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/e3d95284/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/AdminGuard.java ---------------------------------------------------------------------- diff --git a/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/AdminGuard.java b/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/AdminGuard.java new file mode 100644 index 0000000..f9b85c6 --- /dev/null +++ b/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/AdminGuard.java @@ -0,0 +1,26 @@ +// *************************************************************************************************************************** +// * 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.examples.rest; + +import org.apache.juneau.rest.*; + +/** + * Sample guard that only lets administrators through. + */ +public class AdminGuard extends RestGuard { + + @Override /* RestGuard */ + public boolean isRequestAllowed(RestRequest req) { + return true; + } +} http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/e3d95284/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/AtomFeedResource.java ---------------------------------------------------------------------- diff --git a/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/AtomFeedResource.java b/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/AtomFeedResource.java new file mode 100644 index 0000000..3b8e25b --- /dev/null +++ b/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/AtomFeedResource.java @@ -0,0 +1,103 @@ +// *************************************************************************************************************************** +// * 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.examples.rest; + +import static org.apache.juneau.dto.atom.AtomBuilder.*; +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.encoders.*; +import org.apache.juneau.microservice.*; +import org.apache.juneau.rest.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.examples.rest.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 = + feed("tag:juneau.sample.com,2013:1", "Juneau ATOM specification", "2013-05-08T12:29:29Z") + .subtitle(text("html").text("A <em>lot</em> of effort went into making this effortless")) + .links( + link("alternate", "text/html", "http://www.sample.com/").hreflang("en"), + link("self", "application/atom+xml", "http://www.sample.com/feed.atom") + ) + .rights("Copyright (c) 2016, Apache Foundation") + .generator( + generator("Juneau").uri("http://juneau.apache.org/").version("1.0") + ) + .entries( + entry("tag:juneau.sample.com,2013:1.2345", "Juneau ATOM specification snapshot", "2013-05-08T12:29:29Z") + .links( + link("alternate", "text/html", "http://www.sample.com/2012/05/08/juneau.atom"), + link("enclosure", "audio/mpeg", "http://www.sample.com/audio/juneau_podcast.mp3").length(1337) + ) + .published("2013-05-08T12:29:29Z") + .authors( + person("James Bognar").uri(new URI("http://www.sample.com/")).email("[email protected]") + ) + .contributors( + person("Barry M. Caceres") + ) + .content( + content("xhtml") + .lang("en") + .base("http://www.apache.org/") + .text("<div><p>[Update: Juneau supports ATOM.]</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(@Body Feed feed) throws Exception { + this.feed = feed; + return feed; + } +} http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/e3d95284/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/CodeFormatterResource.java ---------------------------------------------------------------------- diff --git a/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/CodeFormatterResource.java b/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/CodeFormatterResource.java new file mode 100644 index 0000000..b0daf7e --- /dev/null +++ b/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/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.examples.rest; + +import static org.apache.juneau.html.HtmlDocSerializerContext.*; + +import java.io.*; + +import org.apache.juneau.microservice.*; +import org.apache.juneau.rest.*; +import org.apache.juneau.rest.annotation.*; + +/** + * Service at <code>/codeFormatter</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.examples.rest.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(@FormData("code") String code, @FormData("lang") String lang) throws Exception { + return SourceResource.highlight(code, lang); + } +} http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/e3d95284/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/Constants.java ---------------------------------------------------------------------- diff --git a/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/Constants.java b/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/Constants.java new file mode 100644 index 0000000..48cea08 --- /dev/null +++ b/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/Constants.java @@ -0,0 +1,28 @@ +// *************************************************************************************************************************** +// * 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.examples.rest; + +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/e3d95284/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/DirectoryResource.java ---------------------------------------------------------------------- diff --git a/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/DirectoryResource.java b/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/DirectoryResource.java new file mode 100644 index 0000000..9a2b84b --- /dev/null +++ b/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/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.examples.rest; + +import static java.util.logging.Level.*; +import static javax.servlet.http.HttpServletResponse.*; +import static org.apache.juneau.html.HtmlDocSerializerContext.*; +import static org.apache.juneau.rest.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.rest.*; +import org.apache.juneau.rest.annotation.*; +import org.apache.juneau.rest.annotation.Properties; +import org.apache.juneau.rest.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.examples.rest.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/e3d95284/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/DockerRegistryResource.java ---------------------------------------------------------------------- diff --git a/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/DockerRegistryResource.java b/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/DockerRegistryResource.java new file mode 100644 index 0000000..bb078af --- /dev/null +++ b/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/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.examples.rest; + +import static org.apache.juneau.html.HtmlDocSerializerContext.*; + +import java.util.*; + +import javax.servlet.*; + +import org.apache.juneau.json.*; +import org.apache.juneau.microservice.*; +import org.apache.juneau.rest.*; +import org.apache.juneau.rest.annotation.*; +import org.apache.juneau.rest.client.*; +import org.apache.juneau.rest.labels.*; + +/** + * Sample resource that shows how to mirror query results from a Docker registry. + */ +@RestResource( + path="/docker", + title="Sample Docker resource", + properties={ + @Property(name=HTMLDOC_links, value="{up:'$R{requestParentURI}',options:'?method=OPTIONS',source:'$R{servletParentURI}/source?classes=(org.apache.juneau.examples.rest.AtomFeedResource)'}") + } +) +public class DockerRegistryResource extends Resource { + private static final long serialVersionUID = 1L; + + // Get registry URL from examples.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(@Query("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/e3d95284/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/HelloWorldResource.java ---------------------------------------------------------------------- diff --git a/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/HelloWorldResource.java b/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/HelloWorldResource.java new file mode 100644 index 0000000..4a519a8 --- /dev/null +++ b/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/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.examples.rest; + +import static org.apache.juneau.html.HtmlDocSerializerContext.*; + +import org.apache.juneau.microservice.*; +import org.apache.juneau.rest.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/e3d95284/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/JsonSchemaResource.java ---------------------------------------------------------------------- diff --git a/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/JsonSchemaResource.java b/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/JsonSchemaResource.java new file mode 100644 index 0000000..c531bb1 --- /dev/null +++ b/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/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.examples.rest; + +import static org.apache.juneau.html.HtmlDocSerializerContext.*; + +import org.apache.juneau.dto.jsonschema.*; +import org.apache.juneau.microservice.*; +import org.apache.juneau.rest.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.examples.rest.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(@Body Schema schema) throws Exception { + this.schema = schema; + return schema; + } +} http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/e3d95284/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/MethodExampleResource.java ---------------------------------------------------------------------- diff --git a/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/MethodExampleResource.java b/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/MethodExampleResource.java new file mode 100644 index 0000000..c523cbf --- /dev/null +++ b/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/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.examples.rest; + +import static org.apache.juneau.html.HtmlDocSerializerContext.*; + +import java.util.*; + +import org.apache.juneau.microservice.*; +import org.apache.juneau.rest.*; +import org.apache.juneau.rest.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.examples.rest.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}/*", responses={@Response(200)}) + public String doGetExample1( + @Method String method, + @Path String a1, + @Path int a2, + @Path UUID a3, + @Query("p1") int p1, + @Query("p2") String p2, + @Query("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}/*", responses={@Response(200)}) + public void doGetExample2(RestRequest req, RestResponse res) throws Exception { + String method = req.getMethod(); + + // Attributes (from URL pattern variables) + String a1 = req.getPathParameter("a1", String.class); + int a2 = req.getPathParameter("a2", int.class); + UUID a3 = req.getPathParameter("a3", UUID.class); + + // Optional GET parameters + int p1 = req.getQueryParameter("p1", int.class, 0); + String p2 = req.getQueryParameter("p2", String.class); + UUID p3 = req.getQueryParameter("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/e3d95284/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/PhotosResource.java ---------------------------------------------------------------------- diff --git a/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/PhotosResource.java b/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/PhotosResource.java new file mode 100644 index 0000000..81bfe9c --- /dev/null +++ b/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/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.examples.rest; + +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.rest.*; +import org.apache.juneau.rest.annotation.*; +import org.apache.juneau.serializer.*; + +/** + * 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.examples.rest.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("averycutecat.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(@Path 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(@Path int id, @Body 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(@Body 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(@Path 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()); + } + } +}
