http://git-wip-us.apache.org/repos/asf/oodt/blob/a47b088a/curator2/src/main/java/org/apache/oodt/cas/curation/service/CurationServiceConfig.java ---------------------------------------------------------------------- diff --git a/curator2/src/main/java/org/apache/oodt/cas/curation/service/CurationServiceConfig.java b/curator2/src/main/java/org/apache/oodt/cas/curation/service/CurationServiceConfig.java new file mode 100644 index 0000000..dc497ed --- /dev/null +++ b/curator2/src/main/java/org/apache/oodt/cas/curation/service/CurationServiceConfig.java @@ -0,0 +1,227 @@ +/* + * 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.oodt.cas.curation.service; + +//OODT imports +import org.apache.oodt.cas.curation.servlet.CuratorConfMetKeys; +import org.apache.oodt.cas.filemgr.datatransfer.DataTransferFactory; +import org.apache.oodt.cas.filemgr.system.XmlRpcFileManagerClient; +import org.apache.oodt.cas.metadata.util.PathUtils; + +//JDK imports +import java.net.URL; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Map; +import java.util.logging.Level; +import java.util.logging.Logger; +import javax.servlet.ServletConfig; +import javax.servlet.ServletContext; + +/** + * + * + * Configures the {@link CurationService} by reading the parameters out of the + * <code>context.xml</code> file, doing a + * {@link PathUtils#replaceEnvVariables(String)} on each property in the + * context.xml. This allows you to specify environment variables using the + * traditional CAS syntax of: + * + * <pre> + * [VAR_NAME], e.g., [CAS_CURATOR_HOME]/some/other/path + * </pre> + * + * The configuration parameters are read once upon loading the instance of this + * object. + * + * @author pramirez + * @author mattmann + * @version $Revision$ + * + */ +public class CurationServiceConfig implements CuratorConfMetKeys { + private static CurationServiceConfig instance; + + private final Map<String, String> parameters = new HashMap<String, String>(); + + private XmlRpcFileManagerClient fmClient = null; + + private static final Logger LOG = Logger + .getLogger(CurationServiceConfig.class.getName()); + + /** + * Gets a singleton static instance of the global + * {@link CurationServiceConfig} for the CAS Curator Webapp. + * + * @param conf + * The {@link ServletConfig} read on startup of the webapp. This is + * typically specified in a <code>context.xml</code> file, but can + * also be specified in <code>web.xml</code>. + * @return A singleton instance of the global {@link link + * CurationServiceConfig}. + * @throws InstantiationException + * If there is any error constructing the config. + */ + public static CurationServiceConfig getInstance(ServletConfig conf) { + if (instance == null) { + instance = new CurationServiceConfig(conf); + } + return instance; + } + + /** + * + * @return The metadata output file path. + */ + public String getMetAreaPath() { + return this.evaluateParameter(MET_AREA_PATH); + } + + /** + * + * @return The extension of metadata files that will be generated and consumed + * by CAS curator. + */ + public String getMetExtension() { + return this.evaluateParameter(MET_EXTENSION); + } + + /** + * + * @return The path to the staging area where the CAS curator is ingesting + * files from. + */ + public String getStagingAreaPath() { + return this.evaluateParameter(STAGING_AREA_PATH); + } + + /** + * + * @return A {@link String} representation of the CAS File Manager {@link URL} + * . + */ + public String getFileMgrURL() { + return this.evaluateParameter(FM_URL); + } + + /** + * + * @return The full {@link XmlRpcFileManagerClient} built from the CAS curator + * property <code>filemgr.url</code>. + */ + public XmlRpcFileManagerClient getFileManagerClient() { + try { + return new XmlRpcFileManagerClient(new URL(this.getFileMgrURL())); + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + + /** + * + * @return The java class name (fully-qualified) of the CAS SSO security + * implementation. + */ + public String getSSOImplClass() { + return this.evaluateParameter(SSO_IMPL_CLASS); + } + + /** + * + * @return The display name of the project. + */ + public String getProjectDisplayName() { + return this.evaluateParameter(PROJECT_DISPLAY_NAME); + } + + /** + * + * @return The upload path for metadata extractor config files. + */ + public String getMetExtrConfUploadPath() { + return this.evaluateParameter(MET_EXTRACTOR_CONF_UPLOAD_PATH); + } + + /** + * + * @return The path to the crawler config file. + */ + public String getCrawlerConfFile() { + return this.evaluateParameter(CRAWLER_CONF_FILE); + } + + /** + * + * @return The path to the location where policy directories should be + * uploaded to. + */ + public String getPolicyUploadPath() { + return this.evaluateParameter(POLICY_UPLOAD_PATH); + } + + /** + * + * @return The default CAS File Manager {@link DataTransferFactory} classname. + */ + public String getDefaultTransferFactory() { + return this.evaluateParameter(DEFAULT_TRANSFER_FACTORY); + } + + /** + * Gets a property from the CAS Curator config without calling + * {@link PathUtils#replaceEnvVariables(String)}. + * + * @param name + * The name of the parameter to return. + * @return The un-evaluated property value from the config. + */ + public String getParameter(String name) { + return this.parameters.get(name); + } + + public String getFileMgrProps() { + return this.evaluateParameter(FM_PROPS); + } + + private String evaluateParameter(String name) { + return PathUtils.replaceEnvVariables(this.parameters.get(name)); + } + + // Note that the constructor is private + private CurationServiceConfig(ServletConfig conf) { + readContextParams(conf.getServletContext()); + try { + fmClient = new XmlRpcFileManagerClient(new URL(this.getFileMgrURL())); + } catch (Exception e) { + e.printStackTrace(); + LOG.log(Level.WARNING, "Unable to build CurationServiceConfig: Message: " + e.getMessage()); + } + } + + @SuppressWarnings("unchecked") + private void readContextParams(ServletContext context) { + for (Enumeration<String> names = context.getInitParameterNames(); names + .hasMoreElements();) { + String name = names.nextElement(); + parameters.put(name, context.getInitParameter(name)); + } + LOG.log(Level.INFO, "Init Parameters: " + parameters); + } +}
http://git-wip-us.apache.org/repos/asf/oodt/blob/a47b088a/curator2/src/main/java/org/apache/oodt/cas/curation/service/DirectoryResource.java ---------------------------------------------------------------------- diff --git a/curator2/src/main/java/org/apache/oodt/cas/curation/service/DirectoryResource.java b/curator2/src/main/java/org/apache/oodt/cas/curation/service/DirectoryResource.java new file mode 100644 index 0000000..2700a69 --- /dev/null +++ b/curator2/src/main/java/org/apache/oodt/cas/curation/service/DirectoryResource.java @@ -0,0 +1,138 @@ +/* + * 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.oodt.cas.curation.service; + +//JDK imports +import java.io.File; +import java.util.logging.Level; +import java.util.logging.Logger; + +//JAX-RS imports +import javax.ws.rs.DefaultValue; +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.UriInfo; + + + +@Path("directory") +/** + * + * A web service endpoint to a service providing views of the staging area, the + * archive area, and the met output area. + * + * @author pramirez + * @version $Id$ + */ +public class DirectoryResource extends CurationService { + private static final Logger LOG = Logger.getLogger(DirectoryResource.class + .getName()); + + @Context + UriInfo uriInfo; + + private static final long serialVersionUID = 715126227357637464L; + + @GET + @Path("staging") + @Produces("text/plain") + public String showStagingArea( + @DefaultValue("/") @QueryParam("path") String path, + @DefaultValue("true") @QueryParam("showFiles") boolean showFiles, + @DefaultValue(FORMAT_HTML) @QueryParam("format") String format) { + if (FORMAT_HTML.equals(format)) { + String response = this.getDirectoryAreaAsHTML(CurationService.config + .getStagingAreaPath(), path, showFiles); + return response; + } + return this.getDirectoryAreaAsJSON(CurationService.config + .getStagingAreaPath(), path, showFiles); + } + + @GET + @Path("metadata") + @Produces("text/plain") + public String showMetArea(@DefaultValue("/") @QueryParam("path") String path, + @DefaultValue("true") @QueryParam("showFiles") boolean showFiles) { + return this.getDirectoryAreaAsJSON(CurationService.config.getMetAreaPath(), + path, showFiles); + } + + @GET + @Path("catalog") + @Produces("text/plain") + public String showArchiveArea(@QueryParam("policy") String policy, + @QueryParam("productType") String productType, + @DefaultValue("20") @QueryParam("num") int numberOfResults, + @DefaultValue("0") @QueryParam("start") int start) { + + // Figure out where the product type root path is and display contents + return productType; + } + + + public String getDirectoryAreaAsHTML(String base, String path, + boolean showFiles) { + StringBuffer html = new StringBuffer(); + String relativePath = null; + try { + relativePath = this.cleansePath(path); + } catch (Exception e) { + e.printStackTrace(); + LOG.log(Level.WARNING, "Error decoding path: [" + path + "]: Message: " + + e.getMessage()); + return html.toString(); + } + + String startingPath = (base + "/" + relativePath); + String f[] = this.getFilesInDirectory(startingPath, showFiles); + + html.append("<ul class=\"fileTree\">\r\n"); + // Loop through and list directories first. Nicer for UI to get these first + for (int i = 0; i < f.length; i++) { + if (new File(startingPath + "/" + f[i]).isDirectory()) { + html.append(" <li class=\"directory collapsed\">"); + html.append("<a href=\"#\" rel=\"").append(relativePath).append("/") + .append(f[i]).append("\">").append(f[i]).append("</a>"); + html.append("</li>\r\n"); + } + } + // If we are showing files now loop through and show files + if (showFiles) { + for (int i = 0; i < f.length; i++) { + if (new File(startingPath + "/" + f[i]).isFile()) { + String filename = new File(startingPath + "/" + f[i]).getName(); + String ext = filename.substring(filename.lastIndexOf('.') + 1); + html.append(" <li class=\"file draggy ext_").append(ext) + .append("\">"); + html.append("<a href=\"#\" rel=\"").append(relativePath).append("/") + .append(f[i]).append("\">").append(f[i]).append("</a>"); + html.append("</li>\r\n"); + } + } + } + html.append("</ul>"); + + return html.toString(); + } + +} http://git-wip-us.apache.org/repos/asf/oodt/blob/a47b088a/curator2/src/main/java/org/apache/oodt/cas/curation/service/IngestionResource.java ---------------------------------------------------------------------- diff --git a/curator2/src/main/java/org/apache/oodt/cas/curation/service/IngestionResource.java b/curator2/src/main/java/org/apache/oodt/cas/curation/service/IngestionResource.java new file mode 100644 index 0000000..2ea61bb --- /dev/null +++ b/curator2/src/main/java/org/apache/oodt/cas/curation/service/IngestionResource.java @@ -0,0 +1,352 @@ +/* + * 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.oodt.cas.curation.service; + +//OODT imports +import org.apache.oodt.cas.curation.structs.IngestionTask; +import org.apache.oodt.cas.curation.util.DateUtils; +import org.apache.oodt.cas.curation.util.ExtractorConfigReader; +import org.apache.oodt.cas.filemgr.ingest.Ingester; +import org.apache.oodt.cas.filemgr.ingest.StdIngester; +import org.apache.oodt.cas.filemgr.structs.exceptions.IngestException; +import org.apache.oodt.cas.metadata.Metadata; + +//JDK imports +import java.io.File; +import java.net.URL; +import java.util.Arrays; +import java.util.Collections; +import java.util.Comparator; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.UUID; +import java.util.Vector; +import java.util.logging.Level; +import java.util.logging.Logger; + +//JAX-RS imports +import javax.ws.rs.DefaultValue; +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.UriInfo; + +//JSON imports +import net.sf.json.JSONObject; + +/** + * + * Leverages CAS {@link Ingester} interface to ingest Products into the CAS File + * Manager via CAS Curator and a REST-ful interface. + * + * @author mattmann + * @version $Revision$ + * + */ +@Path("ingest") +public class IngestionResource extends CurationService { + + private static final long serialVersionUID = -7514150767897700936L; + + private static final Logger LOG = Logger.getLogger(IngestionResource.class + .getName()); + + private static final String DATA_TRANSFER_SERVICE = "org.apache.oodt.cas.filemgr.datatransfer.LocalDataTransferFactory"; + + private static final String RESP_SUCCESS = "success"; + + private IngestionTaskList taskList; + + public IngestionResource() { + super(); + this.taskList = new IngestionTaskList(); + IngestionTask task = new IngestionTask(); + task.setCreateDate(new Date()); + + } + + @Context + UriInfo uriInfo; + + @GET + @Path("create") + @Produces("text/plain") + public String createTask(@QueryParam("files") String fileList, + @QueryParam("numfiles") Integer numFiles, + @QueryParam("metExtCfgId") String metExtractorConfigId, + @QueryParam("policy") String policy, + @QueryParam("ptype") String productType) { + + IngestionTask newTask = new IngestionTask(); + newTask.setCreateDate(new Date()); + try { + newTask.setExtConf(ExtractorConfigReader.readFromDirectory(new File( + CurationService.config.getMetExtrConfUploadPath()), + metExtractorConfigId)); + } catch (Exception e) { + e.printStackTrace(); + String errorMsg = "Unable to load extractor config from metExtCfgId: [" + + metExtractorConfigId + "]"; + LOG.log(Level.WARNING, errorMsg); + return errorMsg; + } + newTask.setFileList(deducePaths(Arrays.asList(fileList.split(",")))); + newTask.setPolicy(policy); + newTask.setProductType(productType); + newTask.setStatus(IngestionTask.NOT_STARTED); + return this.taskList.addIngestionTask(newTask); + } + + @GET + @Path("remove") + @Produces("text/plain") + public void removeTask(@QueryParam("taskId") String ingestTaskId) { + this.taskList.removeIngestionTask(ingestTaskId); + } + + @GET + @Path("list") + @Produces("text/plain") + public String getIngestTaskList( + @QueryParam("format") @DefaultValue(FORMAT_HTML) String format) { + if (format.equals(FORMAT_HTML)) { + return this.encodeTaskListAsHTML(this.taskList.getTaskList()); + } else if (format.equals(FORMAT_JSON)) { + return this.encodeTaskListAsJSON(this.taskList.getTaskList()); + } else { + return "Unsupported Format!"; + } + } + + @GET + @Path("start") + @Produces("text/plain") + public String doIngest(@QueryParam("taskId") String ingestTaskId) { + IngestionTask task = this.taskList.getIngestionTaskById(ingestTaskId); + if (task == null) { + String errorMsg = "Task with ID [" + ingestTaskId + + "] is not being managed by this Ingestion Resource!"; + LOG.log(Level.WARNING, errorMsg); + return this.encodeIngestResponseAsJSON(false, errorMsg); + } + + Ingester ingest = this.configureIngester(); + MetadataResource metService = new MetadataResource(); + for (String file : task.getFileList()) { + Metadata fileMet = null; + try { + String vFilePath = this.getVirtualPath(CurationService.config + .getStagingAreaPath(), file); + LOG.log(Level.FINE, + "IngestionResource: getting staging metadata for virtual path: [" + + vFilePath + "]"); + fileMet = metService.getStagingMetadata(vFilePath, task.getExtConf() + .getIdentifier(), false); + } catch (Exception e) { + e.printStackTrace(); + return this.encodeIngestResponseAsHTML(false, e.getMessage()); + } + + try { + ingest.ingest(safeGetUrl(CurationService.config.getFileMgrURL()), + new File(file), fileMet); + } catch (IngestException e) { + e.printStackTrace(); + return this.encodeIngestResponseAsHTML(false, e.getMessage()); + } + + // set task status to success + task.setStatus(IngestionTask.FINISHED); + } + + return this.encodeIngestResponseAsHTML(true, null); + } + + private String encodeTaskListAsHTML(List<IngestionTask> taskList) { + StringBuffer out = new StringBuffer(); + + for (IngestionTask task : taskList) { + out.append("<tr>"); + out.append("<td>"); + out.append(task.getId()); + out.append("</td><td>"); + out.append(DateUtils.getDateAsISO8601String(task.getCreateDate())); + out.append("</td><td>"); + out.append(task.getFileList().size()); + out.append("</td><td>"); + out.append(task.getPolicy()); + out.append("</td><td>"); + out.append(task.getProductType()); + out.append("</td><td>"); + out.append(task.getExtConf().getIdentifier()); + out.append("</td><td>"); + out.append(task.getExtConf().getConfigFiles().size()); + out.append("</td><td id='"); + out.append(task.getId()); + out.append("_Status'>"); + out.append(task.getStatus()); + out.append("</td>"); + if (!task.getStatus().equals(IngestionTask.FINISHED)) { + out.append("<td><input type=\"button\" rel=\"_taskid_\" value=\"Start\" onclick=\"startIngestionTask('"); + out.append(task.getId()); + out.append("')\"/></td>"); + } else { + out.append("<td><input type=\"button\" rel=\"_taskid_\" value=\"Remove\" onclick=\"removeIngestionTask('"); + out.append(task.getId()); + out.append("')\"></td>"); + } + + out.append("</tr>"); + } + return out.toString(); + } + + private String encodeTaskListAsJSON(List<IngestionTask> taskList) { + List<Map<String, String>> jsonFriendlyTaskList = new Vector<Map<String, String>>(); + for (IngestionTask task : taskList) { + Map<String, String> taskPropMap = new HashMap<String, String>(); + taskPropMap.put("id", task.getId()); + taskPropMap.put("createDate", DateUtils.getDateAsISO8601String(task + .getCreateDate())); + taskPropMap.put("policy", task.getPolicy()); + taskPropMap.put("productType", task.getProductType()); + taskPropMap.put("status", task.getStatus()); + taskPropMap.put("fileList", task.getFileList().toString()); + taskPropMap.put("extractorClass", task.getExtConf().getClassName()); + taskPropMap.put("extractorConfFiles", task.getExtConf().getConfigFiles() + .toString()); + jsonFriendlyTaskList.add(taskPropMap); + } + + JSONObject resObj = new JSONObject(); + resObj.put("taskList", jsonFriendlyTaskList); + return resObj.toString(); + + } + + private String encodeIngestResponseAsHTML(boolean success, String msg) { + StringBuffer out = new StringBuffer(); + if (success) { + out.append("Success"); + } else { + out.append(msg); + } + return out.toString(); + } + + private String encodeIngestResponseAsJSON(boolean success, String msg) { + Map<String, Object> resMap = new HashMap<String, Object>(); + resMap.put("success", success); + resMap.put("msg", msg); + JSONObject resObj = new JSONObject(); + resObj.putAll(resMap); + return resObj.toString(); + + } + + private Ingester configureIngester() { + StdIngester ingest = new StdIngester(DATA_TRANSFER_SERVICE); + return ingest; + } + + private URL safeGetUrl(String urlStr) { + try { + return new URL(urlStr); + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + + private List<String> deducePaths(List<String> vPaths) { + List<String> absolutePaths = new Vector<String>(); + String stagingIngestPath = CurationService.config.getStagingAreaPath(); + if (!stagingIngestPath.endsWith("/")) { + stagingIngestPath += "/"; + } + + for (String vPath : vPaths) { + String realPath = stagingIngestPath + vPath; + absolutePaths.add(realPath); + } + + return absolutePaths; + } + + private String getVirtualPath(String stagingAreaPath, String fullFilePath) { + int startIdx = stagingAreaPath.length(); + try { + return fullFilePath.substring(startIdx); + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + + class IngestionTaskList { + + private HashMap<String, IngestionTask> taskMap; + + public IngestionTaskList() { + this.taskMap = new HashMap<String, IngestionTask>(); + } + + public synchronized String addIngestionTask(IngestionTask task) { + this.provideTaskId(task); + taskMap.put(task.getId(), task); + return task.getId(); + } + + public synchronized void removeIngestionTask(String taskId) { + taskMap.remove(taskId); + } + + public IngestionTask getIngestionTaskById(String taskId) { + return taskMap.get(taskId); + } + + public List<IngestionTask> getTaskList() { + List<IngestionTask> taskList = Arrays.asList(taskMap.values().toArray( + new IngestionTask[taskMap.values().size()])); + Collections.sort(taskList, new Comparator<IngestionTask>() { + + public int compare(IngestionTask o1, IngestionTask o2) { + if (o1.getCreateDate().before(o2.getCreateDate())) { + return -1; + } else if (o1.getCreateDate().equals(o2.getCreateDate())) { + return 0; + } else + return 1; + } + }); + return taskList; + } + + private void provideTaskId(IngestionTask task) { + UUID id = UUID.randomUUID(); + task.setId(id.toString()); + } + + } + +} http://git-wip-us.apache.org/repos/asf/oodt/blob/a47b088a/curator2/src/main/java/org/apache/oodt/cas/curation/service/MetadataResource.java ---------------------------------------------------------------------- diff --git a/curator2/src/main/java/org/apache/oodt/cas/curation/service/MetadataResource.java b/curator2/src/main/java/org/apache/oodt/cas/curation/service/MetadataResource.java new file mode 100644 index 0000000..77eba3f --- /dev/null +++ b/curator2/src/main/java/org/apache/oodt/cas/curation/service/MetadataResource.java @@ -0,0 +1,970 @@ +/* + * 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.oodt.cas.curation.service; + +//JDK imports +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.net.MalformedURLException; +import java.util.Arrays; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +import javax.servlet.ServletContext; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +//JAX-RS imports +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.DefaultValue; +import javax.ws.rs.FormParam; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MultivaluedMap; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.UriInfo; + + + +//JSON imports +import net.sf.json.JSONArray; +import net.sf.json.JSONObject; +import net.sf.json.JSONSerializer; + + + +//OODT imports +import org.apache.oodt.cas.curation.service.CurationService; +import org.apache.oodt.cas.curation.structs.ExtractorConfig; +import org.apache.oodt.cas.curation.util.CurationXmlStructFactory; +import org.apache.oodt.cas.curation.util.ExtractorConfigReader; +import org.apache.oodt.cas.filemgr.catalog.Catalog; +import org.apache.oodt.cas.filemgr.repository.XMLRepositoryManager; +import org.apache.oodt.cas.filemgr.structs.Element; +import org.apache.oodt.cas.filemgr.structs.Product; +import org.apache.oodt.cas.filemgr.structs.ProductType; +import org.apache.oodt.cas.filemgr.structs.Reference; +import org.apache.oodt.cas.filemgr.structs.exceptions.CatalogException; +import org.apache.oodt.cas.filemgr.structs.exceptions.RepositoryManagerException; +import org.apache.oodt.cas.filemgr.structs.exceptions.ValidationLayerException; +import org.apache.oodt.cas.filemgr.system.XmlRpcFileManagerClient; +import org.apache.oodt.cas.filemgr.util.GenericFileManagerObjectFactory; +import org.apache.oodt.cas.filemgr.validation.XMLValidationLayer; +import org.apache.oodt.cas.metadata.MetExtractor; +import org.apache.oodt.cas.metadata.Metadata; +import org.apache.oodt.cas.metadata.SerializableMetadata; +import org.apache.oodt.cas.metadata.exceptions.MetExtractionException; +import org.apache.oodt.cas.metadata.util.GenericMetadataObjectFactory; + +//SPRING imports +import org.springframework.util.StringUtils; + +@Path("metadata") +/** + * + * A web-service endpoint for dealing with CAS {@link Metadata} object. + * + * @author pramirez + * @version $Id$ + */ +public class MetadataResource extends CurationService { + + @Context + UriInfo uriInfo; + + @Context + private ServletContext context; + + private static final long serialVersionUID = 1930946924218765724L; + + public static final String STAGING = "staging"; + + public static final String CATALOG = "catalog"; + + public static final String PRODUCT_TYPE = "productType"; + + public static final String UPDATE = "update"; + + public static final String DELETE = "delete"; + + // single instance of CAS catalog shared among all requests + private Catalog catalog = null; + + public MetadataResource(){ + + } + + public MetadataResource(@Context ServletContext context) { + + } + + @GET + @Path(STAGING) + @Produces("text/plain") + public String getStagingMetadata(@QueryParam("id") String id, + @DefaultValue(FORMAT_HTML) @QueryParam("format") String format, + @QueryParam("configId") String configId, + @DefaultValue("false") @QueryParam("overwrite") Boolean overwrite, + @Context HttpServletRequest req, @Context HttpServletResponse res) { + + // this.sendRedirect("login.jsp", uriInfo, res); + + Metadata metadata = null; + + try { + metadata = this.getStagingMetadata(id, configId, overwrite); + } catch (Exception e) { + return "<div class=\"error\">" + e.getMessage() + "</div>"; + } + + if (FORMAT_HTML.equals(format)) { + return this.getMetadataAsHTML(metadata); + } + return this.getMetadataAsJSON(metadata).toString(); + } + + @GET + @Path("extractor/config") + @Produces("text/plain") + public String getMetExtractorConfigList( + @DefaultValue("") @QueryParam("current") String current, + @DefaultValue(FORMAT_HTML) @QueryParam("format") String format) { + String[] configIds = this.getFilesInDirectory(this.config + .getMetExtrConfUploadPath(), false); + + if (FORMAT_HTML.equals(format)) { + return this.getExtractorConfigIdsAsHTML(configIds, current); + } + return this.getExtractorConfigIdsAsJSON(configIds); + } + + protected String getExtractorConfigIdsAsHTML(String[] configIds, + String current) { + StringBuffer html = new StringBuffer(); + for (int i = 0; i < configIds.length; i++) { + html.append("<option "); + if (configIds[i].equals(current)) { + html.append("selected "); + } + html.append("value=\""); + html.append(configIds[i]); + html.append("\">"); + html.append(configIds[i]); + html.append("</option>\r\n"); + } + return html.toString(); + } + + protected String getExtractorConfigIdsAsJSON(String[] configIds) { + // TODO: Support JSON WHY, OH WHY!!! + return "Not Implemented..."; + } + + /** + * + * @param id + * Relative path from staging root to product. The met extension will + * be added to this id to look up and see if a met file exists with + * in the met area. + * @param configId + * Reference to the extractor config. {@link ExtractorConfigReader} + * will load the configuration + * @param overwrite + * Flag to indicate whether or not to overwrite a met file if present + * in the staging area. + * @return The {@link Metadata} retrieved from the met area path if present or + * extracted using the met extractor config. + * @throws FileNotFoundException + * @throws InstantiationException + * @throws IOException + * @throws MetExtractionException + */ + protected Metadata getStagingMetadata(String id, String configId, + Boolean overwrite) throws FileNotFoundException, InstantiationException, + IOException, MetExtractionException { + if (configId == null || configId.trim().length() == 0) { + return this.readMetFile(id + CurationService.config.getMetExtension()); + } else { + String relMetPath = id.startsWith("/") ? id : "/" + id; + String pathToMetFile = CurationService.config.getMetAreaPath() + + relMetPath + CurationService.config.getMetExtension(); + if (!overwrite && new File(pathToMetFile).exists()) { + return this.readMetFile(id + CurationService.config.getMetExtension()); + } else { + // Make sure the parent directory exists + new File(pathToMetFile).getParentFile().mkdirs(); + Metadata metadata = this.runMetExtractor(id, ExtractorConfigReader + .readFromDirectory( + new File(CurationService.config + .getMetExtrConfUploadPath()), configId)); + this.writeMetFile(id, metadata); + return metadata; + } + } + } + + /** + * + * @param id + * Relative path from staging root to the product + * @param config + * Configuration to run this met extractor + * @return + * @throws MetExtractionException + */ + protected Metadata runMetExtractor(String id, ExtractorConfig config) + throws MetExtractionException { + MetExtractor metExtractor = GenericMetadataObjectFactory + .getMetExtractorFromClassName(config.getClassName()); + metExtractor.setConfigFile(config.getConfigFiles().get(0)); + return metExtractor.extractMetadata(CurationService.config + .getStagingAreaPath() + + "/" + id); + } + + @GET + @Path(CATALOG) + @Produces("text/plain") + public String getCatalogMetadata(@QueryParam("id") String id, + @DefaultValue(FORMAT_HTML) @QueryParam("format") String format, + @Context HttpServletRequest req, @Context HttpServletResponse res) { + + // this.sendRedirect("login.jsp", uriInfo, res); + // Call file manager to get metadata + Product prod; + Metadata metadata; + String productId = id.substring(id.lastIndexOf("/") + 1); + + try { + prod = CurationService.config.getFileManagerClient().getProductById( + productId); + metadata = this.getCatalogMetadata(prod); + } catch (Exception e) { + return "<div class=\"error\">" + e.getMessage() + "</div>"; + } + + if (FORMAT_HTML.equals(format)) { + return this.getMetadataAsHTML(metadata); + } + return this.getMetadataAsJSON(metadata).toString(); + } + + @POST + @Path(CATALOG) + @Consumes("application/x-www-form-urlencoded") + @Produces("text/plain") + public String setCatalogMetadata(MultivaluedMap<String, String> formParams, + @FormParam("id") String id) { + + Product prod; + Metadata metadata = this.getMetadataFromMap(formParams); + + String productId = id.substring(id.lastIndexOf("/") + 1); + + try { + prod = CurationService.config.getFileManagerClient().getProductById( + productId); + this.updateCatalogMetadata(prod, metadata); + } catch (Exception e) { + e.printStackTrace(); + return "<div class=\"error\">" + e.getMessage() + "</div>"; + } + + return this.getMetadataAsHTML(metadata); + } + + @GET + @Path(PRODUCT_TYPE) + @Produces("text/plain") + public String getProductTypeMetadata(@QueryParam("id") String id, + @DefaultValue(FORMAT_HTML) @QueryParam("format") String format, + @Context HttpServletRequest req, @Context HttpServletResponse res) { + + // this.sendRedirect("login.jsp", uriInfo, res); + + Metadata metadata; + String[] idParts = id.split("/", 3); + String policy = idParts[1]; + String productType = idParts[2]; + productType = productType.substring(0, productType.lastIndexOf("/")); + try { + metadata = getProductTypeMetadataForPolicy(policy, productType); + } catch (Exception e) { + return "<div class=\"error\">" + e.getMessage() + "</div>"; + } + + if (FORMAT_HTML.equals(format)) { + return this.getMetadataAsHTML(metadata); + } + return this.getMetadataAsJSON(metadata).toString(); + } + + + @POST + @Path(PRODUCT_TYPE) + @Consumes("application/x-www-form-urlencoded") + @Produces("text/plain") + public String setProductTypeMetadata(MultivaluedMap<String, String> formParams) { + String[] idParts = formParams.getFirst("id").split("/"); + String policy = idParts[1]; + String productType = idParts[2]; + try { + this.writeProductTypeMetadata(policy, productType, this + .getMetadataFromMap(formParams)); + } catch (Exception e) { + return "<div class=\"error\">" + e.getMessage() + "</div>"; + } + return ""; + } + + @POST + @Path(STAGING) + @Consumes("application/x-www-form-urlencoded") + @Produces("text/plain") + public String setStagingMetadata(MultivaluedMap<String, String> formParams) { + try { + this.writeMetFile(formParams.getFirst("id"), this + .getMetadataFromMap(formParams)); + } catch (Exception e) { + return "<div class=\"error\">" + e.getMessage() + "</div>"; + } + return ""; + } + + @GET + @Path("staging/info") + @Produces("text/plain") + public String getMetadataInfo(@QueryParam("id") String id) { + + return "Staging met info"; + } + + + private JSONObject getMetadataAsJSON(Metadata metadata) { + return JSONObject.fromObject(metadata.getHashTable()); + } + + private Metadata getMetadataFromJSON(String metadataJSON) { + JSONObject json = (JSONObject) JSONSerializer.toJSON(metadataJSON); + Metadata metadata = new Metadata(); + + Set<String> keys = json.keySet(); + for (String key : keys) { + List values = (List) JSONSerializer.toJava((JSONArray) json.get(key)); + metadata.addMetadata(key, values); + } + + return metadata; + } + + private Metadata getMetadataFromMap(MultivaluedMap<String, String> formParams) { + Metadata metadata = new Metadata(); + + for (String key : formParams.keySet()) { + if (key.startsWith("metadata.")) { + String newKey = key.substring(key.indexOf('.') + 1); + for (String value : formParams.get(key)) { + metadata.addMetadata(newKey, value); + } + } + } + + return metadata; + } + + protected String getMetadataAsHTML(Metadata metadata) { + if (metadata == null) { + return "<table></table>"; + } + + StringBuffer html = new StringBuffer(); + + html.append("<table>\r\n"); + for (String key : (Set<String>) metadata.getHashTable().keySet()) { + html.append(" <tr>\r\n"); + html.append(" <th>").append(key).append("</th>\r\n"); + html.append(" <td class=\"").append(key).append("\">"); + List<String> values = metadata.getAllMetadata(key); + for (Iterator<String> i = values.iterator(); i.hasNext();) { + html.append("<span>").append(i.next()).append("</span>"); + if (i.hasNext()) { + html.append(", "); + } + } + for (String value : (List<String>) metadata.getAllMetadata(key)) { + } + html.append("</td>\r\n"); + html.append(" </tr>\r\n"); + } + html.append("</table>\r\n"); + + return html.toString(); + } + + + /** + * Reads a {@link Metadata} object from a String representation of a .met + * {@link File}. + * + * @param file + * The full path to the .met {@link File}. + * @return The read-in CAS {@link Metadata} object. + * @throws InstantiationException + * @throws InstantiationException + * If there is an error instantiating the {@link Metadata} class. + * @throws IOException + * @throws FileNotFoundException + * @throws FileNotFoundException + * If the .met {@link File} is not found. + * @throws IOException + * If there is an IO problem opening the met file. + */ + public Metadata readMetFile(String file) throws InstantiationException, + FileNotFoundException, IOException { + SerializableMetadata metadata = new SerializableMetadata("UTF-8", false); + metadata.loadMetadataFromXmlStream(new FileInputStream(config + .getMetAreaPath() + + "/" + file)); + + return metadata; + } + + /** + * Retrieves the cataloged {@link Metadata} associated with a {@link Product}. + * + * @param product + * The {@link Product} to obtain cataloged {@link Metadata} for. + * @return The cataloged {@link Metadata} for {@link Product}. + * @throws CatalogException + * If there is an error talking to the CAS File Manager + * {@link Catalog}. + */ + public Metadata getCatalogMetadata(Product product) throws CatalogException { + return CurationService.config.getFileManagerClient().getMetadata( + CurationService.config.getFileManagerClient().getProductById( + product.getProductId())); + } + + /** + * Writes a CAS {@link Metadata} {@link File} using the given identifier. + * + * @param id + * The identifier of the .met file to write. + * @param metadata + * The {@link Metadata} object to persist and write to a {@link File} + * . + * @throws FileNotFoundException + * If the .met {@link File} cannot be written. + * @throws IOException + * If there is an IO exception writing the {@link File}. + */ + public void writeMetFile(String id, Metadata metadata) + throws FileNotFoundException, IOException { + SerializableMetadata serMet = new SerializableMetadata(metadata, "UTF-8", + false); + serMet.writeMetadataToXmlStream(new FileOutputStream(new File(config + .getMetAreaPath(), id + config.getMetExtension()))); + } + + /** + * Method to update the catalog metadata for a given product. + * All current metadata fields will be preserved, + * except those specified in the HTTP POST request as 'metadata.<field_name>=<field_value>'. + * + * @param id + * identifier of CAS product - either 'id' or 'name' must be specified + * @param name + * name of CAS product - either 'id' or 'name' must be specified + * @param formParams + * HTTP (name, value) form parameters. The parameter names MUST start with "metadata." + * @param replace + * optional flag set to false to add the new metadata values to the existing values, for the given flags + */ + @POST + @Path(UPDATE) + @Consumes("application/x-www-form-urlencoded") + @Produces("text/plain") + public String updateMetadata(MultivaluedMap<String, String> formParams, + @FormParam("id") String id, + @FormParam("name") String name, + @DefaultValue("true") @FormParam("replace") boolean replace, + @DefaultValue("false") @FormParam("remove") boolean remove) { + + // new metadata from HTTP POST request + Metadata newMetadata = this.getMetadataFromMap(formParams); + + // client for interacting with remote File Manager + XmlRpcFileManagerClient fmClient = CurationService.config.getFileManagerClient(); + + // empty metadata + Metadata metadata = new Metadata(); + + try { + + // retrieve product from catalog + Product product = null; + if (StringUtils.hasText(id)) { + id = id.substring(id.lastIndexOf("/") + 1); + product = fmClient.getProductById(id); + } else if (StringUtils.hasText(name)) { + product = fmClient.getProductByName(name); + } else { + throw new Exception("Either the HTTP parameter 'id' or the HTTP parameter 'name' must be specified"); + } + + // retrieve existing metadata + metadata = fmClient.getMetadata(product); + + // remove product references (as they will be added later) + metadata.removeMetadata("reference_orig"); + metadata.removeMetadata("reference_data_store"); + metadata.removeMetadata("reference_fileSize"); + metadata.removeMetadata("reference_mimeType"); + + // merge new and existing metadata + metadata.addMetadata(newMetadata); + + // replace metadata values for keys specified in HTTP request (not others) + if (replace) { + for (String key : newMetadata.getAllKeys()) { + metadata.replaceMetadata(key, newMetadata.getAllMetadata(key)); + } + } + + // remove metadata tags + if (remove) { + for (String key : newMetadata.getAllKeys()) { + metadata.removeMetadata(key); + } + } + + // insert old and new metadata + fmClient.updateMetadata(product, metadata); + + // return product id to downstream processors + return "id="+product.getProductId(); + + } catch (Exception e) { + + e.printStackTrace(); + // return error message + throw new WebApplicationException(e, Response.Status.INTERNAL_SERVER_ERROR); + + } + + } + + /** + * Updates the cataloged {@link Metadata} for a {@link Product} in the CAS + * File Manager. + * + * @param product + * The {@link Product} to update {@link Metadata} for. + * @param newMetadata + * The new {@link Metadata} to persist into the {@link Catalog}. + * @throws CatalogException + * If any error occurs during the update. + * @throws IOException + * @throws FileNotFoundException + */ + public void updateCatalogMetadata(Product product, Metadata newMetadata) + throws CatalogException, FileNotFoundException, IOException { + System.getProperties().load( + new FileInputStream(CurationService.config.getFileMgrProps())); + Catalog catalog = this.getCatalog(); + + Metadata oldMetadata = catalog.getMetadata(product); + List<Reference> references = catalog.getProductReferences(product); + Product newProduct = new Product(product.getProductName(), product + .getProductType(), product.getProductStructure(), product + .getTransferStatus(), product.getProductReferences()); + // Constructor is bugged and doesn't set transfer status + newProduct.setTransferStatus(product.getTransferStatus()); + catalog.removeMetadata(oldMetadata, product); + catalog.removeProduct(product); + newProduct.setProductId(product.getProductId()); + catalog.addProduct(newProduct); + newProduct.setProductReferences(references); + catalog.addProductReferences(newProduct); + catalog.addMetadata(newMetadata, newProduct); + } + + /** + * Method to delete a specific product from the catalog + * + * @param id + * identifier of CAS product - either 'id' or 'name' must be specified + * @param name + * name of CAS product - either 'id' or 'name' must be specified + * @return the product ID of the deleted product if deletion successful + */ + @POST + @Path(DELETE) + @Consumes("application/x-www-form-urlencoded") + @Produces("text/plain") + public String deleteCatalogMetadata( + @FormParam("id") String id, + @FormParam("name") String name) { + + try { + // retrieve product from catalog + Product product = null; + if (StringUtils.hasText(id)) { + id = id.substring(id.lastIndexOf("/") + 1); + product = CurationService.config.getFileManagerClient().getProductById(id); + } else if (StringUtils.hasText(name)) { + product = CurationService.config.getFileManagerClient().getProductByName(name); + } else { + throw new Exception("Either the HTTP parameter 'id' or the HTTP parameter 'name' must be specified"); + } + + // remove product from catalog + this.deleteCatalogProduct(product); + + // return product id to downstream processors + return "id="+product.getProductId(); + + } catch (Exception e) { + + e.printStackTrace(); + // return error message + throw new WebApplicationException(e, Response.Status.INTERNAL_SERVER_ERROR); + + } + } + + /** + * Deletes a given product from the catalog + * + * @param product + * The {@link Product} to delete + * @throws FileNotFoundException + * @throws IOException + * @throws CatalogException + * If any error occurs during this delete operation. + */ + public void deleteCatalogProduct(Product product) + throws FileNotFoundException, IOException, CatalogException { + CurationService.config.getFileManagerClient().removeProduct(product); + } + + private Metadata getProductTypeMetadataForPolicy(String policy, + String productTypeName) throws MalformedURLException, + InstantiationException, RepositoryManagerException { + String rootPolicyPath = this.cleanse(CurationService.config + .getPolicyUploadPath()); + String policyPath = new File(rootPolicyPath + policy).toURL() + .toExternalForm(); + String[] policies = { policyPath }; + XMLRepositoryManager repMgr = new XMLRepositoryManager(Arrays + .asList(policies)); + ProductType productType = repMgr.getProductTypeByName(productTypeName); + + return productType.getTypeMetadata(); + } + + private Metadata writeProductTypeMetadata(String policy, + String productTypeName, Metadata metadata) throws Exception { + String rootPolicyPath = this.cleanse(CurationService.config + .getPolicyUploadPath()); + String policyPath = new File(rootPolicyPath + policy).toURL() + .toExternalForm(); + String[] policies = { policyPath }; + XMLRepositoryManager repMgr = new XMLRepositoryManager(Arrays + .asList(policies)); + + ProductType productType = repMgr.getProductTypeByName(productTypeName); + productType.setTypeMetadata(metadata); + + CurationXmlStructFactory.writeProductTypeXmlDocument(repMgr + .getProductTypes(), rootPolicyPath + policy + "/product-types.xml"); + + // refresh the config on the fm end + CurationService.config.getFileManagerClient().refreshConfigAndPolicy(); + + return productType.getTypeMetadata(); + } + + private String cleanse(String origPath) { + String retStr = origPath; + if (!retStr.endsWith("/")) { + retStr += "/"; + } + return retStr; + } + + // Method to instantiate the CAS catalog, if not done already. + private synchronized Catalog getCatalog() { + + if (catalog==null) { + String catalogFactoryClass = this.context.getInitParameter(CATALOG_FACTORY_CLASS); + // preserve backward compatibility + if (!StringUtils.hasText(catalogFactoryClass)) + catalogFactoryClass = "org.apache.oodt.cas.filemgr.catalog.LuceneCatalogFactory"; + catalog = GenericFileManagerObjectFactory.getCatalogServiceFromFactory(catalogFactoryClass); + } + + return catalog; + } + + @DELETE + @Path(PRODUCT_TYPE+"/remove") + @Produces("text/plain") + public boolean removeProductType( + @FormParam("policy") String policy, + @FormParam("id") String id) { + XMLRepositoryManager xmlRepo = getRepo(policy); + try { + ProductType type = xmlRepo.getProductTypeById(id); + xmlRepo.removeProductType(type); + return true; + } catch (RepositoryManagerException e) { + e.printStackTrace(); + return false; + } + } + + @GET + @Path(PRODUCT_TYPE+"/parentmap") + @Produces("text/plain") + public String getParentTypeMap( + @FormParam("policy") String policy) { + XMLValidationLayer vLayer = getValidationLayer(policy); + return JSONSerializer.toJSON(vLayer.getSubToSuperMap()).toString(); + } + + @POST + @Path(PRODUCT_TYPE+"/parent/add") + @Produces("text/plain") + public boolean addParentForProductType( + @FormParam("policy") String policy, + @FormParam("id") String id, + @FormParam("parentId") String parentId) { + XMLValidationLayer vLayer = getValidationLayer(policy); + XMLRepositoryManager xmlRepo = getRepo(policy); + try { + ProductType type = xmlRepo.getProductTypeById(id); + vLayer.addParentForProductType(type, parentId); + return true; + } catch (RepositoryManagerException e) { + e.printStackTrace(); + } + return false; + } + + @DELETE + @Path(PRODUCT_TYPE+"/parent/remove") + @Produces("text/plain") + public boolean removeParentForProductType( + @FormParam("policy") String policy, + @FormParam("id") String id) + throws ValidationLayerException { + XMLValidationLayer vLayer = getValidationLayer(policy); + XMLRepositoryManager xmlRepo = getRepo(policy); + try { + ProductType type = xmlRepo.getProductTypeById(id); + vLayer.removeParentForProductType(type); + return true; + } catch (RepositoryManagerException e) { + e.printStackTrace(); + } + return false; + } + + @POST + @Path(PRODUCT_TYPE+"/elements/add") + @Produces("text/plain") + public boolean addElementsForProductType( + @FormParam("policy") String policy, + @FormParam("id") String id, + @FormParam("elementIds") String elementIds) { + XMLValidationLayer vLayer = getValidationLayer(policy); + XMLRepositoryManager xmlRepo = getRepo(policy); + try { + ProductType type = xmlRepo.getProductTypeById(id); + for(String elementid: elementIds.split(",")) { + Element element = vLayer.getElementById(elementid); + if(element == null) { + element = new Element(elementid, elementid, "", "", "Automatically added", ""); + vLayer.addElement(element); + } + vLayer.addElementToProductType(type, element); + } + return true; + } catch (Exception e) { + e.printStackTrace(); + } + return false; + } + + @GET + @Path(PRODUCT_TYPE+"/elements") + @Produces("text/plain") + public String getElementsForProductType( + @FormParam("policy") String policy, + @FormParam("id") String id, + @FormParam("direct") boolean direct) { + XMLValidationLayer vLayer = getValidationLayer(policy); + XMLRepositoryManager xmlRepo = getRepo(policy); + try { + ProductType type = xmlRepo.getProductTypeById(id); + ArrayList<String> elementIds = new ArrayList<String>(); + for(Element el : vLayer.getElements(type, direct)) { + elementIds.add(el.getElementId()); + } + return JSONSerializer.toJSON(elementIds).toString(); + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } + + @DELETE + @Path(PRODUCT_TYPE+"/elements/remove/all") + @Produces("text/plain") + public boolean removeAllElementsForProductType( + @FormParam("policy") String policy, + @FormParam("id") String id) { + XMLValidationLayer vLayer = getValidationLayer(policy); + XMLRepositoryManager xmlRepo = getRepo(policy); + try { + ProductType type = xmlRepo.getProductTypeById(id); + List<Element> elementList = vLayer.getElements(type); + for(Element element: elementList) { + vLayer.removeElementFromProductType(type, element); + } + this.removeUnusedElements(elementList, xmlRepo, vLayer); + return true; + } catch (Exception e) { + e.printStackTrace(); + } + return false; + } + + @DELETE + @Path(PRODUCT_TYPE+"/elements/remove") + @Produces("text/plain") + public boolean removeElementsForProductType( + @FormParam("policy") String policy, + @FormParam("id") String id, + @FormParam("elementIds") String elementIds) { + XMLValidationLayer vLayer = getValidationLayer(policy); + XMLRepositoryManager xmlRepo = getRepo(policy); + try { + ProductType type = xmlRepo.getProductTypeById(id); + ArrayList<Element> elements = new ArrayList<Element>(); + for(String elementId: elementIds.split(",")) { + Element element = vLayer.getElementById(elementId); + if(element != null) { + vLayer.removeElementFromProductType(type, element); + elements.add(element); + } + } + this.removeUnusedElements(elements, xmlRepo, vLayer); + return true; + } catch (Exception e) { + e.printStackTrace(); + } + return false; + } + + @GET + @Path(PRODUCT_TYPE+"/typeswithelement/{elementId}") + @Produces("text/plain") + public String getProductTypeIdsHavingElement( + @FormParam("policy") String policy, + @PathParam("elementId") String elementId) { + XMLValidationLayer vLayer = getValidationLayer(policy); + XMLRepositoryManager xmlRepo = getRepo(policy); + ArrayList<String> typeids = new ArrayList<String>(); + try { + for(ProductType type : xmlRepo.getProductTypes()) { + for(Element el : vLayer.getElements(type)) { + if(el.getElementId().equals(elementId)) + typeids.add(type.getProductTypeId()); + } + } + } catch (Exception e) { + e.printStackTrace(); + } + return JSONSerializer.toJSON(typeids).toString(); + } + + + /* + * Private helper functions + */ + private void removeUnusedElements(List<Element> elements, + XMLRepositoryManager xmlRepo, XMLValidationLayer vLayer) + throws ValidationLayerException, RepositoryManagerException { + // Remove Elements that aren't used in any product type + List<ProductType> ptypelist = xmlRepo.getProductTypes(); + HashMap<String, Boolean> usedElementIds = new HashMap<String, Boolean>(); + for(ProductType ptype: ptypelist) { + List<Element> ptypeElements = + vLayer.getElements(ptype); + for(Element el: ptypeElements) { + usedElementIds.put(el.getElementId(), true); + } + } + for(Element el: elements) { + if(!usedElementIds.containsKey(el.getElementId())) + vLayer.removeElement(el); + } + } + + private XMLRepositoryManager getRepo(String policy) { + XMLRepositoryManager xmlRepo = null; + String url = "file://" + CurationService.config.getPolicyUploadPath() + "/" + policy; + + try { + xmlRepo = new XMLRepositoryManager(Collections.singletonList(url)); + } catch (Exception e) { + e.printStackTrace(); + } + + return xmlRepo; + } + + private XMLValidationLayer getValidationLayer(String policy) { + XMLValidationLayer vLayer = null; + String url = "file://" + CurationService.config.getPolicyUploadPath() + "/" + policy; + + try { + vLayer = new XMLValidationLayer(Collections.singletonList(url)); + } catch (Exception e) { + e.printStackTrace(); + } + return vLayer; + } +} http://git-wip-us.apache.org/repos/asf/oodt/blob/a47b088a/curator2/src/main/java/org/apache/oodt/cas/curation/service/PolicyResource.java ---------------------------------------------------------------------- diff --git a/curator2/src/main/java/org/apache/oodt/cas/curation/service/PolicyResource.java b/curator2/src/main/java/org/apache/oodt/cas/curation/service/PolicyResource.java new file mode 100644 index 0000000..ff98753 --- /dev/null +++ b/curator2/src/main/java/org/apache/oodt/cas/curation/service/PolicyResource.java @@ -0,0 +1,310 @@ +/* + * 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.oodt.cas.curation.service; + +//OODT imports +import org.apache.commons.lang.StringEscapeUtils; +import org.apache.oodt.cas.filemgr.repository.XMLRepositoryManager; +import org.apache.oodt.cas.filemgr.structs.Product; +import org.apache.oodt.cas.filemgr.structs.ProductPage; +import org.apache.oodt.cas.filemgr.structs.ProductType; +import org.apache.oodt.cas.filemgr.structs.Query; +import org.apache.oodt.cas.filemgr.structs.exceptions.RepositoryManagerException; + +//JDK imports +import java.io.File; +import java.io.FilenameFilter; +import java.io.IOException; +import java.net.MalformedURLException; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Vector; +import java.util.logging.Level; +import java.util.logging.Logger; + +//JAX-RS imports +import javax.servlet.ServletContext; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.ws.rs.DefaultValue; +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.UriInfo; + +//JSON imports +import net.sf.json.JSONObject; + +@Path("policy") +public class PolicyResource extends CurationService { + + @Context + UriInfo uriInfo; + + private static final long serialVersionUID = -3757481221589264709L; + + private static final Logger LOG = Logger.getLogger(PolicyResource.class + .getName()); + + private static final FilenameFilter DIR_FILTER = new FilenameFilter() { + + public boolean accept(File dir, String name) { + return new File(dir, name).isDirectory() + && !new File(dir, name).getName().startsWith("."); + } + }; + + public PolicyResource(@Context ServletContext context){ + + } + + @GET + @Path("browse") + @Produces("text/plain") + public String browseCatalog( + @QueryParam("path") @DefaultValue("/") String path, + @DefaultValue(FORMAT_HTML) @QueryParam("format") String format, + @DefaultValue("1") @QueryParam("pageNum") Integer pageNum, + @Context HttpServletRequest req, @Context HttpServletResponse res) + throws IOException { + + // TODO: Send a not authorized response if not logged in. This should be a + // utility method as a part of CurationService that every service interface + // calls. + + String[] pathToks = tokenizeVirtualPath(path); + String policy = null; + String productType = null; + + if (pathToks == null) { + LOG.log(Level.WARNING, "malformed path token string: " + + Arrays.asList(pathToks)); + return ""; + } + + policy = pathToks.length > 0 ? pathToks[0]:null; + productType = pathToks.length > 1 ? pathToks[1] : null; + + if (policy != null) { + if (productType != null) { + return getProductsForProductType(policy, productType, format, pageNum); + } else { + return getProductTypesForPolicy(policy, format); + } + } else { + return getPolicies(format); + } + + } + + private String getProductsForProductType(String policy, + String productTypeName, + String format, int pageNum) { + + ProductType productType; + ProductPage page; + try { + productType = this.config.getFileManagerClient().getProductTypeByName( + productTypeName); + page = this.config.getFileManagerClient().pagedQuery(new Query(), + productType, pageNum); + } catch (Exception e) { + e.printStackTrace(); + LOG.log(Level.WARNING, "Unable to obtain products for product type: [" + + productTypeName + "]: Message: " + e.getMessage()); + return ""; + } + + if (format.equals(FORMAT_HTML)) { + return encodeProductsAsHTML(page, policy, productTypeName); + } else if (format.equals(FORMAT_JSON)) { + return encodeProductsAsJSON(page, policy, productTypeName); + } else { + return UNKNOWN_OUT_FORMAT; + } + } + + private String encodeProductsAsHTML(ProductPage page, String policy, + String productTypeName) { + StringBuffer html = new StringBuffer(); + html.append("<ul class=\"fileTree\" >\r\n"); + + for (Product product : page.getPageProducts()) { + html.append(" <li class=\"file\">"); + html.append("<a href=\"#\" rel=\"/"); + html.append(policy); + html.append("/"); + html.append(productTypeName); + html.append("/"); + html.append(product.getProductId()); + html.append("\">"); + html.append(product.getProductName()); + html.append("</a>"); + html.append("</li>\r\n"); + } + + html.append("</ul>"); + return html.toString(); + } + + private String encodeProductsAsJSON(ProductPage page, String policy, + String productTypeName) { + return "NOT IMPLENTED YET"; + } + + private String getPolicies(String format) { + String policyPath = this.cleanse(CurationService.config + .getPolicyUploadPath()); + String[] policyDirs = new File(policyPath).list(DIR_FILTER); + + if (format.equals(FORMAT_HTML)) { + return encodePoliciesAsHTML(policyDirs); + } else if (format.equals(FORMAT_JSON)) { + return encodePoliciesAsJSON(policyDirs); + } else { + return UNKNOWN_OUT_FORMAT; + } + + } + + private String getProductTypesForPolicy(String policy, String format) { + String[] typeNames = null; + try { + typeNames = this.getProductTypeNamesForPolicy(policy); + } catch (Exception e) { + e.printStackTrace(); + LOG.log(Level.WARNING, + "Unable to obtain product type names for policy: [" + policy + + "]: Message: " + e.getMessage()); + return ""; + } + + if (format.equals(FORMAT_HTML)) { + return encodeProductTypesAsHTML(policy, typeNames); + } else if (format.equals(FORMAT_JSON)) { + return encodeProductTypesAsJSON(policy, typeNames); + } else { + return UNKNOWN_OUT_FORMAT; + } + + } + + private String encodePoliciesAsHTML(String[] policyDirs) { + StringBuffer out = new StringBuffer(); + out.append("<ul class=\"fileTree\" >"); + for (String policy : policyDirs) { + out.append("<li class=\"directory collapsed\"><a href=\"#\" rel=\"/"); + out.append(StringEscapeUtils.escapeHtml(policy)); + out.append("/\">"); + out.append(StringEscapeUtils.escapeHtml(policy)); + out.append("</a></li>"); + } + out.append("</ul>"); + return out.toString(); + } + + private String encodePoliciesAsJSON(String[] policyDirs) { + Map<String, String> retMap = new HashMap<String, String>(); + for (String policyDir : policyDirs) { + retMap.put("policy", policyDir); + } + JSONObject resObj = new JSONObject(); + resObj.put("policies", retMap); + resObj.put("succeed", true); + return resObj.toString(); + } + + private String encodeProductTypesAsHTML(String policy, String[] typeNames) { + StringBuffer out = new StringBuffer(); + out.append("<ul class=\"fileTree\" >"); + for (String type : typeNames) { + out + .append("<li class=\"directory collapsed productType\"><a href=\"#\" rel=\"/"); + out.append(StringEscapeUtils.escapeHtml(policy)); + out.append("/"); + out.append(StringEscapeUtils.escapeHtml(type)); + out.append("/\">"); + out.append(StringEscapeUtils.escapeHtml(type)); + out.append("</a></li>"); + } + + out.append("</ul>"); + return out.toString(); + } + + private String encodeProductTypesAsJSON(String policy, String[] typeNames) { + Map<String, Object> retMap = new HashMap<String, Object>(); + retMap.put("policy", policy); + List<Map<String, String>> typeList = new Vector<Map<String, String>>(); + for (String typeName : typeNames) { + Map<String, String> typeMap = new HashMap<String, String>(); + typeMap.put("name", typeName); + typeList.add(typeMap); + } + retMap.put("productTypes", typeList); + JSONObject resObj = new JSONObject(); + resObj.putAll(retMap); + return resObj.toString(); + } + + private String[] getProductTypeNamesForPolicy(String policy) + throws MalformedURLException, InstantiationException, + RepositoryManagerException { + String rootPolicyPath = this.cleanse(CurationService.config + .getPolicyUploadPath()); + String policyPath = new File(rootPolicyPath + policy).toURL() + .toExternalForm(); + String[] policies = { policyPath }; + XMLRepositoryManager repMgr = new XMLRepositoryManager(Arrays + .asList(policies)); + List<ProductType> types = repMgr.getProductTypes(); + String[] typeNames = new String[types.size()]; + int i = 0; + for (ProductType type : types) { + typeNames[i] = type.getName(); + i++; + } + + return typeNames; + } + + private String cleanse(String origPath) { + String retStr = origPath; + if (!retStr.endsWith("/")) { + retStr += "/"; + } + return retStr; + } + + private String[] tokenizeVirtualPath(String path) { + String vPath = path; + if (vPath.startsWith("/") && vPath.length() != 1) { + vPath = vPath.substring(1); + } + String[] pathToks = vPath.split("/"); + LOG.log(Level.INFO, "origPath: ["+path+"]"); + LOG.log(Level.INFO, "pathToks: "+Arrays.asList(pathToks)); + return pathToks; + } + +} http://git-wip-us.apache.org/repos/asf/oodt/blob/a47b088a/curator2/src/main/java/org/apache/oodt/cas/curation/service/SystemResource.java ---------------------------------------------------------------------- diff --git a/curator2/src/main/java/org/apache/oodt/cas/curation/service/SystemResource.java b/curator2/src/main/java/org/apache/oodt/cas/curation/service/SystemResource.java new file mode 100644 index 0000000..784d383 --- /dev/null +++ b/curator2/src/main/java/org/apache/oodt/cas/curation/service/SystemResource.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.oodt.cas.curation.service; + +//JAX-RS imports +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.UriInfo; + +@Path("system") +public class SystemResource extends CurationService { + + @Context + UriInfo uriInfo; + + private static final long serialVersionUID = -2318607955517605998L; + + /** + * This is what will go in the upper left box on landing page. To gather + * information such as is the file manager up If this needs to be something + * that gets updated periodically then it would change into a JSON feed + */ + @GET + @Path("stats") + @Produces("text/html") + public String getStatistics() { + return "<div>Server Stats</div>"; + } + + /** + * This returns the configuration information that is set in the context.xml + * file. + */ + @GET + @Path("config") + @Produces("text/html") + public String getConfig() { + return ""; + } + + /** + * This will return the information that appears in the upper right box on + * landing page. + */ + @GET + @Path("feed") + @Produces("text/html") + public String getFeed() { + return "<div>Latest Products?</div>"; + } +} http://git-wip-us.apache.org/repos/asf/oodt/blob/a47b088a/curator2/src/main/java/org/apache/oodt/cas/curation/servlet/CuratorConfMetKeys.java ---------------------------------------------------------------------- diff --git a/curator2/src/main/java/org/apache/oodt/cas/curation/servlet/CuratorConfMetKeys.java b/curator2/src/main/java/org/apache/oodt/cas/curation/servlet/CuratorConfMetKeys.java new file mode 100644 index 0000000..6233775 --- /dev/null +++ b/curator2/src/main/java/org/apache/oodt/cas/curation/servlet/CuratorConfMetKeys.java @@ -0,0 +1,56 @@ +/* + * 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.oodt.cas.curation.servlet; + +/** + * + * Met keys used in the <code>context.xml</code> file to configure the CAS + * curator webapp. + * + * @author mattmann + * @version $Revision$ + * + */ +public interface CuratorConfMetKeys { + + final String MET_EXTRACTOR_CONF_UPLOAD_PATH = "org.apache.oodt.cas.curator.metExtractorConf.uploadPath"; + + final String POLICY_UPLOAD_PATH = "org.apache.oodt.cas.curator.dataDefinition.uploadPath"; + + final String FM_URL = "org.apache.oodt.cas.fm.url"; + + final String SSO_IMPL_CLASS = "org.apache.oodt.security.sso.implClass"; + + final String DEFAULT_TRANSFER_FACTORY = "org.apache.oodt.cas.filemgr.datatransfer.LocalDataTransferFactory"; + + final String CRAWLER_CONF_FILE = "classpath:/org.apache/oodt/cas/crawl/crawler-config.xml"; + + final String PROJECT_DISPLAY_NAME = "org.apache.oodt.cas.curator.projectName"; + + final String STAGING_AREA_PATH = "org.apache.oodt.cas.curator.stagingAreaPath"; + + final String MET_AREA_PATH = "org.apache.oodt.cas.curator.metAreaPath"; + + final String MET_EXTENSION = "org.apache.oodt.cas.curator.metExtension"; + + final String FM_PROPS = "org.apache.oodt.cas.curator.fmProps"; + + final String CATALOG_FACTORY_CLASS = "org.apache.oodt.cas.curator.catalogFactoryClass"; + +} http://git-wip-us.apache.org/repos/asf/oodt/blob/a47b088a/curator2/src/main/java/org/apache/oodt/cas/curation/servlet/CuratorServlet.java ---------------------------------------------------------------------- diff --git a/curator2/src/main/java/org/apache/oodt/cas/curation/servlet/CuratorServlet.java b/curator2/src/main/java/org/apache/oodt/cas/curation/servlet/CuratorServlet.java new file mode 100644 index 0000000..aed7f14 --- /dev/null +++ b/curator2/src/main/java/org/apache/oodt/cas/curation/servlet/CuratorServlet.java @@ -0,0 +1,28 @@ +/** + * + */ +package org.apache.oodt.cas.curation.servlet; + +import javax.servlet.ServletConfig; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; + +import org.apache.oodt.cas.curation.configuration.Configuration; + + +/** + * Handles basic servlet features like config + * + * @author starchmd + */ +public class CuratorServlet extends HttpServlet { + + private static final long serialVersionUID = 1498427942585673418L; + + @Override + public void init(ServletConfig conf) throws ServletException { + super.init(conf); + //Load configuration from context + Configuration.loadConfiguration(conf.getServletContext()); + } +} http://git-wip-us.apache.org/repos/asf/oodt/blob/a47b088a/curator2/src/main/java/org/apache/oodt/cas/curation/structs/ExtractorConfig.java ---------------------------------------------------------------------- diff --git a/curator2/src/main/java/org/apache/oodt/cas/curation/structs/ExtractorConfig.java b/curator2/src/main/java/org/apache/oodt/cas/curation/structs/ExtractorConfig.java new file mode 100644 index 0000000..79beb30 --- /dev/null +++ b/curator2/src/main/java/org/apache/oodt/cas/curation/structs/ExtractorConfig.java @@ -0,0 +1,78 @@ +/* + * 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.oodt.cas.curation.structs; + +import java.io.File; +import java.util.List; +/** + * A class holding the configuration for metadata extractors + * + * @author starchmd - cleanup only, original author unspecified + */ +public class ExtractorConfig { + + public final static String PROP_CLASS_NAME = "extractor.classname"; + public final static String PROP_CONFIG_FILES = "extractor.config.files"; + public final static String PROP_FILLER = "extractor.filler"; + + private final List<File> configFiles; + private final String className; + private final String identifier; + private final String filler; + /** + * Creates a new extractor configuration object + * @param identifier - name of this extractor + * @param className - class name of extractor + * @param configFiles - list of config file for this extractor (Note: only the first is used) + * @param filler - fill string for unextracted fields + */ + public ExtractorConfig(String identifier, String className, List<File> configFiles, String filler) { + this.configFiles = configFiles; + this.className = className; + this.identifier = identifier; + this.filler = filler; + } + /** + * Gets the list of configuration files (Note: only the first, index 0, is used) + * @return config files + */ + public List<File> getConfigFiles() { + return this.configFiles; + } + /** + * Accessor - get class name of this extractor + * @return class name + */ + public String getClassName() { + return this.className; + } + /** + * Accessor - get identifier (i.e. name) of this extractor + * @return identifier + */ + public String getIdentifier() { + return this.identifier; + } + /** + * Accessor - get the filler string + * @return filler + */ + public String getFiller() { + return this.filler; + } +} http://git-wip-us.apache.org/repos/asf/oodt/blob/a47b088a/curator2/src/main/java/org/apache/oodt/cas/curation/structs/IngestionTask.java ---------------------------------------------------------------------- diff --git a/curator2/src/main/java/org/apache/oodt/cas/curation/structs/IngestionTask.java b/curator2/src/main/java/org/apache/oodt/cas/curation/structs/IngestionTask.java new file mode 100644 index 0000000..d1a4327 --- /dev/null +++ b/curator2/src/main/java/org/apache/oodt/cas/curation/structs/IngestionTask.java @@ -0,0 +1,168 @@ +/* + * 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.oodt.cas.curation.structs; + +//OODT imports +import org.apache.oodt.cas.filemgr.ingest.Ingester; + +//JDK imports +import java.util.Date; +import java.util.List; +import java.util.Vector; + +/** + * + * A specification for ingestion using the {@link Ingester} interface in the + * CAS. + * + * @author mattmann + * @version $Revision$ + * + */ +public class IngestionTask implements IngestionTaskStatus { + + private String id; + + private Date createDate; + + private List<String> fileList; + + private String policy; + + private String productType; + + private String status; + + private ExtractorConfig extConf; + + public IngestionTask() { + this.id = null; + this.createDate = null; + this.fileList = new Vector<String>(); + this.policy = null; + this.productType = null; + this.extConf = new ExtractorConfig(null, null, null,null); + } + + /** + * @return the id + */ + public String getId() { + return id; + } + + /** + * @param id + * the id to set + */ + public void setId(String id) { + this.id = id; + } + + /** + * @return the createDate + */ + public Date getCreateDate() { + return createDate; + } + + /** + * @param createDate + * the createDate to set + */ + public void setCreateDate(Date createDate) { + this.createDate = createDate; + } + + /** + * @return the fileList + */ + public List<String> getFileList() { + return fileList; + } + + /** + * @param fileList + * the fileList to set + */ + public void setFileList(List<String> fileList) { + this.fileList = fileList; + } + + /** + * @return the policy + */ + public String getPolicy() { + return policy; + } + + /** + * @param policy + * the policy to set + */ + public void setPolicy(String policy) { + this.policy = policy; + } + + /** + * @return the productType + */ + public String getProductType() { + return productType; + } + + /** + * @param productType + * the productType to set + */ + public void setProductType(String productType) { + this.productType = productType; + } + + /** + * @return the status + */ + public String getStatus() { + return status; + } + + /** + * @param status + * the status to set + */ + public void setStatus(String status) { + this.status = status; + } + + /** + * @return the extConf + */ + public ExtractorConfig getExtConf() { + return extConf; + } + + /** + * @param extConf + * the extConf to set + */ + public void setExtConf(ExtractorConfig extConf) { + this.extConf = extConf; + } + +} http://git-wip-us.apache.org/repos/asf/oodt/blob/a47b088a/curator2/src/main/java/org/apache/oodt/cas/curation/structs/IngestionTaskStatus.java ---------------------------------------------------------------------- diff --git a/curator2/src/main/java/org/apache/oodt/cas/curation/structs/IngestionTaskStatus.java b/curator2/src/main/java/org/apache/oodt/cas/curation/structs/IngestionTaskStatus.java new file mode 100644 index 0000000..7527060 --- /dev/null +++ b/curator2/src/main/java/org/apache/oodt/cas/curation/structs/IngestionTaskStatus.java @@ -0,0 +1,36 @@ +/* + * 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.oodt.cas.curation.structs; + +/** + * + * Met keys for the {@link IngestionTask#getStatus()} field. + * + * @author mattmann + * @version $Revision$ + * + */ +public interface IngestionTaskStatus { + + public static final String FINISHED = "Finished"; + + public static final String STARTED = "Started"; + + public static final String NOT_STARTED = "Not Started"; +}
