/* * Copyright 2003-2010 Tufts University Licensed under the * Educational Community 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.osedu.org/licenses/ECL-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. */ /** * * @author akumar03 */ package tufts.vue; import java.security.interfaces.DSAKey; import java.util.*; import java.net.*; import java.io.*; import java.text.SimpleDateFormat; import javax.activation.MimetypesFileTypeMap; import edu.tufts.vue.metadata.VueMetadataElement; //required for publishing to Fedora import fedora.client.FedoraClient; import fedora.client.utility.ingest.AutoIngestor; import fedora.client.utility.AutoFinder; import fedora.server.types.gen.Datastream; import fedora.server.types.gen.FieldSearchResult; import fedora.server.types.gen.FieldSearchQuery; import fedora.client.Uploader; import fedora.server.types.gen.Condition; import fedora.server.types.gen.ComparisonOperator; public class FedoraPublisher { public static final String HTTPS = "https"; public static final String HTTP = "http"; public static final String FEDORA_URL_PATH = "/fedora/"; public static final String ENCODING = "UTF-8"; public static final String COMMENT = "Object published through VUE"; public static final boolean VERSIONABLE = true; public static final String RESOURCE_DS = "RESOURCE"; public static final String DC_DS = "DC"; public static final String VUE_DS = "map.vue"; public static final String FORMAT = "foxml1.0"; public static final String VUE_FORMAT_URL = "http://vue.tufts.edu/docs/vueformat/"; public static final String ONT_TYPE_METADATA = "http://vue.tufts.edu/ontology/vue.rdfs#ontoType"; public static final String FEDORA_ONTOLOGY = "http://www.fedora.info/definitions/1/0/fedora-relsext-ontology.rdfs#"; public static final String DC_URL = VueResources.getString("metadata.dublincore.url"); public static final String RELS_URL ="http://www.w3.org/1999/02/22-rdf-syntax-ns#"; public static final String VUE_MIME_TYPE ="application/vue"; public static final String XML_MIME_TYPE ="text/xml"; public static final String DC_LABEL = "Dublin Core Metadata"; public static final String RELS_LABEL ="Relationships to other objects"; public static final String MAP_DS = "map.vue"; public static final String RELS_DS = "RELS-EXT"; public static final String VUE_CM = "tufts/vue/map/generic"; public static final String OTHER_CM = "tufts/vue/other"; public static final String REMOTE_CM = "tufts/vue/remote"; public static final String RESULT_FIELDS[] = {"pid"}; public static final String FILE_PREFIX = "file://"; static SimpleDateFormat formatter = new java.text.SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'.000Z'"); /** Creates a new instance of FedoraExporter */ public FedoraPublisher() { } public static void uploadMap(edu.tufts.vue.dsm.DataSource ds, LWMap map) throws Exception { addObjectToRepository(ds,VUE_CM,map.getFile(),map,map); } public static void uploadArchive(edu.tufts.vue.dsm.DataSource ds, LWMap map) throws Exception { System.out.println("Saving archive to repository: "+map.getFile()); //check if the file ends with vpk extension String mapName = map.getFile().getName(); if(mapName.endsWith(VueUtil.VueArchiveExtension)){ addObjectToRepository(ds,VUE_CM,map.getFile(),map,map); } else { String archiveFilePath = map.getFile().getAbsolutePath(); archiveFilePath = archiveFilePath.substring(0,archiveFilePath.length()-4)+VueUtil.VueArchiveExtension; File archiveFile = new File(archiveFilePath); tufts.vue.action.Archive.writeArchive(map,archiveFile); System.out.println("Writing Archival Object:"+archiveFile); addObjectToRepository(ds,VUE_CM,archiveFile,map,map); } } public static void uploadMapAll(edu.tufts.vue.dsm.DataSource ds, LWMap map) throws Exception{ Properties properties = ds.getConfiguration(); String mapLabel = map.getLabel(); File origFile = map.getFile(); File tempFile = new File(VueUtil.getDefaultUserFolder()+File.separator+origFile.getName()); tempFile.deleteOnExit(); tufts.vue.action.ActionUtil.marshallMap(tempFile,map); LWMap cloneMap = tufts.vue.action.OpenAction.loadMap(tempFile.getAbsolutePath()); Iterator i = cloneMap.getAllDescendents(LWComponent.ChildKind.PROPER).iterator(); while(i.hasNext()) { LWComponent component = (LWComponent) i.next(); if(component.hasResource() && (component instanceof LWNode || component instanceof LWLink) && (component.getResource() instanceof URLResource)){ URLResource resource = (URLResource) component.getResource(); String pid = getFedoraPid(component); if(resource.isLocalFile()) { File localFile = new File(resource.getSpec().replace(FILE_PREFIX,"")); addObjectToRepository(ds,OTHER_CM, localFile, component, cloneMap); String ingestUrl = HTTP+"://"+properties.getProperty("fedora22Address")+":"+properties.getProperty("fedora22Port")+FEDORA_URL_PATH+"get/"+pid+"/"+RESOURCE_DS; component.setResource(URLResource.create(ingestUrl)); } else if(!(resource instanceof Osid2AssetResource)) { addObjectToRepository(ds,REMOTE_CM,null,component,cloneMap); String ingestUrl = HTTP+"://"+properties.getProperty("fedora22Address")+":"+properties.getProperty("fedora22Port")+FEDORA_URL_PATH+"get/"+pid+"/"+RESOURCE_DS; component.setResource(URLResource.create(ingestUrl)); } // System.out.println("Replacing resource: "+resource+ " with "+ingestUrl+" resource is "+resource.getClass()); } } tufts.vue.action.ActionUtil.marshallMap(tempFile,cloneMap); uploadMap(ds,cloneMap); tufts.vue.action.ActionUtil.marshallMap(origFile, map); } private static void addObjectToRepository(edu.tufts.vue.dsm.DataSource ds,String cModel,File file,LWComponent comp,LWMap map) throws Exception{ Properties properties = ds.getConfiguration(); System.setProperty("javax.net.ssl.trustStore", properties.getProperty("fedora22TrustStore")); System.setProperty("javax.net.ssl.trustStorePassword",properties.getProperty("fedora22TrustStorePassword")); FedoraClient fc = new FedoraClient(HTTPS+"://"+properties.getProperty("fedora22Address")+":"+properties.getProperty("fedora22SecurePort")+FEDORA_URL_PATH, properties.getProperty("fedora22UserName"), properties.getProperty("fedora22Password")); String pid = getFedoraPid(comp); AutoFinder af = new AutoFinder(fc.getAPIA()); FieldSearchQuery query = new FieldSearchQuery(); Condition conds[] = new Condition[1]; conds[0] = new Condition(); //"pid",ComparisonOperator.eq,mapPid); conds[0].setProperty("pid"); conds[0].setOperator(ComparisonOperator.eq); conds[0].setValue(pid); query.setConditions(conds); FieldSearchResult result = af.findObjects(RESULT_FIELDS,1,query); if(result.getResultList().length >0 ) { modifyObject(fc,properties,cModel,file,comp,map); } else { addObject(fc,properties,cModel,file,comp,map); } } private static void addObject(FedoraClient fc,Properties p, String cModel,File file,LWComponent comp,LWMap map) throws Exception{ String ingestFoxml = getDigitalObjectXML(p,comp,map,cModel,file); BufferedWriter writer = new BufferedWriter(new FileWriter("C:\\temp\\IngestTest.xml")); writer.write(ingestFoxml); writer.close(); System.out.println("INGEST XML:\n"+ingestFoxml); StringBufferInputStream s = new StringBufferInputStream(ingestFoxml); AutoIngestor.ingestAndCommit(fc.getAPIA(), fc.getAPIM(), s,FORMAT, COMMENT); } private static void modifyObject(FedoraClient fc,Properties p, String cModel,File file,LWComponent comp,LWMap map) throws Exception{ String pid = getFedoraPid(comp); String dsName = RESOURCE_DS; String mimeType =getMimeType(file,comp); if(cModel.equals(VUE_CM)) { dsName = VUE_DS; mimeType =VUE_MIME_TYPE; } String dcXML= getDC(comp,comp.getLabel(),pid); fc.getAPIM().modifyDatastreamByValue(pid,DC_DS,null,DC_LABEL,XML_MIME_TYPE,DC_URL,dcXML.getBytes(),null,null,COMMENT,true); // modifying rels-ext for non VUE_CM if(!cModel.equals(VUE_CM)){ fc.getAPIM().modifyDatastreamByValue(pid,RELS_DS,null,RELS_LABEL,XML_MIME_TYPE,RELS_URL, getRDFDescriptionForLWComponent(comp,map).getBytes(),null,null,COMMENT,true); } if(cModel.equals(REMOTE_CM)){ fc.getAPIM().modifyDatastreamByReference(pid, dsName, null,comp.getLabel(), mimeType, VUE_FORMAT_URL, comp.getResource().getSpec(), null,null, COMMENT,true); }else { dsName = file.getName(); Uploader uploader = new Uploader(HTTPS, p.getProperty("fedora22Address"),Integer.parseInt(p.getProperty("fedora22SecurePort")),p.getProperty("fedora22UserName"), p.getProperty("fedora22Password")); String uploadId = uploader.upload(file); fc.getAPIM().modifyDatastreamByReference(pid, dsName, null,comp.getLabel(), mimeType, VUE_FORMAT_URL, uploadId, null,null, COMMENT,true); } } private static String getDigitalObjectXML(Properties p,LWComponent comp,LWMap map,String cModel,File file) throws Exception{ String pid = getFedoraPid(comp); String label = comp.getLabel(); StringBuffer xml = new StringBuffer(); xml.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"); xml.append("<foxml:digitalObject xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n"); xml.append(" xmlns:foxml=\"info:fedora/fedora-system:def/foxml#\"\n"); xml.append(" xsi:schemaLocation=\"info:fedora/fedora-system:def/foxml# http://www.fedora.info/definitions/1/0/foxml1-0.xsd\""); xml.append("\n PID=\""+ pid + "\">\n"); xml.append(" <foxml:objectProperties>\n"); xml.append(" <foxml:property NAME=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#type\" VALUE=\"FedoraObject\"/>\n"); xml.append(" <foxml:property NAME=\"info:fedora/fedora-system:def/model#label\" VALUE=\"" + label + "\"/>\n"); xml.append(" <foxml:property NAME=\"info:fedora/fedora-system:def/model#contentModel\" VALUE=\"" + cModel + "\"/>\n"); xml.append(" <foxml:property NAME=\"info:fedora/fedora-system:def/model#ownerId\" VALUE=\""+p.getProperty("fedora22UserName")+"\"/>"); xml.append(" </foxml:objectProperties>\n"); xml.append(getDCXML(comp)); if(!cModel.equals(VUE_CM)) { xml.append( getRelsXML(comp,map)); } xml.append(getOjectDSXML(p,comp,cModel,file)); xml.append("</foxml:digitalObject>"); String objXML = xml.toString(); return objXML; } private static String getOjectDSXML(Properties p,LWComponent comp,String cModel, File file) throws Exception { System.out.println("Getting object XML for "+comp.getLabel()+" file: "+file); String r = ""; String dateString = getDateString(); String uploadId = new String(); String pid = getFedoraPid(comp); String dsName = RESOURCE_DS; String mimeType = getMimeType(file,comp); String controlGroup = "M"; String contentLocationType = "INTERNAL_ID"; if(cModel.equals(VUE_CM)) { dsName = file.getName(); mimeType =VUE_MIME_TYPE; r += getDSXML("R",MAP_DS,dateString,comp.getLabel(),"http://local.fedora.server/fedora/get/"+pid+"/"+dsName,"URL",mimeType); } if(!cModel.equals(REMOTE_CM)){ //dsName = URLEncoder.encode(file.getName(), ENCODING); dsName = file.getName(); //Uploader uploader = new Uploader(HTTPS, p.getProperty("fedora22Address"),Integer.parseInt(p.getProperty("fedora22SecurePort")),p.getProperty("fedora22UserName"), edu.tufts.vue.util.Encryption.decrypt(p.getProperty("fedora22Password"))); Uploader uploader = new Uploader(HTTPS, p.getProperty("fedora22Address"),Integer.parseInt(p.getProperty("fedora22SecurePort")),p.getProperty("fedora22UserName"), p.getProperty("fedora22Password")); uploadId = uploader.upload(file); r+= getDSXML("R",RESOURCE_DS,dateString,comp.getLabel(), "http://local.fedora.server/fedora/get/"+pid+"/"+dsName,"URL",mimeType); } else { controlGroup = "E"; contentLocationType = "URL"; uploadId = comp.getResource().getSpec(); } return r+ getDSXML(controlGroup,dsName,dateString,comp.getLabel(), uploadId,contentLocationType,mimeType); } public static String getDSXML(String controlGroup,String dsName,String dateString,String label, String uploadId,String contentLocationType, String mimeType) { StringBuffer xml = new StringBuffer(); xml.append("<foxml:datastream CONTROL_GROUP=\""+controlGroup+"\" ID=\""+dsName+"\" STATE=\"A\" VERSIONABLE=\"true\">\n"); xml.append("<foxml:datastreamVersion CREATED=\""+dateString+"\" FORMAT_URI=\"http://vue.tufts.edu/docs/vueformat/\""); xml.append(" ID=\""+dsName+".0\" LABEL=\""+label+"\" MIMETYPE=\""+mimeType+"\">\n"); xml.append("<foxml:contentDigest DIGEST=\"none\" TYPE=\"DISABLED\"/>\n"); xml.append("<foxml:contentLocation REF=\""+uploadId+"\" TYPE=\""+contentLocationType+"\"/>\n"); xml.append("</foxml:datastreamVersion></foxml:datastream>\n"); return xml.toString(); } private static String getDCXML(LWComponent comp) { String dateString = getDateString(); StringBuffer xml = new StringBuffer(); xml.append("<foxml:datastream CONTROL_GROUP=\"X\" ID=\"DC\" STATE=\"A\" VERSIONABLE=\"true\">\n"); xml.append("<foxml:datastreamVersion CREATED=\""+dateString+"\" ID=\"DC1.0\" LABEL=\"Dublin Core Metadata\" MIMETYPE=\"text/xml\">\n"); xml.append("<foxml:contentDigest DIGEST=\"none\" TYPE=\"DISABLED\"/>\n"); xml.append(" <foxml:xmlContent>\n"); xml.append(getDC(comp,comp.getLabel(),getFedoraPid(comp))); xml.append("</foxml:xmlContent></foxml:datastreamVersion></foxml:datastream>\n"); return xml.toString(); } private static String getDC(LWComponent c,String title,String identifier) { String dc = new String(); // System.out.println("getDC: LWComponent: "+c+ " metadata elements: "+ c.getMetadataList().getMetadata().size()); dc +="<oai_dc:dc xmlns:dc=\"http://purl.org/dc/elements/1.1/\" xmlns:oai_dc=\"http://www.openarchives.org/OAI/2.0/oai_dc/\">"; dc += "<dc:title>"+title+"</dc:title>"; dc += "<dc:identifier>"+identifier+"</dc:identifier>"; if(c.getNotes() != null) { dc += "<dc:description>"+c.getNotes()+"</dc:description>"; } for(VueMetadataElement element: c.getMetadataList().getMetadata()) { // System.out.println("Publishing Metadata: key:"+element.getKey()+ " value: "+ element.getValue()+" for "+c.getLabel()); if(element.getKey().contains(DC_URL)) { String key = "dc:"+element.getKey().substring(DC_URL.length()+1).toLowerCase(); dc += "<"+key+">"+element.getValue()+"</"+key+">"; } } dc += "</oai_dc:dc>"; return dc; } private static String getRelsXML(LWComponent comp,LWMap map) throws Exception { String dateString = getDateString(); StringBuffer xml = new StringBuffer(); xml.append("<foxml:datastream CONTROL_GROUP=\"X\" ID=\"RELS-EXT\" STATE=\"A\" VERSIONABLE=\"true\">\n"); xml.append("<foxml:datastreamVersion CREATED=\""+dateString+"\" ID=\"RELS-EXT.0\" LABEL=\"Relationships to other objects\" MIMETYPE=\"text/xml\">\n"); xml.append("<foxml:xmlContent>\n"); xml.append(getRDFDescriptionForLWComponent(comp,map)); xml.append("</foxml:xmlContent></foxml:datastreamVersion></foxml:datastream>"); return xml.toString(); } private static String getRDFDescriptionForLWComponent(LWComponent comp,LWMap map) { String rdfDescription = new String(); rdfDescription = "<rdf:RDF xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\" xmlns:rel=\"info:fedora/fedora-system:def/relations-external#\">"; rdfDescription += "<rdf:Description rdf:about=\"info:fedora/"+getFedoraPid(comp)+"\">"; for(LWComponent c: map.getAllDescendents(LWComponent.ChildKind.PROPER)) { for(VueMetadataElement element: c.getMetadataList().getMetadata()) { if(DEBUG.RDF) System.out.println("METADATA: "+element.getValue()+" key: "+element.getKey()+" LWComponent: "+comp.getLabel() ); if(element.getKey().equals(ONT_TYPE_METADATA) && element.getValue().startsWith(FEDORA_ONTOLOGY) && c instanceof LWLink){ LWLink link = (LWLink)c; LWComponent head = link.getHead(); if(getFedoraPid(head).equals(getFedoraPid(comp))) { if(DEBUG.RDF) System.out.println("METADATA MATCH COMPONENT: "+element.getValue()+" key: "+element.getKey()+" LWComponent: "+comp.getLabel() +" Link:"+link); LWComponent tail = link.getTail(); rdfDescription += "<rel:"+getFedoraOntologyTerm(element.getValue())+" rdf:resource=\"info:fedora/"+getFedoraPid(tail)+"\" />\n"; } } } } rdfDescription += "<rel:IsPartOf rdf:resource=\"info:fedora/"+getFedoraPid(map)+"\" />"; rdfDescription += "</rdf:Description>"; rdfDescription += "</rdf:RDF>"; return rdfDescription; } private static String getFedoraPid(LWComponent component) { return "vue:"+component.getURIString().substring(component.getURIString().lastIndexOf("/")+1); } private static String getFedoraOntologyTerm(String value) { String term = new String(); term = value.substring(FEDORA_ONTOLOGY.length()); term = term.replaceAll(" ",""); return term; } private static String getDateString() { Date currentTime = new Date(); return formatter.format(currentTime); } private static String getMimeType(File file, LWComponent comp) { String mimeType = "text/html"; if(file!= null) { mimeType = new MimetypesFileTypeMap().getContentType(file) ; } else{ mimeType = new MimetypesFileTypeMap().getContentType(comp.getResource().getSpec()); } return mimeType; } }