Java tutorial
/** * personium.io * Copyright 2014 FUJITSU LIMITED * * Licensed 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 io.personium.core.rs.box; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.Reader; import java.util.Iterator; import java.util.List; import java.util.Map.Entry; import javax.ws.rs.DELETE; import javax.ws.rs.GET; import javax.ws.rs.HeaderParam; import javax.ws.rs.HttpMethod; import javax.ws.rs.OPTIONS; import javax.ws.rs.POST; import javax.ws.rs.PUT; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.core.Context; import javax.ws.rs.core.HttpHeaders; import javax.ws.rs.core.MultivaluedMap; import javax.ws.rs.core.Response; import javax.ws.rs.core.Response.ResponseBuilder; import javax.ws.rs.core.StreamingOutput; import javax.ws.rs.core.UriInfo; import org.apache.http.Header; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpDelete; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.client.methods.HttpPut; import org.apache.http.client.methods.HttpUriRequest; import org.apache.http.entity.InputStreamEntity; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.wink.webdav.WebDAVMethod; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import io.personium.common.utils.PersoniumCoreUtils; import io.personium.core.PersoniumCoreException; import io.personium.core.PersoniumUnitConfig; import io.personium.core.annotations.ACL; import io.personium.core.auth.BoxPrivilege; import io.personium.core.model.DavCmp; import io.personium.core.model.DavMoveResource; import io.personium.core.model.DavRsCmp; import io.personium.core.model.impl.fs.DavCmpFsImpl; /** * PersoniumEngineSvcCollectionResource?JAX-RS. */ public final class PersoniumEngineSvcCollectionResource { private static Logger log = LoggerFactory.getLogger(PersoniumEngineSvcCollectionResource.class); DavCmp davCmp = null; DavCollectionResource dcr = null; DavRsCmp davRsCmp; /** * constructor. * @param parent DavRsCmp * @param davCmp DavCmp */ public PersoniumEngineSvcCollectionResource(final DavRsCmp parent, final DavCmp davCmp) { this.davCmp = davCmp; this.dcr = new DavCollectionResource(parent, davCmp); this.davRsCmp = new DavRsCmp(parent, davCmp); } /** * PROPFIND??. * @param requestBodyXml * @param depth Depth * @param contentLength Content-Length * @param transferEncoding Transfer-Encoding * @return JAX-RS Response */ @WebDAVMethod.PROPFIND public Response propfind(final Reader requestBodyXml, @HeaderParam(PersoniumCoreUtils.HttpHeaders.DEPTH) final String depth, @HeaderParam(HttpHeaders.CONTENT_LENGTH) final Long contentLength, @HeaderParam("Transfer-Encoding") final String transferEncoding) { return this.davRsCmp.doPropfind(requestBodyXml, depth, contentLength, transferEncoding, BoxPrivilege.READ_PROPERTIES, BoxPrivilege.READ_ACL); } /** * DELETE????????. * @return JAX-RS */ @DELETE public Response delete() { // // DavEngineSvcCollectionResource??(??Box)?????this.davRsCmp.getParent()???null??????? this.davRsCmp.getParent().checkAccessContext(this.davRsCmp.getAccessContext(), BoxPrivilege.WRITE); if (!this.davRsCmp.getDavCmp().isEmpty()) { throw PersoniumCoreException.Dav.HAS_CHILDREN; } return this.davCmp.delete(null, false).build(); } /** * PROPPATCH??. * @param requestBodyXml * @return JAX-RS Response */ @WebDAVMethod.PROPPATCH public Response proppatch(final Reader requestBodyXml) { // this.davRsCmp.checkAccessContext(this.davRsCmp.getAccessContext(), BoxPrivilege.WRITE_PROPERTIES); return this.davRsCmp.doProppatch(requestBodyXml); } /** * ACL??. ACL??. * @param reader XML * @return JAX-RS Response */ @ACL public Response acl(final Reader reader) { // this.davRsCmp.checkAccessContext(this.davRsCmp.getAccessContext(), BoxPrivilege.WRITE_ACL); return this.davCmp.acl(reader).build(); } /** * OPTIONS. * @return JAX-RS Response */ @OPTIONS public Response options() { // this.davRsCmp.checkAccessContext(this.davRsCmp.getAccessContext(), BoxPrivilege.READ); return PersoniumCoreUtils.responseBuilderForOptions(HttpMethod.DELETE, io.personium.common.utils.PersoniumCoreUtils.HttpMethod.MOVE, io.personium.common.utils.PersoniumCoreUtils.HttpMethod.PROPFIND, io.personium.common.utils.PersoniumCoreUtils.HttpMethod.PROPPATCH, io.personium.common.utils.PersoniumCoreUtils.HttpMethod.ACL).build(); } /** * ?Jax-RS?. * @return DavFileResource */ @Path("__src") public PersoniumEngineSourceCollection src() { DavCmp nextCmp = this.davCmp.getChild(DavCmp.SERVICE_SRC_COLLECTION); if (nextCmp.exists()) { return new PersoniumEngineSourceCollection(this.davRsCmp, nextCmp); } else { // ??????404?? throw PersoniumCoreException.Dav.RESOURCE_NOT_FOUND; } } /** * relay_GET. * @param path ?? * @param uriInfo URI * @param headers * @return JAX-RS Response */ @Path("{path}") @GET public Response relayget(@PathParam("path") String path, @Context final UriInfo uriInfo, @Context HttpHeaders headers) { // this.davRsCmp.checkAccessContext(this.davRsCmp.getAccessContext(), BoxPrivilege.EXEC); return relaycommon(HttpMethod.GET, uriInfo, path, headers, null); } /** * relay_POST. * @param path ?? * @param uriInfo URI * @param headers * @param is * @return JAX-RS Response */ @Path("{path}") @POST public Response relaypost(@PathParam("path") String path, @Context final UriInfo uriInfo, @Context HttpHeaders headers, final InputStream is) { // this.davRsCmp.checkAccessContext(this.davRsCmp.getAccessContext(), BoxPrivilege.EXEC); return relaycommon(HttpMethod.POST, uriInfo, path, headers, is); } /** * relay_PUT. * @param path ?? * @param uriInfo URI * @param headers * @param is * @return JAX-RS Response */ @Path("{path}") @PUT public Response relayput(@PathParam("path") String path, @Context final UriInfo uriInfo, @Context HttpHeaders headers, final InputStream is) { // this.davRsCmp.checkAccessContext(this.davRsCmp.getAccessContext(), BoxPrivilege.EXEC); return relaycommon(HttpMethod.PUT, uriInfo, path, headers, is); } /** * relay_DELETE. * @param path ?? * @param uriInfo URI * @param headers * @return JAX-RS Response */ @Path("{path}") @DELETE public Response relaydelete(@PathParam("path") String path, @Context final UriInfo uriInfo, @Context HttpHeaders headers) { // this.davRsCmp.checkAccessContext(this.davRsCmp.getAccessContext(), BoxPrivilege.EXEC); return relaycommon(HttpMethod.DELETE, uriInfo, path, headers, null); } /** * relay??. * @param method * @param uriInfo URI * @param path ?? * @param headers * @param is * @return JAX-RS Response */ public Response relaycommon(String method, UriInfo uriInfo, String path, HttpHeaders headers, InputStream is) { String cellName = this.davRsCmp.getCell().getName(); String boxName = this.davRsCmp.getBox().getName(); String requestUrl = String.format("http://%s:%s/%s/%s/%s/service/%s", PersoniumUnitConfig.getEngineHost(), PersoniumUnitConfig.getEnginePort(), PersoniumUnitConfig.getEnginePath(), cellName, boxName, path); // baseUrl? String baseUrl = uriInfo.getBaseUri().toString(); // ??? HttpClient client = new DefaultHttpClient(); HttpUriRequest req = null; if (method.equals(HttpMethod.POST)) { HttpPost post = new HttpPost(requestUrl); InputStreamEntity ise = new InputStreamEntity(is, -1); ise.setChunked(true); post.setEntity(ise); req = post; } else if (method.equals(HttpMethod.PUT)) { HttpPut put = new HttpPut(requestUrl); InputStreamEntity ise = new InputStreamEntity(is, -1); ise.setChunked(true); put.setEntity(ise); req = put; } else if (method.equals(HttpMethod.DELETE)) { HttpDelete delete = new HttpDelete(requestUrl); req = delete; } else { HttpGet get = new HttpGet(requestUrl); req = get; } req.addHeader("X-Baseurl", baseUrl); req.addHeader("X-Request-Uri", uriInfo.getRequestUri().toString()); if (davCmp instanceof DavCmpFsImpl) { DavCmpFsImpl dcmp = (DavCmpFsImpl) davCmp; req.addHeader("X-Personium-Fs-Path", dcmp.getFsPath()); req.addHeader("X-Personium-Fs-Routing-Id", dcmp.getCellId()); } req.addHeader("X-Personium-Box-Schema", this.davRsCmp.getBox().getSchema()); // ??? MultivaluedMap<String, String> multivalueHeaders = headers.getRequestHeaders(); for (Iterator<Entry<String, List<String>>> it = multivalueHeaders.entrySet().iterator(); it.hasNext();) { Entry<String, List<String>> entry = it.next(); String key = (String) entry.getKey(); if (key.equalsIgnoreCase(HttpHeaders.CONTENT_LENGTH)) { continue; } List<String> valueList = (List<String>) entry.getValue(); for (Iterator<String> i = valueList.iterator(); i.hasNext();) { String value = (String) i.next(); req.setHeader(key, value); } } if (log.isDebugEnabled()) { log.debug("?EngineRelay " + req.getMethod() + " " + req.getURI()); Header[] reqHeaders = req.getAllHeaders(); for (int i = 0; i < reqHeaders.length; i++) { log.debug("RelayHeader[" + reqHeaders[i].getName() + "] : " + reqHeaders[i].getValue()); } } // Engine?? HttpResponse objResponse = null; try { objResponse = client.execute(req); } catch (ClientProtocolException e) { throw PersoniumCoreException.ServiceCollection.SC_INVALID_HTTP_RESPONSE_ERROR; } catch (Exception ioe) { throw PersoniumCoreException.ServiceCollection.SC_ENGINE_CONNECTION_ERROR.reason(ioe); } // ResponseBuilder res = Response.status(objResponse.getStatusLine().getStatusCode()); Header[] headersResEngine = objResponse.getAllHeaders(); // ? for (int i = 0; i < headersResEngine.length; i++) { // Engine????Transfer-Encoding???? // ?MW????????Content-Length???Transfer-Encoding???? // 2?????????????????????? if ("Transfer-Encoding".equalsIgnoreCase(headersResEngine[i].getName())) { continue; } // Engine????Date???? // Web??MW?Jetty???2????????? if (HttpHeaders.DATE.equalsIgnoreCase(headersResEngine[i].getName())) { continue; } res.header(headersResEngine[i].getName(), headersResEngine[i].getValue()); } InputStream isResBody = null; // ? HttpEntity entity = objResponse.getEntity(); if (entity != null) { try { isResBody = entity.getContent(); } catch (IllegalStateException e) { throw PersoniumCoreException.ServiceCollection.SC_UNKNOWN_ERROR.reason(e); } catch (IOException e) { throw PersoniumCoreException.ServiceCollection.SC_ENGINE_CONNECTION_ERROR.reason(e); } final InputStream isInvariable = isResBody; // ?? StreamingOutput strOutput = new StreamingOutput() { @Override public void write(final OutputStream os) throws IOException { int chr; try { while ((chr = isInvariable.read()) != -1) { os.write(chr); } } finally { isInvariable.close(); } } }; res.entity(strOutput); } // ?? return res.build(); } /** * MOVE??. * @param headers * @return JAX-RS */ @WebDAVMethod.MOVE public Response move(@Context HttpHeaders headers) { // ??(????) this.davRsCmp.getParent().checkAccessContext(this.davRsCmp.getAccessContext(), BoxPrivilege.WRITE); return new DavMoveResource(this.davRsCmp.getParent(), this.davRsCmp.getDavCmp(), headers).doMove(); } }