/* See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * Esri Inc. 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 com.esri.gpt.control.rest; import com.esri.gpt.catalog.arcims.ImsMetadataAdminDao; import com.esri.gpt.catalog.arcims.ImsServiceException; import com.esri.gpt.catalog.context.CatalogIndexException; import com.esri.gpt.catalog.harvest.protocols.HarvestProtocol.ProtocolType; import com.esri.gpt.catalog.harvest.repository.HrAssertUrlException; import com.esri.gpt.catalog.harvest.repository.HrCompleteUpdateRequest; import com.esri.gpt.catalog.harvest.repository.HrRecord; import com.esri.gpt.catalog.harvest.repository.HrRecord.HarvestFrequency; import com.esri.gpt.catalog.management.MmdActionCriteria; import com.esri.gpt.catalog.management.MmdActionRequest; import com.esri.gpt.catalog.management.MmdCriteria; import com.esri.gpt.catalog.management.MmdEnums; import com.esri.gpt.catalog.management.MmdResult; import com.esri.gpt.catalog.publication.PublicationRecord; import com.esri.gpt.catalog.publication.PublicationRequest; import com.esri.gpt.catalog.publication.ValidationRequest; import com.esri.gpt.catalog.schema.MetadataDocument; import com.esri.gpt.catalog.schema.SchemaException; import com.esri.gpt.catalog.schema.ValidationException; import com.esri.gpt.control.webharvest.client.arcgis.ArcGISProtocol; import com.esri.gpt.control.webharvest.protocol.ProtocolFactory; import com.esri.gpt.control.webharvest.protocol.ProtocolInvoker; import com.esri.gpt.framework.collection.StringAttribute; import com.esri.gpt.framework.collection.StringAttributeMap; import com.esri.gpt.framework.context.ApplicationConfiguration; import com.esri.gpt.framework.context.ApplicationContext; import com.esri.gpt.framework.context.BaseServlet; import com.esri.gpt.framework.context.RequestContext; import com.esri.gpt.framework.jsf.FacesContextBroker; import com.esri.gpt.framework.jsf.MessageBroker; import com.esri.gpt.framework.security.credentials.Credentials; import com.esri.gpt.framework.security.credentials.CredentialsDeniedException; import com.esri.gpt.framework.security.identity.IdentityException; import com.esri.gpt.framework.security.identity.NotAuthorizedException; import com.esri.gpt.framework.security.principal.Publisher; import com.esri.gpt.framework.util.EnumerationAdapter; import com.esri.gpt.framework.util.UuidUtil; import com.esri.gpt.framework.util.Val; import de.tudresden.gis.db.McpPublish; import de.tudresden.gis.manage.http.HttpHelperMethods; import de.tudresden.gis.manage.xml.Constant; import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.PrintWriter; import java.io.StringWriter; import java.io.UnsupportedEncodingException; import java.net.URI; import java.net.URLDecoder; import java.nio.charset.StandardCharsets; import java.nio.file.FileSystem; import java.nio.file.FileSystems; import java.nio.file.Files; import java.nio.file.InvalidPathException; import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.StandardCopyOption; import java.sql.SQLException; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; import javax.faces.context.FacesContext; import javax.servlet.ServletException; import javax.servlet.annotation.MultipartConfig; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.Part; import org.apache.commons.io.IOUtils; import org.n52.movingcode.runtime.codepackage.MovingCodePackage; /** * Provides an HTTP REST interface for the management of an XML based metadata document. * <p/> * The URL pattern for this end-point is:<br/> * <i>http://host:port/application/</i><b>rest/manage/document</b> * <p/> * Four HTTP methods are supported: * <ul> * <li>GET - gets an XML document from the catalog * <ul> * <li>the subject document must be specified within the URL</li> * <li>the XML is returned within the body of the HTTP response</li> * </ul> * <li>PUT - publishes an XML document to the catalog * <ul> * <li>the XML must be supplied within the body of the HTTP request.</li> * <li>URL parameter publicationMethod is accepted, values are upload,editor,other</li> * <li>URL parameter asDraft=true is accepted</li> * <li>if no document provided, that means this is resource registration request.</li> * <li>returns HTTP 200 when a document is replaced</li> * <li>returns HTTP 201 when a document is created</li> * </ul> * <li>POST - same as PUT</li> * <li>DELETE - deletes a document from the catalog * <ul> * <li>the subject document must be specified within the URL</li> * <li>returns HTTP 200 when a document is deleted</li> * </ul> * </ul> * The subject document can be specified within the URL as follows: * <ul> * <li>.../rest/manage/document/<b>identifier</b></li> * <li>.../rest/manage/document<b>?id=identifier</b></li> * <li><b>identifier</b> can be the catalog's UUID for the document, * or the file identifier internal to the XML document</li> * <li><b>identifier</b> must be properly URL encoded</li> * </ul> * Attributes applicable for resource registration: * <ul> * <li>url - resource URL (required)</li> * <li>uuid - UUID of the resource (optional). If provided this is an update of the already existing resource</li> * <li>name - resource name/title (optional)</li> * <li>protocol - protocol type (optional: res,arcgis,arcims,csw,oai,waf). Default: res</li> * <li>frequency - frequency (optional: Monthly, BiWeekly, Weekly, Dayly, Hourly, Once, Skip). Default: Skip</li> * <li>sendNotification - to send notification (optional: true,false). Default: false</li> * <li>updateContent - to harvest content during synchronization (optional: true,false). Default: true</li> * <li>updateDefinition - to update definition during synchronization (optional: true,false). Default: true</li> * <li>autoApprove - to automatically approve newly acquired metadata (optional: true,false). Default: true</li> * <li>findable - to make this resource findable when searching for metadata (optional: true, false), Default: true</li> * <li>searchable - to make this resource to act as distributed search endpoint (only if csw) (optional: true, false), Default: true</li> * <li>synchronizable - to make this resource synchronizable (optional: true, false), Default: true</li> * <li>username - user name required to access protected resource (optional)</li> * <li>password - password required to access protected resource (optional)</li> * <li>soapurl - (ARCGIS only) resource SOAP URL</li> * <li>profile - (CSW only) profile</li> * <li>set - (OAI only) set</li> * <li>prefix - (OAI only) prefix</li> * <li>service - (ARCIMS only) service</li> * <li>port - (ARCIMS only) port</li> * <li>rootFolder - (ARCIMS only) root folder</li> * </ul> * Exceptions applicable to all methods: * <ul> * <li>HTTP 401 Unauthorized * - indicates that valid credentials must be supplied to access this URL</li> * <li>HTTP 403 The document is owned by another user. * - when an attempt is made to access a document owned by another user</li> * </ul> * Exceptions applicable to GET/DETETE: * <ul> * <li>HTTP 404 Document not found.. * - when the document specified within the request URL could not be located * within the catalog</li> * </ul> * Exceptions applicable to PUT/POST: * <ul> * <li>HTTP 400 IOException while reading request body. * - when characters could not be read from the request body</li> * <li>HTTP 409 Document was empty. * - when the request body was empty</li> * <li>HTTP 409 Unable to parse document as XML. * - when the content of the request body cannot be parsed as XML</li> * <li>HTTP 409 Unrecognized metadata schema. * - when the supplied XML does not match a configured XML standard for the catalog</li> * <li>HTTP 409 Document failed to validate.. * - when the supplied XML is invalid with respect to the configured validation rules * for the catalog</li> * <li>HTTP 409 XSD violation. * - when the supplied XML is invalid with respect to it's XSD</li> * <li>HTTP 409 Duplicated resource URL. * - when registering new resource with URL as another already registered resource</li> * </ul> * */ @MultipartConfig public class ManageDocumentServlet extends BaseServlet { /** class variables ========================================================= */ /** The logger.*/ private static final Logger LOGGER = Logger.getLogger(ManageDocumentServlet.class.getName()); /** methods ================================================================= */ /** * Determines the source uri for a publication request. * @param request the servlet request * @param context the request context * @param publisher the publisher * @throws SQLException if an exception occurs while communicating with the database * @throws ServletException */ private void determineSourceUri(HttpServletRequest request, RequestContext context, PublicationRequest publicationRequest) throws SQLException, ServletException { String uuid = this.determineUuid(request, context, false); if ((uuid != null) && (uuid.length() > 0)) { publicationRequest.getPublicationRecord().setSourceFileName(uuid+".xml"); //sourceUri = uuid; } else { String pathInfo = Val.chkStr(request.getPathInfo()); String queryString = Val.chkStr(request.getQueryString()); if (pathInfo.startsWith("/")) pathInfo = pathInfo.substring(1); if (queryString.length() > 0) { pathInfo = pathInfo+"?"+queryString; } if (pathInfo.length() > 0) { //sourceUri = "userid:"+pubRequest.getPublisher().getLocalID()+"/"+pathInfo; } } } /** * Determines the specified document UIID from the HTTP request URL. * @param request the servlet request * @param context the request context * @param force if true, throw a ServletException if the document UUID is undetermined * @return the document UUID * @throws SQLException if an exception occurs while communicating with the database * @throws ServletException if the document UUID is undetermined (force=true only) */ private String determineUuid(HttpServletRequest request, RequestContext context, boolean force) throws SQLException, ServletException { String uuid = ""; String id = Val.chkStr(request.getParameter("id")); if (id.length() == 0) { String tmp = Val.chkStr(request.getPathInfo()).replaceAll("^/", ""); try { id = Val.chkStr(URLDecoder.decode(tmp,"UTF-8")); } catch (UnsupportedEncodingException e) { // will never happen } } // determine the document uuid (the supplied id could be a gpt uuid or file identifier) if (id.length() > 0) { ImsMetadataAdminDao dao = new ImsMetadataAdminDao(context); uuid = dao.findUuid(id); if (!force && ((uuid == null) || (uuid.length() == 0))) { String tmpId = UuidUtil.addCurlies(id); if (tmpId.length() == 38) { uuid = tmpId; } } } // throw an exception if the document uuid was not located if (force && ((uuid == null) || (uuid.length() == 0))) { throw new ServletException("404: Document not found."); } return uuid; } /** * Deletes a document from the catalog. * <br/>An HTTP 200 response code is set when a document is successfully deleted. * @param request the servlet request * @param response the servlet response * @throws ServletException if the request cannot be handled * @throws IOException if an I/O error occurs while handling the request */ @Override protected void doDelete(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.execute(request,response,"DELETE"); } /** * Gets an XML document from the catalog. * <br/>The XML is returned within the body of the HTTP response. * @param request the servlet request * @param response the servlet response * @throws ServletException if the request cannot be handled * @throws IOException if an I/O error occurs while handling the request */ @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.execute(request,response,"GET"); } /** * Handles a POST request. * <br/>Same as doPut(). * @param request the servlet request * @param response the servlet response * @throws ServletException if the request cannot be handled * @throws IOException if an I/O error occurs while handling the request */ @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.execute(request,response,"POST"); } /** * Publishes an XML document to the catalog. * <br/>The XML must be supplied within the body of the HTTP request. * <br/>An HTTP 200 response code is set when a document is successfully replaced. * <br/>An HTTP 201 response code is set when a document is successfully created. * @param request the servlet request * @param response the servlet response * @throws ServletException if the request cannot be handled * @throws IOException if an I/O error occurs while handling the request */ @Override protected void doPut(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.execute(request,response,"PUT"); } /** * Provides a concrete executeUpdate() method to fulfill the sub-class requirement of the parent * BaseServlet class. * This method is never invoked, all work is handled through * doGet(), doPut(), doPost() and doDelete(). */ @Override protected void execute(HttpServletRequest request, HttpServletResponse response, RequestContext context) throws Exception { } /** * Processes the HTTP request. * @param request the HTTP request * @param response HTTP response * @param context request context * @param method the method to executeUpdate GET|PUT|POST|DELETE * @throws ServletException if the request cannot be handled * @throws IOException if an I/O error occurs while handling the request */ private void execute(HttpServletRequest request, HttpServletResponse response, String method) throws ServletException, IOException { RequestContext context = null; try { String msg = "HTTP "+method+", "+request.getRequestURL().toString(); if ((request.getQueryString() != null) && (request.getQueryString().length() > 0)) { msg += "?"+request.getQueryString(); } getLogger().fine(msg); String sEncoding = request.getCharacterEncoding(); if ((sEncoding == null) || (sEncoding.trim().length() == 0)) { request.setCharacterEncoding("UTF-8"); } context = RequestContext.extract(request); //redirect to new method for list parameter without any authentication if (method.equals("GET") && request.getParameter("list")!=null) { this.executeGetList(request,response,context); return; } if (method.equals("GET") && request.getParameter("download")!=null) { this.executeGetPackage(request,response,context); return; } /// estabish the publisher StringAttributeMap params = context.getCatalogConfiguration().getParameters(); String autoAuthenticate = Val.chkStr(params.getValue("BaseServlet.autoAuthenticate")); if (!autoAuthenticate.equalsIgnoreCase("false")) { Credentials credentials = getCredentials(request); if (credentials != null) { this.authenticate(context,credentials); } } Publisher publisher = new Publisher(context); // executeUpdate the appropriate action if (method.equals("GET")) { this.executeGet(request,response,context,publisher); } else if (method.equals("POST")) { this.executePost(request,response,context,publisher); } else if (method.equals("PUT")) { this.executePut(request,response,context,publisher); } else if (method.equals("DELETE")) { this.executeDelete(request,response,context,publisher); } } catch (CredentialsDeniedException e) { String sRealm = this.getRealm(context); response.setHeader("WWW-Authenticate","Basic realm=\""+sRealm+"\""); response.sendError(HttpServletResponse.SC_UNAUTHORIZED); } catch (NotAuthorizedException e) { String sRealm = this.getRealm(context); response.setHeader("WWW-Authenticate","Basic realm=\""+sRealm+"\""); response.sendError(HttpServletResponse.SC_UNAUTHORIZED); } catch (ValidationException e) { String sMsg = e.toString(); if (sMsg.contains("XSD violation.")) { sMsg = "XSD violation."; } else if (sMsg.contains("Invalid metadata document.")) { sMsg = "Invalid metadata document."; } else { sMsg = "Invalid metadata document."; } String json = Val.chkStr(request.getParameter("errorsAsJson")); if (json.length()>0) { json = Val.escapeXmlForBrowser(json); FacesContextBroker fcb = new FacesContextBroker(request, response); MessageBroker msgBroker = fcb.extractMessageBroker(); ArrayList<String> validationMessages = new ArrayList<String>(); e.getValidationErrors().buildMessages(msgBroker, validationMessages, true); StringBuilder sb = new StringBuilder(); sb.append(json).append(" = {\r\n"); sb.append("message: \"").append(Val.escapeStrForJson(sMsg)).append("\",\r\n"); sb.append("code: 409,\r\n"); sb.append("errors: [\r\n"); for (int i=0; i<validationMessages.size(); i++) { if (i>0) { sb.append(",\r\n"); } sb.append("\"").append(Val.escapeStrForJson(validationMessages.get(i))).append("\""); } if (validationMessages.size()>0) { sb.append("\r\n"); } sb.append("]}"); LOGGER.log(Level.SEVERE, sb.toString()); response.getWriter().print(sb.toString()); } else { response.sendError(409,sMsg); } } catch (ServletException e) { String sMsg = e.getMessage(); int nCode = Val.chkInt(sMsg.substring(0,3),500); sMsg = Val.chkStr(sMsg.substring(4)); String json = Val.chkStr(request.getParameter("errorsAsJson")); if (json.length()>0) { json = Val.escapeXmlForBrowser(json); StringBuilder sb = new StringBuilder(); sb.append(json).append(" = {\r\n"); sb.append("message: \"").append(Val.escapeStrForJson(sMsg)).append("\",\r\n"); sb.append("code: ").append(nCode).append(",\r\n"); sb.append("errors: [\r\n"); sb.append("\"").append(Val.escapeStrForJson(sMsg)).append("\""); sb.append("]}"); LOGGER.log(Level.SEVERE, sb.toString()); response.getWriter().print(sb.toString()); } else { response.sendError(nCode,sMsg); } } catch (Throwable t) { String sMsg = t.toString(); String json = Val.chkStr(request.getParameter("errorsAsJson")); if (json.length()>0) { json = Val.escapeXmlForBrowser(json); StringBuilder sb = new StringBuilder(); sb.append(json).append(" = {\r\n"); sb.append("message: \"").append(Val.escapeStrForJson(sMsg)).append("\",\r\n"); sb.append("code: ").append(500).append(",\r\n"); sb.append("errors: [\r\n"); sb.append("\"").append(Val.escapeStrForJson(sMsg)).append("\""); sb.append("]}"); LOGGER.log(Level.SEVERE, sb.toString()); response.getWriter().print(sb.toString()); } else if (sMsg.contains("The document is owned by another user:")) { response.sendError(HttpServletResponse.SC_FORBIDDEN,"The document is owned by another user."); } else { //String sErr = "Exception occured while processing servlet request."; //getLogger().log(Level.SEVERE,sErr,t); //response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, // sMsg + sErr); } } finally { if (context != null) context.onExecutionPhaseCompleted(); } } /** * Deletes the metadata document specified within the URL. * @param request the servlet request * @param response the servlet response * @param context the request context * @param publisher the publisher * @throws Exception if an exception occurs */ private void executeDelete(HttpServletRequest request, HttpServletResponse response, RequestContext context, Publisher publisher) throws Exception { String uuid = this.determineUuid(request,context,true); MmdActionCriteria actionCriteria = new MmdActionCriteria(); actionCriteria.setActionKey("delete"); actionCriteria.getSelectedRecordIdSet().add(uuid); MmdResult result = new MmdResult(); MmdCriteria criteria = new MmdCriteria(); criteria.setActionCriteria(actionCriteria); MmdActionRequest actionRequest = new MmdActionRequest(context,publisher,criteria,result); actionRequest.execute(); LOGGER.finer(result.getActionResult().getNumberOfRecordsModified()+" document(s) deleted."); } /** * Gets the XML string associated with the metadata document specified within the URL. * @param request the servlet request * @param response the servlet response * @param context the request context * @param publisher the publisher * @throws Exception if an exception occurs */ private void executeGet(HttpServletRequest request, HttpServletResponse response, RequestContext context, Publisher publisher) throws Exception { String uuid = this.determineUuid(request,context,true); MetadataDocument mdDoc = new MetadataDocument(); String xml = Val.chkStr(mdDoc.prepareForDownload(context,publisher,uuid)); if (xml.length() > 0) { this.writeXmlResponse(response,xml); } } /** * Publishes the XML metadata document supplied within the request body. * <br/>this method is a pass-turu to executePut(). * @param request the servlet request * @param response the servlet response * @param context the request context * @param publisher the publisher * @throws Exception if an exception occurs */ private void executePost(HttpServletRequest request, HttpServletResponse response, RequestContext context, Publisher publisher) throws Exception { this.executePut(request,response,context,publisher); } /** * Publishes the XML metadata document supplied within the request body. * @param request the servlet request * @param response the servlet response * @param context the request context * @param publisher the publisher * @throws Exception if an exception occurs */ private void executePut(HttpServletRequest request, HttpServletResponse response, RequestContext context, Publisher publisher) throws Exception { String xml = null; HrRecord record = extractRegistrationInfo(request); //get multipart request for xml creating + upload try{ //create mode - xml and zip are sended via parts if (request.getParts().size()>0){ createAndUpload(request, response, context, publisher); return; } } catch (Exception e){ } //else normal - edit mode (no parts, no zip file - only xml change) if (record==null) { try { xml = this.readInputCharacters(request); } catch (IOException e) { throw new ServletException("400: IOException while reading request body."); } xml = Val.chkStr(Val.removeBOM(xml)); if (xml.length() > 0) { PublicationRequest pubRequest = new PublicationRequest(context,publisher,xml); PublicationRecord pubRecord = pubRequest.getPublicationRecord(); pubRecord.setPublicationMethod(MmdEnums.PublicationMethod.upload.toString()); String pubMethod = Val.chkStr(request.getParameter("publicationMethod")); if (pubMethod.length() > 0) { try { pubMethod = MmdEnums.PublicationMethod.valueOf(Val.chkStr(pubMethod)).toString(); pubRecord.setPublicationMethod(pubMethod); } catch (IllegalArgumentException ex) { } } String asDraft = Val.chkStr(request.getParameter("asDraft")); if (asDraft.equals("true")) { pubRecord.setApprovalStatus(MmdEnums.ApprovalStatus.draft.toString()); } this.determineSourceUri(request,context,pubRequest); try { pubRequest.publish(); //SAVE XML TO ZIP ARCHIVE saveXml2Package(xml,pubRecord.getUuid()); if (!pubRecord.getWasDocumentReplaced()) { response.setStatus(HttpServletResponse.SC_CREATED); } //Validation error triggert via pubRequest.publish /ValidationRequest } catch (ValidationException e) { String sMsg = e.toString(); if (sMsg.contains("XSD violation.")) { throw new ServletException("409: XSD violation."); } else if (sMsg.contains("Invalid metadata document.")) { throw new ServletException("409: Document failed to validate."); } else { throw new ServletException("409: Document failed to validate."); } } catch (SchemaException e) { String sMsg = e.toString(); if (sMsg.contains("Unrecognized metadata schema.")) { throw new ServletException("409: Unrecognized metadata schema."); } else if (sMsg.contains("Unable to parse document.")) { throw new ServletException("409: Unable to parse document as XML."); } else { throw e; } } } else { throw new ServletException("409: Document was empty."); } } else { try { HrCompleteUpdateRequest req = new HrCompleteUpdateRequest(context, record); req.execute(); response.setStatus(HttpServletResponse.SC_CREATED); } catch (HrAssertUrlException e) { throw new ServletException("409: Duplicated resource URL."); } catch (ValidationException e) { String sMsg = e.toString(); if (sMsg.contains("XSD violation.")) { throw new ServletException("409: XSD violation."); } else if (sMsg.contains("Invalid metadata document.")) { throw new ServletException("409: Document failed to validate."); } else { throw new ServletException("409: Document failed to validate."); } } catch (SchemaException e) { String sMsg = e.toString(); if (sMsg.contains("Unrecognized metadata schema.")) { throw new ServletException("409: Unrecognized metadata schema."); } else if (sMsg.contains("Unable to parse document.")) { throw new ServletException("409: Unable to parse document as XML."); } else { throw e; } } catch (Exception ex) { throw new ServletException("409: Unable to register resource."); } } } /** * Extracts registration info. * @param request HTTP request * @return registration info or <code>null</code> if unable to extract registration info */ private HrRecord extractRegistrationInfo(HttpServletRequest request) { ApplicationContext appCtx = ApplicationContext.getInstance(); ApplicationConfiguration appCfg = appCtx.getConfiguration(); HrRecord record = new HrRecord(); StringAttributeMap attributes = new StringAttributeMap(); boolean updateContent = true; boolean updateDefinition = true; boolean autoApprove = true; for (String paramName : new EnumerationAdapter<String>(request.getParameterNames())) { String paramValue = request.getParameter(paramName); if (paramName.equalsIgnoreCase("uuid")) { record.setUuid(paramValue); } if (paramName.equalsIgnoreCase("name")) { record.setName(paramValue); } else if (paramName.equalsIgnoreCase("url")) { record.setHostUrl(paramValue); } else if (paramName.equalsIgnoreCase("soapurl")) { attributes.add(new StringAttribute(ArcGISProtocol.SOAP_URL,paramValue)); } else if (paramName.equalsIgnoreCase("protocol")) { ProtocolFactory factory = appCfg.getProtocolFactories().get(paramValue); if (factory!=null) { record.setProtocol(factory.newProtocol()); } } else if (paramName.equalsIgnoreCase("frequency")) { record.setHarvestFrequency(HarvestFrequency.checkValueOf(paramValue)); } else if (paramName.equalsIgnoreCase("sendNotification")) { record.setSendNotification(Val.chkBool(paramValue, false)); } else if (paramName.equalsIgnoreCase("updateContent")) { updateContent = Val.chkBool(paramValue, true); } else if (paramName.equalsIgnoreCase("updateDefinition")) { updateDefinition = Val.chkBool(paramValue, true); } else if (paramName.equalsIgnoreCase("autoApprove")) { autoApprove = Val.chkBool(paramValue, true); } else if (paramName.equalsIgnoreCase("findable")) { record.setFindable(Val.chkBool(paramValue, true)); } else if (paramName.equalsIgnoreCase("searchable")) { record.setSearchable(Val.chkBool(paramValue, true)); } else if (paramName.equalsIgnoreCase("synchronizable")) { record.setSynchronizable(Val.chkBool(paramValue, true)); } else { attributes.add(new StringAttribute(paramName,paramValue)); } } if (record.getProtocol()==null || record.getProtocol().getKind().equalsIgnoreCase(ProtocolType.None.name())) { ProtocolFactory factory = appCfg.getProtocolFactories().get(ProtocolType.RES.name()); if (factory!=null) { record.setProtocol(factory.newProtocol()); } } if (record.getProtocol()!=null) { record.getProtocol().setAttributeMap(attributes); ProtocolInvoker.setUpdateDefinition(record.getProtocol(), updateDefinition); ProtocolInvoker.setUpdateContent(record.getProtocol(), updateContent); ProtocolInvoker.setAutoApprove(record.getProtocol(), autoApprove); } record = record.getName().length()>0 && record.getHostUrl().length()>0 && record.getProtocol()!=null? record: null; return record; } private boolean saveXml2Package(String xml, String uuid) throws IOException{ uuid = UuidUtil.removeCurlies(uuid); //xml file String folder = Constant.UPLOAD_FOLDER ; File temp = new File(folder + File.separator + uuid + File.separator + Constant.XML_OUTPUT_FILE_NAME); InputStream in = new ByteArrayInputStream(xml.getBytes(StandardCharsets.UTF_8)); //InputStream in = doc.newInputStream(); Path a = temp.toPath(); Files.copy(in, a, java.nio.file.StandardCopyOption.REPLACE_EXISTING); //copy xml file into zip file Map<String, String> env = new HashMap<>(); env.put("create", "true"); Path path = null; path = Paths.get(folder + File.separator + uuid + File.separator + Constant.XML_OUTPUT_ZIP_NAME); URI uri = URI.create("jar:" + path.toUri()); try (FileSystem fs = FileSystems.newFileSystem(uri, env)) { Files.copy( Paths.get(folder + File.separator + uuid + File.separator + Constant.XML_OUTPUT_FILE_NAME), fs.getPath(Constant.XML_OUTPUT_FILE_NAME), StandardCopyOption.REPLACE_EXISTING ); } return true; } private void createAndUpload(HttpServletRequest request, HttpServletResponse response, RequestContext context, Publisher publisher) throws IOException, IllegalStateException, ServletException, SchemaException, CatalogIndexException, ImsServiceException, SQLException, NotAuthorizedException, IdentityException{ //XML InputStream xmlStream = request.getPart("xml").getInputStream(); String xml = IOUtils.toString(xmlStream, "UTF-8"); xml = Val.chkStr(Val.removeBOM(xml)); //read file OutputStream out = null; InputStream filecontent = request.getPart("file").getInputStream(); //ID InputStream idStream = request.getPart("id").getInputStream(); String id = IOUtils.toString(idStream, "UTF-8"); /**Collection<Part> x = request.getParts(); Part[] array = x.toArray (new Part[x.size ()]); for(int f=0; f<array.length;f++){ System.out.println(array[f].getName() + " " + array[f].getSize()); }*/ //verify - throw servlet exception ValidationRequest vRequest = new ValidationRequest(context, "id", xml); // in case of schema problems verify method would throw exception try{ vRequest.verify(); }catch(ValidationException e){ System.out.println("valid error: "+e); throw new ServletException("409: Document failed to validate."); } //Save Zip file String webDataPath = Constant.UPLOAD_FOLDER, folder =id; new File(webDataPath + File.separator + folder).mkdir(); try { //initiate output stream out = new FileOutputStream( new File(webDataPath + File.separator + folder + File.separator + Constant.XML_OUTPUT_ZIP_NAME) ); int read = 0; final byte[] bytes = new byte[1024]; while ((read = filecontent.read(bytes)) != -1) { out.write(bytes, 0, read); } } finally { //close all open streams if necessary if (out != null) { out.close(); } if (filecontent != null) { filecontent.close(); } } //save xml in mcp saveXml2Package(xml,id); //save xml in db if (xml.length() > 0) { //PublicationRequest pubRequest = new PublicationRequest(context,publisher,xml); //PublicationRecord pubRecord = pubRequest.getPublicationRecord(); //pubRecord.setPublicationMethod("editor"); //pubRequest.publish(); MovingCodePackage mvp = new MovingCodePackage(new File(webDataPath + File.separator + folder + File.separator + Constant.XML_OUTPUT_ZIP_NAME)); McpPublish mcpP = new McpPublish(mvp, webDataPath + File.separator + folder + File.separator + Constant.XML_OUTPUT_ZIP_NAME, id, context ); if(mcpP.publish(false))System.out.println("publishing successfully"); } response.setStatus(HttpServletResponse.SC_CREATED); } private void executeGetList(HttpServletRequest request, HttpServletResponse response, RequestContext context) throws Exception { String list = request.getParameter("list"); int count = 3; if (request.getParameter("count")!=null){ count = Integer.parseInt(request.getParameter("count")); } if (list.equals("recent")){ String json = HttpHelperMethods.getRecent(count); response.setContentType("application/json"); PrintWriter out = response.getWriter(); out.print(json); out.flush(); } if (list.equals("top")){ String json = HttpHelperMethods.getTopRated(count); response.setContentType("application/json"); PrintWriter out = response.getWriter(); out.print(json); out.flush(); } if (list.contains("id:")){ String json = HttpHelperMethods.getEntryWithID(list.replace("id:", "")); response.setContentType("application/json"); PrintWriter out = response.getWriter(); out.print(json); out.flush(); } } private void executeGetPackage(HttpServletRequest request, HttpServletResponse response, RequestContext context) throws Exception { String id = request.getParameter("download"); String value = UuidUtil.removeCurlies(id); String path = Constant.UPLOAD_FOLDER + File.separator + value + File.separator + Constant.XML_OUTPUT_ZIP_NAME; File file = new File(path); InputStream fis = new FileInputStream(file); //HttpServletResponse response = // (HttpServletResponse) FacesContext.getCurrentInstance() // .getExternalContext().getResponse(); response.setContentType("application/zip"); response.setHeader("Content-Disposition", "attachment;filename=package.zip"); OutputStream responseOutput = response.getOutputStream(); byte[] buf = new byte[2048]; int bytesRead; while ((bytesRead = fis.read(buf)) > 0) { responseOutput.write(buf, 0, bytesRead); } responseOutput.flush(); fis.close(); responseOutput.close(); FacesContext.getCurrentInstance().responseComplete(); } }