You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@juneau.apache.org by ja...@apache.org on 2016/08/01 17:30:28 UTC

[39/53] [partial] incubator-juneau git commit: Merge changes from GitHub repo.

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/1b4f98a0/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/addressbook/AddressBookResource.java
----------------------------------------------------------------------
diff --git a/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/addressbook/AddressBookResource.java b/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/addressbook/AddressBookResource.java
new file mode 100755
index 0000000..78608e1
--- /dev/null
+++ b/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/addressbook/AddressBookResource.java
@@ -0,0 +1,331 @@
+/***************************************************************************************************************************
+ * 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.addressbook;
+
+import static javax.servlet.http.HttpServletResponse.*;
+import static org.apache.juneau.html.HtmlDocSerializerContext.*;
+import static org.apache.juneau.jena.RdfCommonContext.*;
+import static org.apache.juneau.jena.RdfSerializerContext.*;
+import static org.apache.juneau.samples.addressbook.AddressBook.*;
+import static org.apache.juneau.server.RestServletContext.*;
+import static org.apache.juneau.server.labels.DefaultLabels.*;
+
+import java.util.*;
+
+import org.apache.juneau.*;
+import org.apache.juneau.dto.*;
+import org.apache.juneau.dto.cognos.*;
+import org.apache.juneau.encoders.*;
+import org.apache.juneau.microservice.*;
+import org.apache.juneau.samples.addressbook.*;
+import org.apache.juneau.server.*;
+import org.apache.juneau.server.annotation.*;
+import org.apache.juneau.server.converters.*;
+import org.apache.juneau.server.labels.*;
+import org.apache.juneau.server.samples.*;
+import org.apache.juneau.transform.*;
+import org.apache.juneau.utils.*;
+
+/**
+ * Proof-of-concept resource that shows off the capabilities of working with POJO resources.
+ * Consists of an in-memory address book repository.
+ */
+@RestResource(
+	path="/addressBook",
+	messages="nls/AddressBookResource",
+	properties={
+		@Property(name=REST_allowMethodParam, value="*"),
+		@Property(name=HTML_uriAnchorText, value=TO_STRING),
+		@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:'$R{servletURI}?method=OPTIONS',source:'$R{servletParentURI}/source?classes=(org.apache.juneau.server.samples.addressbook.AddressBookResource,org.apache.juneau.samples.addressbook.Address,org.apache.juneau.samples.addressbook.AddressBook,org.apache.juneau.samples.addressbook.CreateAddress,org.apache.juneau.samples.addressbook.CreatePerson,org.apache.juneau.samples.addressbook.IAddressBook,org.apache.juneau.samples.addressbook.Person)'}"),
+		// Resolve all relative URIs so that they're relative to this servlet!
+		@Property(name=SERIALIZER_relativeUriBase, value="$R{servletURI}"),
+	},
+	stylesheet="styles/devops.css",
+	encoders=GzipEncoder.class
+)
+public class AddressBookResource extends ResourceJena {
+	private static final long serialVersionUID = 1L;
+
+	// The in-memory address book
+	private AddressBook addressBook;
+
+	@Override /* Servlet */
+	public void init() {
+
+		try {
+			// Create the address book
+			addressBook = new AddressBook(java.net.URI.create(""));
+
+			// Add some people to our address book by default
+			addressBook.createPerson(
+				new CreatePerson(
+					"Barack Obama",
+					toCalendar("Aug 4, 1961"),
+					new CreateAddress("1600 Pennsylvania Ave", "Washington", "DC", 20500, true),
+					new CreateAddress("5046 S Greenwood Ave", "Chicago", "IL", 60615, false)
+				)
+			);
+			addressBook.createPerson(
+				new CreatePerson(
+					"George Walker Bush",
+					toCalendar("Jul 6, 1946"),
+					new CreateAddress("43 Prairie Chapel Rd", "Crawford", "TX", 76638, true),
+					new CreateAddress("1600 Pennsylvania Ave", "Washington", "DC", 20500, false)
+				)
+			);
+
+		} catch (Exception e) {
+			throw new RuntimeException(e);
+		}
+	}
+
+	/**
+	 * [GET /]
+	 * Get root page.
+	 */
+	@RestMethod(name="GET", path="/",
+		converters=Queryable.class
+	)
+	public Link[] getRoot() throws Exception {
+		return new Link[] {
+			new Link("people", "people"),
+			new Link("addresses", "addresses")
+		};
+	}
+
+	/**
+	 * [GET /people/*]
+	 * Get all people in the address book.
+	 * Traversable filtering enabled to allow nodes in returned POJO tree to be addressed.
+	 * Introspectable filtering enabled to allow public methods on the returned object to be invoked.
+	 */
+	@RestMethod(name="GET", path="/people/*",
+		converters={Traversable.class,Queryable.class,Introspectable.class}
+	)
+	public AddressBook getAllPeople() throws Exception {
+		return addressBook;
+	}
+
+	/**
+	 * [GET /people/{id}/*]
+	 * Get a single person by ID.
+	 * Traversable filtering enabled to allow nodes in returned POJO tree to be addressed.
+	 * Introspectable filtering enabled to allow public methods on the returned object to be invoked.
+	 */
+	@RestMethod(name="GET", path="/people/{id}/*",
+		converters={Traversable.class,Queryable.class,Introspectable.class}
+	)
+	public Person getPerson(@Attr int id) throws Exception {
+		return findPerson(id);
+	}
+
+	/**
+	 * [GET /addresses/*]
+	 * Get all addresses in the address book.
+	 */
+	@RestMethod(name="GET", path="/addresses/*",
+		converters={Traversable.class,Queryable.class}
+	)
+	public List<Address> getAllAddresses() throws Exception {
+		return addressBook.getAddresses();
+	}
+
+	/**
+	 * [GET /addresses/{id}/*]
+	 * Get a single address by ID.
+	 */
+	@RestMethod(name="GET", path="/addresses/{id}/*",
+		converters={Traversable.class,Queryable.class}
+	)
+	public Address getAddress(@Attr int id) throws Exception {
+		return findAddress(id);
+	}
+
+	/**
+	 * [POST /people]
+	 * Create a new Person bean.
+	 */
+	@RestMethod(name="POST", path="/people",
+		guards=AdminGuard.class
+	)
+	public Redirect createPerson(@Content CreatePerson cp) throws Exception {
+		Person p = addressBook.createPerson(cp);
+		return new Redirect("people/{0}", p.id);
+	}
+
+	/**
+	 * [POST /people/{id}/addresses]
+	 * Create a new Address bean.
+	 */
+	@RestMethod(name="POST", path="/people/{id}/addresses",
+		guards=AdminGuard.class
+	)
+	public Redirect createAddress(@Attr int id, @Content CreateAddress ca) throws Exception {
+		Person p = findPerson(id);
+		Address a = p.createAddress(ca);
+		return new Redirect("addresses/{0}", a.id);
+	}
+
+	/**
+	 * [DELETE /people/{id}]
+	 * Delete a Person bean.
+	 */
+	@RestMethod(name="DELETE", path="/people/{id}",
+		guards=AdminGuard.class
+	)
+	public String deletePerson(@Attr int id) throws Exception {
+		addressBook.removePerson(id);
+		return "DELETE successful";
+	}
+
+	/**
+	 * [DELETE /addresses/{id}]
+	 * Delete an Address bean.
+	 */
+	@RestMethod(name="DELETE", path="/addresses/{id}",
+		guards=AdminGuard.class
+	)
+	public String deleteAddress(@Attr int addressId) throws Exception {
+		Person p = addressBook.findPersonWithAddress(addressId);
+		if (p == null)
+			throw new RestException(SC_NOT_FOUND, "Person not found");
+		Address a = findAddress(addressId);
+		p.addresses.remove(a);
+		return "DELETE successful";
+	}
+
+	/**
+	 * [PUT /people/{id}/*]
+	 * Change property on Person bean.
+	 */
+	@RestMethod(name="PUT", path="/people/{id}/*",
+		guards=AdminGuard.class
+	)
+	public String updatePerson(RestRequest req, @Attr int id) throws Exception {
+		try {
+			Person p = findPerson(id);
+			String pathRemainder = req.getPathRemainder();
+			PojoRest r = new PojoRest(p);
+			ClassMeta<?> cm = r.getClassMeta(pathRemainder);
+			Object in = req.getInput(cm);
+			r.put(pathRemainder, in);
+			return "PUT successful";
+		} catch (Exception e) {
+			throw new RestException(SC_BAD_REQUEST, "PUT unsuccessful").initCause(e);
+		}
+	}
+
+	/**
+	 * [PUT /addresses/{id}/*]
+	 * Change property on Address bean.
+	 */
+	@RestMethod(name="PUT", path="/addresses/{id}/*",
+		guards=AdminGuard.class
+	)
+	public String updateAddress(RestRequest req, @Attr int id) throws Exception {
+		try {
+			Address a = findAddress(id);
+			String pathInfo = req.getPathInfo();
+			PojoRest r = new PojoRest(a);
+			ClassMeta<?> cm = r.getClassMeta(pathInfo);
+			Object in = req.getInput(cm);
+			r.put(pathInfo, in);
+			return "PUT successful";
+		} catch (Exception e) {
+			throw new RestException(SC_BAD_REQUEST, "PUT unsuccessful").initCause(e);
+		}
+	}
+
+	/**
+	 * [INIT /]
+	 * Reinitialize this resource.
+	 */
+	@RestMethod(name="INIT", path="/",
+		guards=AdminGuard.class
+	)
+	public String doInit() throws Exception {
+		init();
+		return "OK";
+	}
+
+	/**
+	 * [GET /cognos]
+	 * Get data in Cognos/XML format
+	 */
+	@RestMethod(name="GET", path="/cognos")
+	public DataSet getCognosData() throws Exception {
+
+		// The Cognos metadata
+		Column[] items = {
+			new Column("name", "xs:String", 255),
+			new Column("age", "xs:int"),
+			new Column("numAddresses", "xs:int")
+				.addTransform(
+					new PojoTransform<Person,Integer>() {
+						@Override /* PojoTransform */
+						public Integer transform(Person p) {
+							return p.addresses.size();
+						}
+					}
+				)
+		};
+
+		return new DataSet(items, addressBook, this.getBeanContext());
+	}
+
+	/**
+	 * [OPTIONS /*]
+	 * View resource options
+	 */
+	@Override /* RestServletJenaDefault */
+	@RestMethod(name="OPTIONS", path="/*")
+	public ResourceOptions getOptions(RestRequest req) {
+		return new Options(req);
+	}
+
+	/** Convenience method - Find a person by ID */
+	private Person findPerson(int id) throws RestException {
+		Person p = addressBook.findPerson(id);
+		if (p == null)
+			throw new RestException(SC_NOT_FOUND, "Person not found");
+		return p;
+	}
+
+	/** Convenience method - Find an address by ID */
+	private Address findAddress(int id) throws RestException {
+		Address a = addressBook.findAddress(id);
+		if (a == null)
+			throw new RestException(SC_NOT_FOUND, "Address not found");
+		return a;
+	}
+
+	/**
+	 * Output POJO for OPTIONS requests.
+	 * Note that we're extending the existing ResourceOptions class.
+	 */
+	public class Options extends ResourceOptions {
+		public ParamDescription[] queryableParameters;
+		public String[] otherNotes;
+
+		public Options(RestRequest req) {
+			super(AddressBookResource.this, req);
+			Locale locale = req.getLocale();
+			queryableParameters = getQueryableParamDescriptions(locale);
+			otherNotes = getMessage(locale, "otherNotes").split("\\.\\s*");
+		}
+	}
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/1b4f98a0/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/addressbook/ClientTest.java
----------------------------------------------------------------------
diff --git a/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/addressbook/ClientTest.java b/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/addressbook/ClientTest.java
new file mode 100755
index 0000000..4ee49bb
--- /dev/null
+++ b/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/addressbook/ClientTest.java
@@ -0,0 +1,107 @@
+/***************************************************************************************************************************
+ * 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.addressbook;
+
+import java.text.*;
+import java.util.*;
+
+import org.apache.juneau.client.*;
+import org.apache.juneau.json.*;
+import org.apache.juneau.samples.addressbook.*;
+import org.apache.juneau.xml.*;
+
+/**
+ * Sample client code for interacting with AddressBookResource
+ */
+public class ClientTest {
+
+	public static void main(String[] args) {
+
+		try {
+			System.out.println("Running client test...");
+
+			// Create a client to handle XML requests and responses.
+			RestClient client = new RestClient(JsonSerializer.DEFAULT, JsonParser.DEFAULT);
+			RestClient xmlClient = new RestClient(XmlSerializer.DEFAULT, XmlParser.DEFAULT);
+			try {
+				String root = "http://localhost:10000/addressBook";
+
+				// Get the current contents of the address book
+				AddressBook ab = client.doGet(root + "/people").getResponse(AddressBook.class);
+				System.out.println("Number of entries = " + ab.getPeople().size());
+
+				// Same, but use XML as the protocol both ways
+				ab = xmlClient.doGet(root + "/people").getResponse(AddressBook.class);
+				System.out.println("Number of entries = " + ab.getPeople().size());
+
+
+				// Delete the existing entries
+				for (Person p : ab.getPeople()) {
+					String r = client.doDelete(p.uri).getResponse(String.class);
+					System.out.println("Deleted person " + p.name + ", response = " + r);
+				}
+
+				// Make sure they're gone
+				ab = client.doGet(root + "/people").getResponse(AddressBook.class);
+				System.out.println("Number of entries = " + ab.getPeople().size());
+
+				// Add 1st person again
+				CreatePerson cp = new CreatePerson(
+					"Barack Obama",
+					toCalendar("Aug 4, 1961"),
+					new CreateAddress("1600 Pennsylvania Ave", "Washington", "DC", 20500, true),
+					new CreateAddress("5046 S Greenwood Ave", "Chicago", "IL", 60615, false)
+				);
+				Person p = client.doPost(root + "/people", cp).getResponse(Person.class);
+				System.out.println("Created person " + p.name + ", uri = " + p.uri);
+
+				// Add 2nd person again, but add addresses separately
+				cp = new CreatePerson(
+					"George Walker Bush",
+					toCalendar("Jul 6, 1946")
+				);
+				p = client.doPost(root + "/people", cp).getResponse(Person.class);
+				System.out.println("Created person " + p.name + ", uri = " + p.uri);
+
+				// Add addresses to 2nd person
+				CreateAddress ca = new CreateAddress("43 Prairie Chapel Rd", "Crawford", "TX", 76638, true);
+				Address a = client.doPost(p.uri + "/addresses", ca).getResponse(Address.class);
+				System.out.println("Created address " + a.uri);
+
+				ca = new CreateAddress("1600 Pennsylvania Ave", "Washington", "DC", 20500, false);
+				a = client.doPost(p.uri + "/addresses", ca).getResponse(Address.class);
+				System.out.println("Created address " + a.uri);
+
+				// Find 1st person, and change name
+				Person[] pp = client.doGet(root + "/people?q=(name='Barack+Obama')").getResponse(Person[].class);
+				String r = client.doPut(pp[0].uri + "/name", "Barack Hussein Obama").getResponse(String.class);
+				System.out.println("Changed name, response = " + r);
+				p = client.doGet(pp[0].uri).getResponse(Person.class);
+				System.out.println("New name = " + p.name);
+			} finally {
+				client.closeQuietly();
+				xmlClient.closeQuietly();
+			}
+
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+	}
+
+	// Utility method
+	public static Calendar toCalendar(String birthDate) throws Exception {
+		Calendar c = new GregorianCalendar();
+		c.setTime(DateFormat.getDateInstance(DateFormat.MEDIUM).parse(birthDate));
+		return c;
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/1b4f98a0/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/addressbook/nls/AddressBookResource.properties
----------------------------------------------------------------------
diff --git a/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/addressbook/nls/AddressBookResource.properties b/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/addressbook/nls/AddressBookResource.properties
new file mode 100755
index 0000000..b3230b0
--- /dev/null
+++ b/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/addressbook/nls/AddressBookResource.properties
@@ -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.                                              *
+# ***************************************************************************************************************************
+
+label = AddressBook sample resource
+description = Proof-of-concept resource that shows off the capabilities of working with POJO resources
+
+getRoot = Get root page
+
+getAllPeople = Get all people in the address book
+getAllPeople.res.200.content = List<Person>
+
+getPerson = Get a single person by ID
+getPerson.req.attr.id = Person UUID
+getPerson.res.200.content = Person bean
+getPerson.res.404 = Person ID not found
+
+getAllAddresses = Get all addresses in the address book
+getAllAddresses.res.200.content = List<Address>
+
+getAddress = Get a single address by ID
+getAddress.req.attr.id = Address UUID
+getAddress.res.200.content = Address bean
+getAddress.res.404 = Address ID not found
+
+createPerson = Create a new Person bean 
+createPerson.res.307.header.Location = URL of new person
+
+createAddress = Create a new Address bean
+createAddress.req.attr.id = Person UUID
+createAddress.res.307.header.Location = URL of new address
+
+deletePerson = Delete a Person bean
+deletePerson.req.attr.id = Person UUID
+deletePerson.res.200.content = "DELETE successful"
+deletePerson.res.404 = Person ID not found
+
+deleteAddress = Delete an Address bean
+deleteAddress.req.attr.id = Address UUID
+deleteAddress.res.200.content = "DELETE successful"
+deleteAddress.res.404 = Address ID not found
+
+updatePerson = Change property on Person bean
+updatePerson.req.attr.id = Person UUID
+updatePerson.req.content = Anything
+updatePerson.res.200.content = "PUT successful"
+updatePerson.res.400 = Invalid object type used
+updatePerson.res.404 = Person ID not found
+
+updateAddress = Change property on Address bean
+updateAddress.req.attr.id = Address UUID
+updateAddress.req.content = Anything
+updateAddress.res.200.content = "PUT successful"
+updateAddress.res.400 = Invalid object type used
+updateAddress.res.404 = Address ID not found
+
+doInit = Reinitialize this resource
+doInit.res.200.content = "OK"
+
+getOptions = View resource options
+
+getCognosData = Get data in Cognos/XML format
+getCognosData.res.200.content = DataSet
+
+otherNotes = GZip support enabled.  Public methods can be invoked by using the &Method URL parameter.  'text/cognos+xml' support available under root resource only
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/1b4f98a0/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/averycutedog.jpg
----------------------------------------------------------------------
diff --git a/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/averycutedog.jpg b/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/averycutedog.jpg
new file mode 100755
index 0000000..335855e
Binary files /dev/null and b/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/averycutedog.jpg differ

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/1b4f98a0/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/htdocs/code-highlighting.css
----------------------------------------------------------------------
diff --git a/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/htdocs/code-highlighting.css b/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/htdocs/code-highlighting.css
new file mode 100755
index 0000000..1475500
--- /dev/null
+++ b/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/htdocs/code-highlighting.css
@@ -0,0 +1,124 @@
+code, 
+tt, 
+pre,
+dt code {
+	font-size: 9pt;
+}
+
+/*--- Bordered code ---*/
+p.bcode {
+	font-size: 9pt;
+	white-space: pre;
+	border: 1px solid black;
+	margin: 10px 20px;
+	padding: 10px;
+	border-radius: 10px;
+	overflow: hidden;
+	font-family: monospace;
+	background-color: #f8f8f8;
+	border-color: #cccccc;
+	-moz-tab-size: 3;
+	tab-size: 3;
+	-o-tab-size: 3;
+}
+
+.fixedWidth {
+	max-width: 800px;
+}
+
+/* Override padding bottom in javadoc comments. */
+.blockList p.bcode {
+	padding-bottom: 0px !important;
+}
+
+/*--- Unbordered code ---*/
+p.code {
+	font-size: 9pt;
+	white-space: pre;
+	font-family: monospace;
+	padding-bottom: 15px;
+	margin: -15px;
+}
+
+td.code {
+	font-size: 9pt;
+	white-space: pre;
+	font-family: monospace;
+}
+
+table.code {
+	font-size: 9pt;
+	white-space: pre;
+	font-family: monospace;
+}
+
+/*--- Java code effects ---*/
+jc,jd,jt,jk,js,jf,jsf,jsm,ja {
+	font-size: 9pt;
+	white-space: pre;
+	font-family: monospace;
+}
+/* Comment */
+jc {
+	color: green;
+}
+/* Javadoc comment */
+jd {
+	color: #3f5fbf;
+}
+/* Javadoc tag */
+jt {
+	color: #7f9fbf;
+	font-weight: bold;
+}
+/* Primitive */
+jk {
+	color: #7f0055;
+	font-weight: bold;
+}
+/* String */
+js {
+	color: blue;
+}
+/* Field */
+jf {
+	color: blue;
+}
+/* Static field */
+jsf {
+	color: blue;
+	font-style: italic;
+}
+/* Static method */
+jsm {
+	font-style: italic;
+}
+/* Annotation */
+ja {
+	color: grey;
+}
+
+/*--- XML code effects ---*/
+xt,xa,xc,xs {
+	font-size: 9pt;
+	white-space: pre;
+	font-family: monospace;
+}
+
+xt {
+	color: DarkCyan;
+}
+
+xa {
+	color: purple;
+}
+
+xc {
+	color: mediumblue;
+}
+
+xs {
+	color: blue;
+	font-style: italic;
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/1b4f98a0/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/nls/AtomFeedResource.properties
----------------------------------------------------------------------
diff --git a/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/nls/AtomFeedResource.properties b/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/nls/AtomFeedResource.properties
new file mode 100755
index 0000000..1fadf05
--- /dev/null
+++ b/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/nls/AtomFeedResource.properties
@@ -0,0 +1,21 @@
+# ***************************************************************************************************************************
+# * 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.                                              *
+# ***************************************************************************************************************************
+
+#--------------------------------------------------------------------------------
+# AtomFeedResource labels
+#--------------------------------------------------------------------------------
+label = Sample ATOM feed resource
+description = Sample resource that shows how to render ATOM feeds
+getFeed = Get the sample ATOM feed
+setFeed = Overwrite the sample ATOM feed
+doOptions = Show resource options

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/1b4f98a0/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/nls/CodeFormatterResource.properties
----------------------------------------------------------------------
diff --git a/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/nls/CodeFormatterResource.properties b/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/nls/CodeFormatterResource.properties
new file mode 100755
index 0000000..f3f1d08
--- /dev/null
+++ b/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/nls/CodeFormatterResource.properties
@@ -0,0 +1,18 @@
+# ***************************************************************************************************************************
+# * 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.                                              *
+# ***************************************************************************************************************************
+
+#--------------------------------------------------------------------------------
+# CodeFormatterResource labels
+#--------------------------------------------------------------------------------
+label = Code Formatter
+description = Utility for generating HTML code-formatted source code

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/1b4f98a0/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/nls/HelloWorldResource.properties
----------------------------------------------------------------------
diff --git a/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/nls/HelloWorldResource.properties b/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/nls/HelloWorldResource.properties
new file mode 100755
index 0000000..8414e9a
--- /dev/null
+++ b/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/nls/HelloWorldResource.properties
@@ -0,0 +1,19 @@
+# ***************************************************************************************************************************
+# * 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.                                              *
+# ***************************************************************************************************************************
+
+#--------------------------------------------------------------------------------
+# HelloWorldResource labels
+#--------------------------------------------------------------------------------
+label = Hello World sample resource
+description = Simplest possible resource
+sayHello = Responds with "Hello world!" 

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/1b4f98a0/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/nls/JsonSchemaResource.properties
----------------------------------------------------------------------
diff --git a/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/nls/JsonSchemaResource.properties b/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/nls/JsonSchemaResource.properties
new file mode 100755
index 0000000..45664dd
--- /dev/null
+++ b/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/nls/JsonSchemaResource.properties
@@ -0,0 +1,20 @@
+# ***************************************************************************************************************************
+# * 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.                                              *
+# ***************************************************************************************************************************
+
+#--------------------------------------------------------------------------------
+# JsonSchemaResource labels
+#--------------------------------------------------------------------------------
+label = Sample resource that shows how to generate JSON-Schema documents
+getSchema = Get the JSON-Schema document
+setSchema = Overwrite the JSON-Schema document
+doOptions = Show resource options

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/1b4f98a0/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/nls/MethodExampleResource.properties
----------------------------------------------------------------------
diff --git a/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/nls/MethodExampleResource.properties b/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/nls/MethodExampleResource.properties
new file mode 100755
index 0000000..6921941
--- /dev/null
+++ b/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/nls/MethodExampleResource.properties
@@ -0,0 +1,37 @@
+# ***************************************************************************************************************************
+# * 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.                                              *
+# ***************************************************************************************************************************
+
+#--------------------------------------------------------------------------------
+# MethodExampleResource labels
+#--------------------------------------------------------------------------------
+label = A simple REST method example resource
+doGetExample = Sample GET method
+doGetExample1 = Sample GET using annotations
+doGetExample1.req.attr.a1 = Sample variable
+doGetExample1.req.attr.a2 = Sample variable
+doGetExample1.req.attr.a3 = Sample variable
+doGetExample1.req.param.p1 = Sample parameter
+doGetExample1.req.param.p2 = Sample parameter
+doGetExample1.req.param.p3 = Sample parameter
+doGetExample1.req.header.Accept-Language = Sample header
+doGetExample1.req.header.DNT = Sample header
+doGetExample2 = Sample GET using Java APIs
+doGetExample2.req.attr.a1 = Sample variable
+doGetExample2.req.attr.a2 = Sample variable
+doGetExample2.req.attr.a3 = Sample variable
+doGetExample2.req.param.p1 = Sample parameter
+doGetExample2.req.param.p2 = Sample parameter
+doGetExample2.req.param.p3 = Sample parameter
+doGetExample2.req.header.Accept-Language = Sample header
+doGetExample2.req.header.DNT = Sample header
+getOptions = Get these options

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/1b4f98a0/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/nls/PhotosResource.properties
----------------------------------------------------------------------
diff --git a/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/nls/PhotosResource.properties b/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/nls/PhotosResource.properties
new file mode 100755
index 0000000..fdcd5f2
--- /dev/null
+++ b/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/nls/PhotosResource.properties
@@ -0,0 +1,24 @@
+# ***************************************************************************************************************************
+# * 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.                                              *
+# ***************************************************************************************************************************
+
+#--------------------------------------------------------------------------------
+# PhotosResource labels
+#--------------------------------------------------------------------------------
+label = Sample resource that allows images to be uploaded and retrieved.
+getAllPhotos = Show the list of all currently loaded photos
+getPhoto = Get a photo by ID
+addPhoto = Add a photo
+setPhoto = Overwrite a photo by ID
+deletePhoto = Delete a photo by ID
+doOptions = Show resource options
+

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/1b4f98a0/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/nls/RequestEchoResource.properties
----------------------------------------------------------------------
diff --git a/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/nls/RequestEchoResource.properties b/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/nls/RequestEchoResource.properties
new file mode 100755
index 0000000..40ec24f
--- /dev/null
+++ b/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/nls/RequestEchoResource.properties
@@ -0,0 +1,19 @@
+# ***************************************************************************************************************************
+# * 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.                                              *
+# ***************************************************************************************************************************
+
+#--------------------------------------------------------------------------------
+# RequestEchoResource labels
+#--------------------------------------------------------------------------------
+label = Echos the current HttpServletRequest object back to the browser.
+doGet = Serializes the incoming HttpServletRequest object.
+

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/1b4f98a0/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/nls/RootResources.properties
----------------------------------------------------------------------
diff --git a/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/nls/RootResources.properties b/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/nls/RootResources.properties
new file mode 100755
index 0000000..d187d6f
--- /dev/null
+++ b/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/nls/RootResources.properties
@@ -0,0 +1,18 @@
+# ***************************************************************************************************************************
+# * 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.                                              *
+# ***************************************************************************************************************************
+
+#--------------------------------------------------------------------------------
+# RootResources labels
+#--------------------------------------------------------------------------------
+label = Root resources
+description = This is an example of a router resource that is used to access other resources.

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/1b4f98a0/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/nls/SampleRemoteableServlet.properties
----------------------------------------------------------------------
diff --git a/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/nls/SampleRemoteableServlet.properties b/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/nls/SampleRemoteableServlet.properties
new file mode 100755
index 0000000..087c24c
--- /dev/null
+++ b/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/nls/SampleRemoteableServlet.properties
@@ -0,0 +1,17 @@
+# ***************************************************************************************************************************
+# * 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.                                              *
+# ***************************************************************************************************************************
+
+#--------------------------------------------------------------------------------
+# SampleRemoteableServlet labels
+#--------------------------------------------------------------------------------
+label = Sample resource that demonstrates the remotable API

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/1b4f98a0/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/nls/SourceResource.properties
----------------------------------------------------------------------
diff --git a/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/nls/SourceResource.properties b/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/nls/SourceResource.properties
new file mode 100755
index 0000000..1bb3e9f
--- /dev/null
+++ b/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/nls/SourceResource.properties
@@ -0,0 +1,19 @@
+# ***************************************************************************************************************************
+# * 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.                                              *
+# ***************************************************************************************************************************
+
+#--------------------------------------------------------------------------------
+# SourceResource labels
+#--------------------------------------------------------------------------------
+label = Servlet for viewing source code on classes whose Java files are present on the classpath.
+getSource = View source on the specified classes.
+

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/1b4f98a0/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/nls/SqlQueryResource.properties
----------------------------------------------------------------------
diff --git a/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/nls/SqlQueryResource.properties b/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/nls/SqlQueryResource.properties
new file mode 100755
index 0000000..3bde956
--- /dev/null
+++ b/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/nls/SqlQueryResource.properties
@@ -0,0 +1,19 @@
+# ***************************************************************************************************************************
+# * 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.                                              *
+# ***************************************************************************************************************************
+
+#--------------------------------------------------------------------------------
+# SqlQueryResource labels
+#--------------------------------------------------------------------------------
+label = Sample resource that shows how to serialize SQL ResultSets 
+doGet = Display the query entry page
+doPost = Execute one or more queries

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/1b4f98a0/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/nls/TempDirResource.properties
----------------------------------------------------------------------
diff --git a/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/nls/TempDirResource.properties b/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/nls/TempDirResource.properties
new file mode 100755
index 0000000..1586ab6
--- /dev/null
+++ b/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/nls/TempDirResource.properties
@@ -0,0 +1,18 @@
+# ***************************************************************************************************************************
+# * 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.                                              *
+# ***************************************************************************************************************************
+
+#--------------------------------------------------------------------------------
+# TempDirResource labels
+#--------------------------------------------------------------------------------
+label = Temp Directory View Service
+description = View and download files in the '$S{java.io.tmpdir}' directory.

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/1b4f98a0/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/nls/TumblrParserResource.properties
----------------------------------------------------------------------
diff --git a/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/nls/TumblrParserResource.properties b/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/nls/TumblrParserResource.properties
new file mode 100755
index 0000000..a900159
--- /dev/null
+++ b/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/nls/TumblrParserResource.properties
@@ -0,0 +1,19 @@
+# ***************************************************************************************************************************
+# * 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.                                              *
+# ***************************************************************************************************************************
+
+#--------------------------------------------------------------------------------
+# SqlQueryResource labels
+#--------------------------------------------------------------------------------
+label = Tumblr blog parser service
+getInstructions = Get the instructions page
+parseBlog = Parse the specified blog

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/1b4f98a0/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/nls/UrlEncodedFormResource.properties
----------------------------------------------------------------------
diff --git a/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/nls/UrlEncodedFormResource.properties b/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/nls/UrlEncodedFormResource.properties
new file mode 100755
index 0000000..385508d
--- /dev/null
+++ b/org.apache.juneau.samples/src/main/java/org/apache/juneau/server/samples/nls/UrlEncodedFormResource.properties
@@ -0,0 +1,22 @@
+# ***************************************************************************************************************************
+# * 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.                                              *
+# ***************************************************************************************************************************
+
+#--------------------------------------------------------------------------------
+# UrlEncodedFormResource labels
+#--------------------------------------------------------------------------------
+label = URL-Encoded Form Post Example
+description = Shows how URL-Encoded form input can be loaded into POJOs.  POJO is simply echoed back.
+aString = A String:
+aNumber = A Number:
+aDate = A Date:
+submit = submit
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/1b4f98a0/org.apache.juneau.samples/src/test/java/org/apache/juneau/server/samples/CT_AddressBookResource.java
----------------------------------------------------------------------
diff --git a/org.apache.juneau.samples/src/test/java/org/apache/juneau/server/samples/CT_AddressBookResource.java b/org.apache.juneau.samples/src/test/java/org/apache/juneau/server/samples/CT_AddressBookResource.java
new file mode 100755
index 0000000..1c086fb
--- /dev/null
+++ b/org.apache.juneau.samples/src/test/java/org/apache/juneau/server/samples/CT_AddressBookResource.java
@@ -0,0 +1,231 @@
+/***************************************************************************************************************************
+ * 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.server.samples.TestUtils.*;
+import static org.junit.Assert.*;
+
+import java.util.*;
+
+import org.apache.juneau.*;
+import org.apache.juneau.client.*;
+import org.apache.juneau.html.*;
+import org.apache.juneau.internal.*;
+import org.apache.juneau.json.*;
+import org.apache.juneau.samples.addressbook.*;
+import org.apache.juneau.transforms.*;
+import org.apache.juneau.xml.*;
+import org.junit.*;
+
+@SuppressWarnings({"serial"})
+public class CT_AddressBookResource {
+
+	private static boolean debug = false;
+
+	static RestClient[] clients;
+
+	@BeforeClass
+	public static void beforeClass() throws Exception {
+		clients = new RestClient[] {
+			new SamplesRestClient(JsonSerializer.class, JsonParser.class),
+			new SamplesRestClient(XmlSerializer.class, XmlParser.class),
+			new SamplesRestClient(HtmlSerializer.class, HtmlParser.class).setAccept("text/html+stripped"),
+			new SamplesRestClient(XmlSerializer.class,  HtmlParser.class).setAccept("text/html+stripped")
+		};
+		for (RestClient c : clients) {
+			c.getSerializer().addTransforms(CalendarTransform.Medium.class);
+			c.getParser().addTransforms(CalendarTransform.Medium.class);
+			c.getSerializer().setProperty(XmlSerializerContext.XML_autoDetectNamespaces, true);
+		}
+	}
+
+	@AfterClass
+	public static void afterClass() {
+		for (RestClient c : clients) {
+			c.closeQuietly();
+		}
+	}
+
+	//====================================================================================================
+	// Get AddressBookResource as JSON
+	//====================================================================================================
+	@Test
+	public void testBasic() throws Exception {
+		String in = IOUtils.read(getClass().getResourceAsStream("/org/apache/juneau/server/test/CT_AddressBookResource_test0.json"));
+		JsonParser p = new JsonParser().addTransforms(CalendarTransform.Medium.class);
+		Person person = p.parse(in, Person.class);
+		if (debug) System.err.println(person);
+	}
+
+	// A list of People objects.
+	public static class PersonList extends LinkedList<Person> {}
+
+	//====================================================================================================
+	// PojoRest tests
+	//====================================================================================================
+	@Test
+	public void testPojoRest() throws Exception {
+		for (RestClient client : clients) {
+			int rc;
+			Person p;
+			List<Person> people;
+
+			// Reinitialize the resource
+			rc = client.doGet("/addressBook?method=init").run();
+			assertEquals(200, rc);
+
+			// Simple GETs
+			people = client.doGet("/addressBook/people").getResponse(PersonList.class);
+			assertEquals("Barack Obama", people.get(0).name);
+			assertEquals(76638, people.get(1).addresses.get(0).zip);
+
+			// PUT a simple String field
+			p = people.get(0);
+			rc = client.doPut(p.uri+"/name", "foo").run();
+			assertEquals(200, rc);
+			String name = client.doGet(p.uri+"/name").getResponse(String.class);
+			assertEquals("foo", name);
+			p = client.doGet(p.uri).getResponse(Person.class);
+			assertEquals("foo", p.name);
+
+			// POST an address as JSON
+			CreateAddress ca = new CreateAddress("a1","b1","c1",1,false);
+			Address a = client.doPost(p.uri + "/addresses", new ObjectMap(BeanContext.DEFAULT.forBean(ca))).getResponse(Address.class);
+			assertEquals("a1", a.street);
+			a = client.doGet(a.uri).getResponse(Address.class);
+			assertEquals("a1", a.street);
+			assertEquals(1, a.zip);
+			assertFalse(a.isCurrent);
+
+			// POST an address as a bean
+			ca = new CreateAddress("a2","b2","c2",2,true);
+			a = client.doPost(p.uri + "/addresses", ca).getResponse(Address.class);
+			assertEquals("a2", a.street);
+			a = client.doGet(a.uri).getResponse(Address.class);
+			assertEquals("a2", a.street);
+			assertEquals(2, a.zip);
+			assertTrue(a.isCurrent);
+
+			// POST a person
+			CreatePerson billClinton = new CreatePerson("Bill Clinton", AddressBook.toCalendar("Aug 19, 1946"),
+				new CreateAddress("a3","b3","c3",3,false)
+			);
+			rc = client.doPost("/addressBook/people", billClinton).run();
+			assertEquals(200, rc);
+			people = client.doGet("/addressBook/people").getResponse(PersonList.class);
+			p = people.get(2);
+			assertEquals(3, people.size());
+			assertEquals("Bill Clinton", p.name);
+
+			// DELETE an address
+			rc = client.doDelete(p.addresses.get(0).uri).run();
+			assertEquals(200, rc);
+			people = client.doGet("/addressBook/people").getResponse(PersonList.class);
+			p = people.get(2);
+			assertEquals(0, p.addresses.size());
+
+			// DELETE a person
+			rc = client.doDelete(p.uri).run();
+			assertEquals(200, rc);
+			people = client.doGet("/addressBook/people").getResponse(PersonList.class);
+			assertEquals(2, people.size());
+
+			// Reinitialize the resource
+			rc = client.doGet("/addressBook?method=init").run();
+			assertEquals(200, rc);
+		}
+	}
+
+	//====================================================================================================
+	// PojoQuery tests
+	//====================================================================================================
+	@Test
+	public void testPojoQuery() throws Exception {
+
+		for (RestClient client : clients) {
+			RestCall r;
+			List<Person> people;
+
+			// Reinitialize the resource
+			int rc = client.doGet("/addressBook?method=init").run();
+			assertEquals(200, rc);
+
+			r = client.doGet("/addressBook/people?q=(name=B*)");
+			people = r.getResponse(PersonList.class);
+			assertEquals(1, people.size());
+			assertEquals("Barack Obama", people.get(0).name);
+
+			r = client.doGet("/addressBook/people?q=(name='Barack+Obama')");
+			people = r.getResponse(PersonList.class);
+			assertEquals(1, people.size());
+			assertEquals("Barack Obama", people.get(0).name);
+
+			r = client.doGet("/addressBook/people?q=(name='Barack%20Obama')");
+			people = r.getResponse(PersonList.class);
+			assertEquals(1, people.size());
+			assertEquals("Barack Obama", people.get(0).name);
+
+			r = client.doGet("/addressBook/people?v=(name,birthDate)");
+			people = r.getResponse(PersonList.class);
+			assertEquals("Barack Obama", people.get(0).name);
+			assertTrue(people.get(0).getAge() > 10);
+			assertEquals(0, people.get(0).addresses.size());
+
+			r = client.doGet("/addressBook/people?v=(addresses,birthDate)");
+			people = r.getResponse(PersonList.class);
+			assertNull(people.get(0).name);
+			assertTrue(people.get(0).getAge() > 10);
+			assertEquals(2, people.get(0).addresses.size());
+
+			r = client.doGet("/addressBook/people?s=($o(age=d))");
+			people = r.getResponse(PersonList.class);
+			assertTrue(people.get(0).getAge() > 10);
+			r = client.doGet("/addressBook/people?s=(age)");
+			people = r.getResponse(PersonList.class);
+			assertTrue(people.get(0).getAge() > 10);
+			r = client.doGet("/addressBook/people?s=($o(age=a))");
+			people = r.getResponse(PersonList.class);
+			assertTrue(people.get(0).getAge() > 10);
+
+			r = client.doGet("/addressBook/people?p=1&l=1");
+			people = r.getResponse(PersonList.class);
+			assertEquals(1, people.size());
+			assertTrue(people.get(0).getAge() > 10);
+		}
+	}
+
+	//====================================================================================================
+	// PojoIntrospector tests
+	//====================================================================================================
+	@Test
+	public void testPojoIntrospector() throws Exception {
+
+		for (RestClient client : clients) {
+
+			List<Person> people;
+
+			// Reinitialize the resource
+			int rc = client.doGet("/addressBook?method=init").run();
+			assertEquals(200, rc);
+
+			// Simple GETs
+			people = client.doGet("/addressBook/people").getResponse(PersonList.class);
+			Person p = people.get(0);
+			int length = client.doGet(p.uri+"/name?invokeMethod=length").getResponse(Integer.class);
+			assertEquals(12, length);
+
+			String[] tokens = client.doGet(p.uri+"/name?invokeMethod=split(java.lang.String,int)&invokeArgs=['a',3]").getResponse(String[].class);
+			assertObjectEquals("['B','r','ck Obama']", tokens);
+		}
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/1b4f98a0/org.apache.juneau.samples/src/test/java/org/apache/juneau/server/samples/CT_AddressBookResource_test0.json
----------------------------------------------------------------------
diff --git a/org.apache.juneau.samples/src/test/java/org/apache/juneau/server/samples/CT_AddressBookResource_test0.json b/org.apache.juneau.samples/src/test/java/org/apache/juneau/server/samples/CT_AddressBookResource_test0.json
new file mode 100755
index 0000000..dcaaaff
--- /dev/null
+++ b/org.apache.juneau.samples/src/test/java/org/apache/juneau/server/samples/CT_AddressBookResource_test0.json
@@ -0,0 +1,14 @@
+{
+	name: "Bill Clinton", 
+	age: 66, 
+	birthDate: "Aug 19, 1946", 
+	addresses: [
+		{
+			street: "a3", 
+			city: "b3", 
+			state: "c3", 
+			zip: 3, 
+			isCurrent: false
+		}
+	]
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/1b4f98a0/org.apache.juneau.samples/src/test/java/org/apache/juneau/server/samples/CT_RootResources.java
----------------------------------------------------------------------
diff --git a/org.apache.juneau.samples/src/test/java/org/apache/juneau/server/samples/CT_RootResources.java b/org.apache.juneau.samples/src/test/java/org/apache/juneau/server/samples/CT_RootResources.java
new file mode 100755
index 0000000..a3fbc3e
--- /dev/null
+++ b/org.apache.juneau.samples/src/test/java/org/apache/juneau/server/samples/CT_RootResources.java
@@ -0,0 +1,146 @@
+/***************************************************************************************************************************
+ * 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.junit.Assert.*;
+
+import java.net.*;
+
+import org.apache.juneau.*;
+import org.apache.juneau.client.*;
+import org.apache.juneau.html.*;
+import org.apache.juneau.json.*;
+import org.apache.juneau.server.labels.*;
+import org.apache.juneau.xml.*;
+import org.junit.*;
+
+public class CT_RootResources {
+
+	private static String path = URI.create(Constants.getSampleUrl()).getPath();              // /jazz/juneau/sample
+	private static boolean debug = false;
+
+	private static RestClient jsonClient;
+
+	@BeforeClass
+	public static void beforeClass() {
+		jsonClient = new SamplesRestClient(JsonSerializer.DEFAULT, JsonParser.DEFAULT);
+	}
+
+	@AfterClass
+	public static void afterClass() {
+		jsonClient.closeQuietly();
+	}
+
+	//====================================================================================================
+	// text/json
+	//====================================================================================================
+	@Test
+	public void testJson() throws Exception {
+		RestClient client = new SamplesRestClient(JsonSerializer.DEFAULT, JsonParser.DEFAULT);
+		RestCall r = client.doGet("");
+		ResourceDescription[] x = r.getResponse(ResourceDescription[].class);
+		assertEquals("helloWorld", x[0].getName().getName());
+		assertEquals(path + "/helloWorld", x[0].getName().getHref());
+		assertEquals("Hello World sample resource", x[0].getDescription());
+
+		r = jsonClient.doOptions("");
+		ObjectMap x2 = r.getResponse(ObjectMap.class);
+		String s = x2.getString("description");
+		if (debug) System.err.println(s);
+		assertTrue(s, s.startsWith("This is an example"));
+
+		client.closeQuietly();
+	}
+
+	//====================================================================================================
+	// text/xml
+	//====================================================================================================
+	@Test
+	public void testXml() throws Exception {
+		RestClient client = new SamplesRestClient().setParser(XmlParser.DEFAULT);
+		RestCall r = client.doGet("");
+		ResourceDescription[] x = r.getResponse(ResourceDescription[].class);
+		assertEquals("helloWorld", x[0].getName().getName());
+		assertEquals(path + "/helloWorld", x[0].getName().getHref());
+		assertEquals("Hello World sample resource", x[0].getDescription());
+
+		r = jsonClient.doOptions("");
+		ObjectMap x2 = r.getResponse(ObjectMap.class);
+		String s = x2.getString("description");
+		if (debug) System.err.println(s);
+		assertTrue(s, s.startsWith("This is an example"));
+
+		client.closeQuietly();
+	}
+
+	//====================================================================================================
+	// text/html+stripped
+	//====================================================================================================
+	@Test
+	public void testHtmlStripped() throws Exception {
+		RestClient client = new SamplesRestClient().setParser(HtmlParser.DEFAULT).setAccept("text/html+stripped");
+		RestCall r = client.doGet("");
+		ResourceDescription[] x = r.getResponse(ResourceDescription[].class);
+		assertEquals("helloWorld", x[0].getName().getName());
+		assertTrue(x[0].getName().getHref().endsWith("/helloWorld"));
+		assertEquals("Hello World sample resource", x[0].getDescription());
+
+		r = jsonClient.doOptions("").setHeader("Accept", "text/json");
+		ObjectMap x2 = r.getResponse(ObjectMap.class);
+		String s = x2.getString("description");
+		if (debug) System.err.println(s);
+		assertTrue(s, s.startsWith("This is an example"));
+
+		client.closeQuietly();
+	}
+
+	//====================================================================================================
+	// /htdoces/styles.css
+	//====================================================================================================
+	@Test
+	public void testStyleSheet() throws Exception {
+		RestClient client = new SamplesRestClient().setAccept("text/css");
+		RestCall r = client.doGet("/style.css");
+		String css = r.getResponseAsString();
+		if (debug) System.err.println(css);
+		assertTrue(css, css.indexOf("table {") != -1);
+
+		client.closeQuietly();
+	}
+
+	//====================================================================================================
+	// application/json+schema
+	//====================================================================================================
+	@Test
+	public void testJsonSchema() throws Exception {
+		RestClient client = new SamplesRestClient().setParser(JsonParser.DEFAULT).setAccept("text/json+schema");
+		RestCall r = client.doGet("");
+		ObjectMap m = r.getResponse(ObjectMap.class);
+		if (debug) System.err.println(m);
+		assertEquals("org.apache.juneau.server.labels.ChildResourceDescriptions<org.apache.juneau.server.labels.ResourceDescription>", m.getString("description"));
+		assertEquals("org.apache.juneau.server.labels.ResourceDescription", m.getObjectMap("items").getString("description"));
+
+		client.closeQuietly();
+	}
+
+	//====================================================================================================
+	// OPTIONS page
+	//====================================================================================================
+	@Test
+	public void testOptionsPage() throws Exception {
+		RestCall r = jsonClient.doOptions("");
+		ResourceOptions o = r.getResponse(ResourceOptions.class);
+		if (debug) System.err.println(o);
+		assertEquals("This is an example of a router resource that is used to access other resources.", o.getDescription());
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/1b4f98a0/org.apache.juneau.samples/src/test/java/org/apache/juneau/server/samples/CT_SampleRemoteableServicesResource.java
----------------------------------------------------------------------
diff --git a/org.apache.juneau.samples/src/test/java/org/apache/juneau/server/samples/CT_SampleRemoteableServicesResource.java b/org.apache.juneau.samples/src/test/java/org/apache/juneau/server/samples/CT_SampleRemoteableServicesResource.java
new file mode 100755
index 0000000..561bfe6
--- /dev/null
+++ b/org.apache.juneau.samples/src/test/java/org/apache/juneau/server/samples/CT_SampleRemoteableServicesResource.java
@@ -0,0 +1,69 @@
+/***************************************************************************************************************************
+ * 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.junit.Assert.*;
+
+import org.apache.juneau.client.*;
+import org.apache.juneau.json.*;
+import org.apache.juneau.samples.addressbook.*;
+import org.apache.juneau.transforms.*;
+import org.apache.juneau.urlencoding.*;
+import org.apache.juneau.xml.*;
+import org.junit.*;
+
+public class CT_SampleRemoteableServicesResource {
+
+	static RestClient[] clients;
+
+	@BeforeClass
+	public static void beforeClass() throws Exception {
+		clients = new RestClient[] {
+			new SamplesRestClient(JsonSerializer.class, JsonParser.class),
+			new SamplesRestClient(XmlSerializer.class, XmlParser.class),
+//	TODO - broken?		new TestRestClient(HtmlSerializer.class, HtmlParser.class).setAccept("text/html+stripped"),
+			new SamplesRestClient(UonSerializer.class, UonParser.class),
+		};
+		for (RestClient c : clients) {
+			c.addTransforms(CalendarTransform.Medium.class);
+			c.setRemoteableServletUri("/remoteable");
+			c.setProperty(XmlSerializerContext.XML_autoDetectNamespaces, true);
+		}
+	}
+
+	@AfterClass
+	public static void afterClass() {
+		for (RestClient c : clients) {
+			c.closeQuietly();
+		}
+	}
+
+	//====================================================================================================
+	// Get AddressBookResource as JSON
+	//====================================================================================================
+	@Test
+	public void testBasic() throws Exception {
+		for (RestClient client : clients) {
+			IAddressBook ab = client.getRemoteableProxy(IAddressBook.class);
+			Person p = ab.createPerson(
+				new CreatePerson("Test Person",
+					AddressBook.toCalendar("Aug 1, 1999"),
+					new CreateAddress("Test street", "Test city", "Test state", 12345, true))
+			);
+			assertEquals(
+				"{id:x,name:'Test Person',birthDate:'Aug 1, 1999',addresses:[{id:x,street:'Test street',city:'Test city',state:'Test state',zip:12345,isCurrent:true}],age:x}",
+				JsonSerializer.DEFAULT_LAX.toString(p).replaceAll("id:\\d+", "id:x").replaceAll("age:\\d+", "age:x"));
+		}
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/1b4f98a0/org.apache.juneau.samples/src/test/java/org/apache/juneau/server/samples/CT_TestMultiPartFormPosts.java
----------------------------------------------------------------------
diff --git a/org.apache.juneau.samples/src/test/java/org/apache/juneau/server/samples/CT_TestMultiPartFormPosts.java b/org.apache.juneau.samples/src/test/java/org/apache/juneau/server/samples/CT_TestMultiPartFormPosts.java
new file mode 100755
index 0000000..168caca
--- /dev/null
+++ b/org.apache.juneau.samples/src/test/java/org/apache/juneau/server/samples/CT_TestMultiPartFormPosts.java
@@ -0,0 +1,47 @@
+/***************************************************************************************************************************
+ * 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.junit.Assert.*;
+
+import java.io.*;
+
+import org.apache.http.*;
+import org.apache.http.entity.mime.*;
+import org.apache.juneau.client.*;
+import org.apache.juneau.internal.*;
+import org.apache.juneau.utils.*;
+import org.junit.*;
+
+public class CT_TestMultiPartFormPosts {
+
+	private static String URL = "/tempDir";
+	boolean debug = false;
+
+	//====================================================================================================
+	// Test that RestClient can handle multi-part form posts.
+	//====================================================================================================
+	@Test
+	public void testUpload() throws Exception {
+		RestClient client = new SamplesRestClient();
+		File f = FileUtils.createTempFile("testMultiPartFormPosts.txt");
+		IOPipe.create(new StringReader("test!"), new FileWriter(f)).closeOut().run();
+		HttpEntity entity = MultipartEntityBuilder.create().addBinaryBody(f.getName(), f).build();
+		client.doPost(URL + "/upload", entity);
+
+		String downloaded = client.doGet(URL + '/' + f.getName() + "?method=VIEW").getResponseAsString();
+		assertEquals("test!", downloaded);
+
+		client.closeQuietly();
+	}
+}
\ No newline at end of file