Java tutorial
/** ========================================================================= * * Copyright (C) 2011, 2012 IBM Corporation * * based on work of * * Copyright (C) 2006, 2007 TAO Consulting Pte <http://www.taoconsulting.sg/> * * All rights reserved. * * ========================================================================== * * * * Licensed under the Apache License, Version 2.0 (the "License"). You may * * not use this file except in compliance with the License. You may obtain a * * copy of the License at <http://www.apache.org/licenses/LICENSE-2.0>. * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * * License for the specific language governing permissions and limitations * * under the License. * * * * ========================================================================== **/ package com.ibm.xsp.webdav.resource; import java.io.File; import java.io.InputStream; import java.io.OutputStream; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import java.util.Date; import java.util.Vector; import lotus.domino.Base; import lotus.domino.DateTime; import lotus.domino.Item; import lotus.domino.Database; import lotus.domino.Document; import lotus.domino.DocumentCollection; import lotus.domino.EmbeddedObject; import lotus.domino.NotesException; import lotus.domino.Session; import lotus.domino.View; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.xerces.impl.dv.util.Base64; import biz.taoconsulting.dominodav.exceptions.DAVNotFoundException; import biz.taoconsulting.dominodav.interfaces.IDAVAddressInformation; import biz.taoconsulting.dominodav.interfaces.IDAVRepository; import biz.taoconsulting.dominodav.interfaces.IDAVResource; import com.ibm.xsp.webdav.domino.DocumentInputStream; import com.ibm.xsp.webdav.domino.DocumentOutputStream; import com.ibm.xsp.webdav.domino.DominoProxy; import com.ibm.xsp.webdav.repository.DAVRepositoryDominoDocuments; /** * A WebDAV resource is an addressable Web object, such as a file or directory. * An ordinary resource can be viewed as a file. It can have a content body of * any MIME type [RFC2045], [RFC2046], including HTML-formatted text, other * text, an image, an executable, or an Office document. It can have locks and * properties. The specification for URI Syntax [RFC2396] defines a resource as * "anything that has identity." HTTP/1.1 [RFC2616] defines a resource both as * "a network data object or service" and "anything that has a URI." The WebDAV * specification does not redefine a resource but works from these definitions. * * @author Stephan H. Wissel */ public class DAVResourceDominoDocuments extends DAVResourceDomino { /** * Directory composed out of temp directory, username, unid and File name */ private String tempFileDir; /** * We need to ensure that a document is considered a collection */ @Override public boolean isCollection() { return super.isCollection(); // if (!("NotesAttachment".equals(this.getResourceType()))) { // return true; // } // return false; } /** * Logger for Errors */ private static final Log LOGGER = LogFactory.getLog(DAVResourceDominoDocuments.class); /** * @param repository * the repository the Resource is in * @param url * the path relative to the repository -- as seen from the * browser * @throws DAVNotFoundException * --- if the file is not there */ public DAVResourceDominoDocuments(IDAVRepository repository, String url) throws DAVNotFoundException { setup(repository, url, false); // this.setOwner(repository); // this.setPublicHref(url); // this.populateAttachmentPropertiesFromNotesDoc(); } /** * Light version * * @param repository */ public DAVResourceDominoDocuments(IDAVRepository repository) { this.setOwner(repository); this.setPublicHref(""); } /** * @param rep * The repository * @param url * the requested path -- as seen from the browser * @param isMember * - for directories: is it listed as part of the parent or by * itself? * @throws DAVNotFoundException * -- resource might not be there */ public DAVResourceDominoDocuments(IDAVRepository rep, String url, boolean isMember) throws DAVNotFoundException { setup(rep, url, isMember); // this.setOwner(rep); // this.setPublicHref(url); // this.setMember(isMember); // this.populateAttachmentPropertiesFromNotesDoc(); } public DAVResourceDominoDocuments(IDAVRepository rep, String url, boolean isMember, boolean forceCreate) throws DAVNotFoundException { setup(rep, url, isMember, forceCreate); // this.setOwner(rep); // this.setPublicHref(url); // this.setMember(isMember); // this.populateAttachmentPropertiesFromNotesDoc(); } /** * @see biz.taoconsulting.dominodav.resource.DAVAbstractResource#delete() */ public boolean delete() { Document curDoc = null; String notesURL = this.getInternalAddress(); curDoc = DominoProxy.getDocument(notesURL); if (curDoc != null) { try { curDoc.remove(true); return true; } catch (NotesException ne) { return false; } } return false; } /** * @see biz.taoconsulting.dominodav.resource.DAVAbstractResource#getOutputStream() */ public OutputStream getOutputStream() { // This returns the OutputStream when writing back to the class if (this.out == null) { this.out = new DocumentOutputStream(this); } return this.out; } /** * @see biz.taoconsulting.dominodav.resource.DAVAbstractResource#getStream() * Originally I tried EmbeddedObject.getInputStream(); but that didn't * go down well with the servlet, so now I use a temp file approach * where an attachment is stored into a temp file and then served to * the servlet as fileinput stream */ public InputStream getStream() { Session s = null; InputStream curStream = null; String notesURL = this.getInternalAddress(); // LOGGER.info("NotesUrl="+notesURL); Document curDoc = null; s = DominoProxy.getUserSession(); if (s != null) { try { // We need to find the $File to isolate the document int dollarFile = notesURL.lastIndexOf("/$File"); if (dollarFile < 0) { // This is not an attachment return null; } String docURL = notesURL.substring(0, dollarFile); // LOGGER.info("docURL="+docURL); curDoc = (Document) s.resolve(docURL); String curAttName = this.getName(); curAttName = java.net.URLDecoder.decode(curAttName, "utf-8"); // LOGGER.info("curAttName="+curAttName); EmbeddedObject curAttachment = curDoc.getAttachment(curAttName); if (curAttachment == null) { LOGGER.info("Attachment is null"); } File tempFile = this.getTempfile(); // Delete if it exists if (tempFile.exists()) { tempFile.delete(); } curAttachment.extractFile(tempFile.getAbsolutePath()); LOGGER.info("Current attachment path extracted is =" + tempFile.getAbsolutePath()); curStream = new DocumentInputStream(tempFile, this); } catch (Exception e) { LOGGER.error(e); } } return curStream; } /** * @param notesURL * The attachment/document to be processed * @param notesViewMember * Name of document/attachment in view * @return true/false if resource population worked or not */ public void fetchChildren() { // LOGGER.info(getCallingMethod()+":"+"Start fetchChildren.."); if (this.isMember()) { // LOGGER.info(getCallingMethod()+":"+"No fetch children for isMember()= true"); return; } // We fetch the right type of children String resType = this.getResourceType(); // LOGGER.info(getCallingMethod()+":"+"This resource is not a member; so start fetching.."); try { if ("NotesDocument".equals(resType)) { // LOGGER.info(getCallingMethod()+":"+"Resource is a NotesDocument; Start fetchingChildren for it...!"); this.fetchChildrenForNotesDocument(); // LOGGER.info(getCallingMethod()+":"+"End fetching children for NotesDocument OK!"); } else if ("NotesAttachment".equals(resType)) { // Notes Attachments don't have children // LOGGER.info(getCallingMethod()+":"+"Resource is a NotesAttachment.. NO IMPLEMENTATION!"); } else if ("NotesDatabase".equals(resType)) { // LOGGER.info(getCallingMethod()+":"+"Resource is NotesDatabase; Start fetchingChildren for it..!"); this.fetchChildrenForNotesDatabase(); // LOGGER.info(getCallingMethod()+":"+"End fetching children for NotesDatabase OK!"); } else { // We presume a view for the resource type // LOGGER.info(getCallingMethod()+":"+"Resource is a View; Start fetching Children for it....!"); fetchChildrenForNotesView(); // LOGGER.info(getCallingMethod()+":"+"End fetching children for NotesView OK!"); } } catch (NotesException e) { } // LOGGER.info(getCallingMethod()+":"+"End function fetchChildren OK!"); } @SuppressWarnings("unchecked") private void fetchChildrenForNotesDocument() throws NotesException { // LOGGER.info(getCallingMethod()+":"+"Start fetchChildrenForNotesDocument; Fetching children for doc with UNID=" // + this.getDocumentUniqueID()); Document curDoc = null; // String docID = null; Vector<IDAVResource> resMembers = new Vector<IDAVResource>(); this.setMembers(resMembers); String notesURL = this.getInternalAddress(); // LOGGER.info("Internal Address is "+notesURL); // LOGGER.info("PublicHref is "+this.getPublicHref()); curDoc = DominoProxy.getDocument(notesURL); // LOGGER.info(getCallingMethod()+":"+"Currdoc not null ; OK"); if (curDoc == null) { LOGGER.error("Could not retrieve the document"); return; } boolean readOnly = this.checkReadOnlyAccess(curDoc); Date curCreationDate = curDoc.getCreated().toJavaDate(); if (curDoc.hasItem("DAVCreated")) { @SuppressWarnings("rawtypes") Vector times = curDoc.getItemValueDateTimeArray("DAVCreated"); Object time = times.elementAt(0); if (time.getClass().getName().endsWith("DateTime")) { curCreationDate = ((DateTime) time).toJavaDate(); } } Date curChangeDate = curDoc.getLastModified().toJavaDate(); if (curDoc.hasItem("DAVModified")) { @SuppressWarnings("rawtypes") Vector times = curDoc.getItemValueDateTimeArray("DAVModified"); Object time = times.elementAt(0); if (time.getClass().getName().endsWith("DateTime")) { curChangeDate = ((DateTime) time).toJavaDate(); } } this.setCreationDate(curCreationDate); this.setLastModified(curChangeDate); this.setReadOnly(readOnly); // Read the repository list to get the view try { // LOGGER.info(getCallingMethod()+":"+"Currdoc not null ; OK; Has UNID="+curDoc.getUniversalID()); // docID = curDoc.getUniversalID(); // LOGGER.info(getCallingMethod()+":"+"Openend document " + docID); // No children if there are no attachments if (!curDoc.hasEmbedded()) { // if(1==1){return;} // E.C. It is a directory, so fetch the children documents as // resources // LOGGER.info(getCallingMethod()+":"+"Current doc with unid="+curDoc.getUniversalID()+" has no embedded files. Try to find children"); DocumentCollection responses = curDoc.getResponses(); // LOGGER.info(getCallingMethod()+":"+"Get Responses..."); int numOfResponses = responses.getCount(); // LOGGER.info(getCallingMethod()+":"+"Current doc has "+String.valueOf(numOfResponses) // + " responses"); if (numOfResponses > 0) { resMembers = new Vector<IDAVResource>(numOfResponses); // LOGGER.info(getCallingMethod()+":"+"Start Process responses"); Document docResp = responses.getFirstDocument(); while (docResp != null) { // LOGGER.info(getCallingMethod()+":"+"Doc response has unid="+docResp.getUniversalID()+ // "; Try find attachment(s)"); Vector<String> allEmbedded = DominoProxy.evaluate("@AttachmentNames", docResp); int numOfAttachments = allEmbedded.isEmpty() ? 0 : (allEmbedded.get(0).toString().equals("") ? 0 : allEmbedded.size()); // LOGGER.info(getCallingMethod()+":"+"Doc has "+ // String.valueOf(numOfAttachments)+" attachment(s)"); if (numOfAttachments == 0) { // No attachments in here! // LOGGER.info(getCallingMethod()+":"+"Doc "+docResp.getUniversalID()+" response has no attachment; is a directory; Create resource for it"); DAVResourceDominoDocuments resAtt = new DAVResourceDominoDocuments(this.getRepository(), this.getPublicHref() + "/" + docResp.getItemValueString( ((DAVRepositoryDominoDocuments) (this.getRepository())) .getDirectoryField()), true); resAtt.setup(docResp); LOGGER.info(getCallingMethod() + ":" + "Created DavResourceDomino Attachments from getDocumentResource-OK"); this.getMembers().add(resAtt); // resMembers.add(resAtt); LOGGER.info(getCallingMethod() + ":" + "Resource successfull added"); } else { // LOGGER.info(getCallingMethod()+":"+"Doc response "+docResp.getUniversalID()+" has attachments >0; "); String curAttName = allEmbedded.get(0).toString(); if ((curAttName != null) && (!curAttName.equals(""))) { // LOGGER.info(getCallingMethod()+":"+"Doc response fitrst attachment has name "+curAttName); DAVResourceDominoDocuments resAtt = new DAVResourceDominoDocuments( this.getRepository(), this.getPublicHref() + "/" + curAttName, true); resAtt.setup(docResp); if (resAtt != null) { // Now add it to the Vector // LOGGER.info(getCallingMethod()+":"+"Created DAVResourceDominoDocuments with getAttachmentResource-OK!\n Start load resource"); // resMembers.add(curAttachment); this.getMembers().add(resAtt); // LOGGER.info(getCallingMethod()+":"+"Resource successfull added"); Date viewDate = this.getLastModified(); Date docDate = resAtt.getLastModified(); if (viewDate == null || (docDate != null && viewDate.before(docDate))) { this.setLastModified(docDate); } LOGGER.info(getCallingMethod() + ":" + "Resource successfull updated last modified"); // LOGGER.info(getCallingMethod()+":"+"Processing complete attachment:" // + curAttName); } } } // LOGGER.info(getCallingMethod()+":"+"Start recycling.."); docResp = responses.getNextDocument(docResp); // LOGGER.info(getCallingMethod()+":"+"Recycling OK!"); } // end while } // end if numresp>0 try { // LOGGER.info(getCallingMethod()+":"+"Final recycling.."); if (curDoc != null) { // curDoc.recycle(); } // LOGGER.info(getCallingMethod()+":"+"End FINAL recycling OK!"); } catch (Exception e) { LOGGER.error(e); } // Now save back the members to the main object // LOGGER.info(getCallingMethod()+":"+"Finish processing current doc as a directory; No more attachment(s) in it; Return!"); return; } // Get all attachments // LOGGER.info(getCallingMethod()+":"+"Current doc has attachments!"); @SuppressWarnings("rawtypes") Vector allEmbedded = DominoProxy.evaluate("@AttachmentNames", curDoc); int numOfAttchments = allEmbedded.size(); if (numOfAttchments == 0) { // No attachments in here! // LOGGER.info(getCallingMethod()+":"+"Something wrong: Doc + "+docID // + " has no attachments (@AttachmentNames)"); return; } // LOGGER.info(getCallingMethod()+":"+docID + " has " + new // Integer(numOfAttchments).toString() + " attachment(s)"); // Initialize an empty vector at the right size // We might need to enlarge it if we have more attachments resMembers = new Vector<IDAVResource>(numOfAttchments); // LOGGER.info(getCallingMethod()+":"+"Start processing attachment(s).."); for (int i = 0; i < numOfAttchments; i++) { String curAttName = allEmbedded.get(i).toString(); DAVResourceDominoDocuments curAttachment = getDocumentResource(curDoc); if (curAttachment != null) { // Now add it to the Vector // LOGGER.info(getCallingMethod()+":"+"Resource attachment successfully created!"); // resMembers.add(curAttachment); this.getMembers().add(curAttachment); // LOGGER.info("Resource attachment successfully added: " + // curAttName+"; OK!"); } else { LOGGER.error("Could not load attachment#" + curAttName + "#"); } } } catch (NotesException ne) { LOGGER.error(ne); } catch (Exception e) { LOGGER.error(e); } finally { try { // LOGGER.info(getCallingMethod()+":"+"Final block; Start Recycling!"); if (curDoc != null) { // curDoc.recycle(); } } catch (Exception e) { LOGGER.error(e); } // Now save back the members to the main object // this.setMembers(resMembers); // LOGGER.info("Completed reading attachments resources from Notes document; OK!"); } } private void fetchChildrenForNotesView() { // LOGGER.info(getCallingMethod()+":"+"Start fetchChildrenForNotesView; Fetching children for " // + // this.getName()+" with internal address= "+this.getInternalAddress()+" and public href= "+this.getPublicHref()); Document curDoc = null; this.setMembers(new Vector<IDAVResource>()); View curView = null; Database curDb = null; // Vector<IDAVResource> resMembers = null; String notesURL = this.getInternalAddress(); curView = DominoProxy.getView(notesURL); if (curView == null) { LOGGER.error("Could not retrieve view: " + notesURL); return; } // Read the repository list to get the view try { // LOGGER.info(getCallingMethod()+":"+"Openend view " + // curView.getName()); // Initialize an empty vector at the right size // We might need to enlarge it if we have more attachments // LOGGER.info( "View num doc is "+new // Integer(curView.getEntryCount()).toString()); for (int i = 0; i < curView.getEntryCount(); i++) { curDoc = curView.getNthDocument(i + 1); // LOGGER.info( "Start processing doc no "+ new // Integer(i).toString()); if (curDoc == null) { // LOGGER.info(getCallingMethod()+":"+this.getName() + // " does not (yet) contain resources"); return; } // LOGGER.info(getCallingMethod()+":"+"Start process view "); DAVResourceDominoDocuments docRes = null; if (curDoc.hasEmbedded()) { // LOGGER.info(getCallingMethod()+":"+"Document "+curDoc.getUniversalID()+ // " has embedded; Start Add Attachments"); // docRes = this.addAttachmentsFromDocument(curDoc); docRes = new DAVResourceDominoDocuments(this.getRepository()); LOGGER.info("DOCRES from att created ok; start setup"); docRes.setup(curDoc); // docRes.setCollection(false); // docRes.setMember(true); // LOGGER.info(getCallingMethod()+":"+"Successfully create attachments for "+curDoc.getUniversalID()); } else { // LOGGER.info(getCallingMethod()+":"+"Document "+ // curDoc.getUniversalID()+ // " has no attachment; try to get a resource"); docRes = new DAVResourceDominoDocuments(this.getRepository()); docRes.setup(curDoc); docRes.setCollection(true); docRes.setMember(false); // LOGGER.info(getCallingMethod()+":"+"Successfully create resource from doc "+docRes.getName()); } // TODO: Fix this! if (docRes != null) { // LOGGER.info(getCallingMethod()+":"+"Resource "+docRes.getName()+"created OK; Try to add to resMembers"); this.getMembers().add(docRes); // LOGGER.info(getCallingMethod()+":"+"Resources added OK;"); // Capture last modified based on the latest date of the // documents in view Date viewDate = this.getLastModified(); Date docDate = docRes.getLastModified(); if (viewDate == null || (docDate != null && viewDate.before(docDate))) { this.setLastModified(docDate); } // LOGGER.info(getCallingMethod()+":"+"Resource processes OK"); } // // // LOGGER.info(getCallingMethod()+":"+"Try recycle and find the next for "+curDoc.getUniversalID()+"...."); // Document oldDoc=curDoc; // curDoc = curView.getNextDocument(curDoc); // oldDoc.recycle(); // // LOGGER.info(getCallingMethod()+":"+"Recycle OK!"); // // // LOGGER.info("Next doc is "+((curDoc!=null)?"Not null":"null")); } // end for } catch (NotesException ne) { LOGGER.error(ne); } catch (Exception e) { LOGGER.error(e); } finally { try { // LOGGER.info(getCallingMethod()+":"+"Final recycle...."); if (curDoc != null) { // curDoc.recycle(); } if (curView != null) { curView.recycle(); } if (curDb != null) { curDb.recycle(); } // LOGGER.info(getCallingMethod()+":"+"Final recycle OK!"); } catch (Exception e) { LOGGER.error(e); } // LOGGER.info(getCallingMethod()+":"+"Completed reading file resources from Domino view"); // LOGGER.info(getCallingMethod()+":"+"Start to setMembers..."); // this.setMembers(resMembers); // LOGGER.info(getCallingMethod()+":"+"SetMembers OK! Exit fetchChildrenforNotesView"); } // Now save back the members to the main object } private void fetchChildrenForNotesDatabase() { // LOGGER.info(getCallingMethod()+":"+"Fetching children for " + // this.getName()); Document curDoc = null; Document nextDoc = null; DocumentCollection curEntries = null; Vector<IDAVResource> resMembers = null; String notesURL = this.getInternalAddress(); Database curDb = DominoProxy.getDatabase(notesURL); if (curDb == null) { LOGGER.error("Could not get the database " + notesURL); return; } // Read the repository list to get the view try { // LOGGER.info(getCallingMethod()+":"+"Openend databasew " + // curDb.getFileName()); // Initialize an empty vector at the right size // We might need to enlarge it if we have more attachments curEntries = curDb.getAllDocuments(); resMembers = new Vector<IDAVResource>(curEntries.getCount()); curDoc = curEntries.getFirstDocument(); if (curDoc == null) { // LOGGER.info(getCallingMethod()+":"+this.getName() + // " does not (yet) contain resources"); return; } while (curDoc != null) { nextDoc = curEntries.getNextDocument(curDoc); DAVResourceDominoDocuments docRes = this.addAttachmentsFromDocument(curDoc); if (docRes != null) { resMembers.add(docRes); } curDoc.recycle(); curDoc = nextDoc; } } catch (NotesException ne) { LOGGER.error(ne); } catch (Exception e) { LOGGER.error(e); } finally { try { if (curDoc != null) { curDoc.recycle(); } if (nextDoc != null) { nextDoc.recycle(); } if (curEntries != null) { curEntries.recycle(); } if (curDb != null) { curDb.recycle(); } } catch (Exception e) { LOGGER.error(e); } // LOGGER.info(getCallingMethod()+":"+"Completed reading file resources from Domino view"); } // Now save back the members to the main object this.setMembers(resMembers); } /** * Reads all attachments in a document and adds them to the resourcelist. * Since a document can contain more than one attachment we treat documents * as directories since webDAV from Windows/Linux ignores the URL and uses * the name to build the request URL * * @param s * @param curDoc * @param resMembers */ private DAVResourceDominoDocuments addAttachmentsFromDocument(Document curDoc) { // String docID = null; DAVResourceDominoDocuments docRes = null; try { // LOGGER.info(getCallingMethod()+":"+"Start addAttachmentsFromDocument "+curDoc.getUniversalID()); // docID = curDoc.getUniversalID(); if (!curDoc.hasEmbedded()) { // LOGGER.info(getCallingMethod()+":"+docID + // " has no attachments (hasEmbedded)"); } else { // LOGGER.info(getCallingMethod()+":"+docID + // " has attachments; start creating resource of type attachment(file)"); docRes = this.getDocumentResource(curDoc); // LOGGER.info(getCallingMethod()+":"+"End creating resource of type attachment!"); } } catch (NotesException e) { LOGGER.error(e); docRes = null; } // LOGGER.info(getCallingMethod()+":"+"Return docRes OK! "); return docRes; } private DAVResourceDominoDocuments getDocumentResource(Document curDoc) { // The result we are giving back DAVResourceDominoDocuments curRes = null; curRes = new DAVResourceDominoDocuments(this.getRepository()); curRes.setup(curDoc); // LOGGER.info(getCallingMethod()+":"+"End getDocumentResource OK!"); return curRes; } // This function overwrites the main function in DAVResourceDomino protected String getNameFromInternalAddress(String internalName) throws Exception { int lastSlash = internalName.lastIndexOf("/"); if (lastSlash < 0) { return internalName; } String candidate = internalName.substring(lastSlash + 1); int questionMarkPos = candidate.indexOf("?"); if (questionMarkPos < 0) { return candidate; } return candidate.substring(0, questionMarkPos); } /** * @return The file to read/write the data to since stream in attachments * doesn't seem to be reliable */ public File getTempfile() { // We check for a directory with the UNID of the resource // and write the file there String unid = this.getDocumentUniqueID(); File returnFile = null; // Check for the root temp Dir String rootTempDir = this.getRepository().getTempDir(); // Get the username in base64 encoded, so we can use it as temp file // name String userDir = null; try { String userName = DominoProxy.getUserName(); userDir = Base64.encode(userName.getBytes()); } catch (Exception e) { LOGGER.error(e); userDir = "Anonymous"; } // Save the values for reuse this.tempFileDir = rootTempDir + File.separator + userDir + File.separator + unid; // Create the directory if needed File curTempDir = new File(this.tempFileDir); if (!curTempDir.exists()) { // Create the directory structure - we keep the user dir curTempDir.mkdirs(); } else if (!curTempDir.isDirectory()) { // Very bad LOGGER.error("Tempdir exists and is not a directory: " + this.tempFileDir); return null; } // Update the full value this.tempFileDir = curTempDir.getAbsolutePath(); // Now create the file object String trueFileName = this.tempFileDir + File.separator + this.getName(); returnFile = new File(trueFileName); return returnFile; } /** * Removes the temporary file */ public void removeTempFiles() { try { // First the file, then the temp dir File fullFile = new File(this.tempFileDir + File.separator + this.getName()); if (fullFile.exists()) { fullFile.delete(); } fullFile = null; // Temp dir File docTempDir = new File(this.tempFileDir); // We only can remove the directory if it isn't empty // Other files might be opened in other tabs or windows if (docTempDir.exists()) { File[] content = docTempDir.listFiles(); if (content == null || content.length == 0) { String userTempDirName = docTempDir.getParent(); docTempDir.delete(); docTempDir = null; File userTempDir = new File(userTempDirName); if (userTempDir.exists()) { File[] otherTemp = userTempDir.listFiles(); if (otherTemp == null || otherTemp.length == 0) { userTempDir.delete(); } } } } } catch (Exception e) { LOGGER.error(e); } } public String getCallingMethod() { return trace(Thread.currentThread().getStackTrace(), 2); } public String getCallingMethod(int level) { return trace(Thread.currentThread().getStackTrace(), 2 + level); } private String trace(StackTraceElement e[], int level) { if (e != null && e.length >= level) { StackTraceElement s = e[level]; if (s != null) { return s.getMethodName(); } } return null; } @SuppressWarnings("deprecation") private void setup(Document curDoc) { try { // LOGGER.info(getCallingMethod()+":"+"Start setup..."); @SuppressWarnings("rawtypes") Vector allEmbedded = DominoProxy.evaluate("@AttachmentNames", curDoc); // LOGGER.info(getCallingMethod()+":"+"All Embedded computed"); int numOfAttachments = allEmbedded.isEmpty() ? 0 : (allEmbedded.get(0).equals("") ? 0 : allEmbedded.size()); String docID = curDoc.getUniversalID(); this.setDocumentUniqueID(docID); // LOGGER.info("Num of attachments="+new // Integer(numOfAttachments).toString()); boolean readOnly = this.checkReadOnlyAccess(curDoc); this.setReadOnly(readOnly); LOGGER.info("Creation date for " + curDoc.getUniversalID() + " =" + curDoc.getCreated().toString() + "; Time zone=" + curDoc.getCreated().getZoneTime() + "; Local time=" + curDoc.getCreated().getLocalTime()); Date curCreationDate = curDoc.getCreated().toJavaDate(); LOGGER.info("Current date in Java is " + curCreationDate.toString() + "Time zone=" + new Integer(curCreationDate.getTimezoneOffset()).toString() + "; Locale time is:" + curCreationDate.toLocaleString()); if (curDoc.hasItem("DAVCreated")) { // Item davCreated=curDoc.getFirstItem("DAVCreated"); @SuppressWarnings("rawtypes") Vector times = curDoc.getItemValueDateTimeArray("DAVCreated"); if (times != null) { if (times.size() > 0) { Object time = times.elementAt(0); if (time != null) { if (time.getClass().getName().endsWith("DateTime")) { curCreationDate = ((DateTime) time).toJavaDate(); if (curCreationDate == null) { curCreationDate = curDoc.getCreated().toJavaDate(); } } } } } } Date curChangeDate = curDoc.getLastModified().toJavaDate(); if (curDoc.hasItem("DAVModified")) { @SuppressWarnings("rawtypes") Vector times = curDoc.getItemValueDateTimeArray("DAVModified"); if (times != null) { if (times.size() > 0) { Object time = times.elementAt(0); if (time != null) { if (time.getClass().getName().endsWith("DateTime")) { curChangeDate = ((DateTime) time).toJavaDate(); if (curChangeDate == null) { curChangeDate = curDoc.getLastModified().toJavaDate(); } } } } } } this.setCreationDate(curCreationDate); this.setLastModified(curChangeDate); LOGGER.info("Creation date is set to " + this.getCreationDate().toString()); LOGGER.info("Last modified date is set to " + this.getLastModified().toString()); String pubHRef = ((IDAVAddressInformation) this.getRepository()).getPublicHref(); // LOGGER.info("THIS getpublichref="+this.getPublicHref()); String curAttName = null; if (numOfAttachments == 0) { // LOGGER.info(getCallingMethod()+":"+"Start setting resource"); this.setName(docID); String name = curDoc.getItemValueString( ((DAVRepositoryDominoDocuments) (this.getRepository())).getDirectoryField()); this.setName(name); if (this.getPublicHref().equals("")) { // try{ this.setPublicHref(pubHRef + "/" + name); // URLEncoder.encode(name, "UTF-8")); // }catch(UnsupportedEncodingException e){ // LOGGER.error(e); // } } this.setCollection(true); this.setInternalAddress( ((IDAVAddressInformation) this.getRepository()).getInternalAddress() + "/" + docID); this.setResourceType("NotesDocument"); this.setMember(false); this.setContentLength(0L); // this.fetchChildren(); } else { curAttName = allEmbedded.get(0).toString(); // LOGGER.info("Attachment name is "+curAttName); this.setMember(true); this.setResourceType("NotesAttachment"); if (this.getPublicHref().equals("")) { try { this.setPublicHref(pubHRef + "/" + URLEncoder.encode(curAttName, "UTF-8")); } catch (UnsupportedEncodingException e) { LOGGER.error(e); } // this.setPublicHref( pubHRef+"/"+curAttName); } this.setInternalAddress(((IDAVAddressInformation) this.getRepository()).getInternalAddress() + "/" + docID + "/$File/" + curAttName); this.setCollection(false); this.setName(curAttName); EmbeddedObject curAtt = curDoc.getAttachment(curAttName); if (curAtt == null) { // LOGGER.info("Error! Current Embedded is null"); return; } else { // LOGGER.info("Embedded is not null. OK! "); } Long curSize = new Long(curAtt.getFileSize()); this.setContentLength(curSize); } // LOGGER.info("Current res realized! pubHREF="+this.getPublicHref()+"; Internal Address="+this.getInternalAddress()+"; "); } catch (NotesException ne) { LOGGER.error("ERROR! Can not set; " + ne.getMessage()); } } private void setup(IDAVRepository rep, String url, boolean isMember, boolean forceCreate) throws DAVNotFoundException { this.setOwner(rep); DAVRepositoryDominoDocuments repository = (DAVRepositoryDominoDocuments) rep; String folderUrl = null; String fileName = null; try { url = java.net.URLDecoder.decode(url, "UTF-8"); } catch (Exception e) { } // LOGGER.info("setup with url="+url); if (url.lastIndexOf("/") > 0) { folderUrl = url.substring(0, url.lastIndexOf("/")); fileName = url.substring(url.lastIndexOf("/") + 1); } // LOGGER.info("Folder="+folderUrl+"; FileName="+fileName); if ((fileName != null) && (folderUrl != null)) { // LOGGER.info("in if"); DAVResourceDominoDocuments folder = new DAVResourceDominoDocuments(rep, folderUrl, false); if (folder != null) { // LOGGER.info("Folder not null"); Base notesObj = DominoProxy.resolve(((DAVRepositoryDominoDocuments) this.getRepository()) .getInternalAddressFromExternalUrl(folderUrl, "")); Database db = null; Document docParent = null; if (notesObj instanceof View) { // LOGGER.info("isView"); View notesView = (View) notesObj; try { db = notesView.getParent(); } catch (NotesException e) { } } else { if (notesObj instanceof Document) { docParent = (Document) notesObj; // LOGGER.info("is doc"); try { db = docParent.getParentDatabase(); } catch (NotesException e) { } } } if (db != null) { try { Document doc = db.createDocument(); String pubhref = folderUrl; if (pubhref.startsWith(repository.getPublicHref())) { pubhref = pubhref.substring(repository.getPublicHref().length()); } doc.replaceItemValue(repository.getPubHrefField(), pubhref + "/" + fileName); doc.replaceItemValue("Form", ((DAVRepositoryDominoDocuments) rep).getFileFormName()); doc.computeWithForm(true, false); Session s = DominoProxy.getUserSession(); // NotesSession Item webdavAuthor = doc.replaceItemValue("AuthorDAV", s.getEffectiveUserName()); webdavAuthor.setSummary(true); webdavAuthor.setAuthors(true); if (docParent != null) { doc.makeResponse(docParent); } if (!isMember) { // is collection doc.replaceItemValue("Form", ((DAVRepositoryDominoDocuments) rep).getDirectoryFormName()); doc.replaceItemValue(((DAVRepositoryDominoDocuments) rep).getDirectoryField(), fileName); } doc.save(); this.setDocumentUniqueID(doc.getUniversalID()); this.setPublicHref(url); this.setName(fileName); this.setMember(isMember); if (isMember) { this.setInternalAddress( ((IDAVAddressInformation) this.getRepository()).getInternalAddress() + "/" + doc.getUniversalID() + "/$File/" + this.getName()); this.setCollection(false); } else { this.setInternalAddress( ((IDAVAddressInformation) this.getRepository()).getInternalAddress() + "/" + doc.getUniversalID()); this.setCollection(true); } } catch (NotesException ne) { } } } } // this.setDominoResourceType(); } private void setup(IDAVRepository rep, String url, boolean isMember) throws DAVNotFoundException { // Store a link to the repository this.setOwner(rep); try { url = java.net.URLDecoder.decode(url, "UTF-8"); } catch (Exception e) { } // LOGGER.info("DAVResouceDomino for "+url+"; Directory field="+((DAVRepositoryDominoDocuments)(this.getRepository())).getDirectoryField()); try { // url=java.net.URLDecoder.decode(url, "utf-8"); // url=url.replace('+', ' '); } catch (Exception e) { } // The path can't be null and can't be empty. if it is empty we use "/" if (url == null || url.equals("")) { url = new String("/"); } String unid = null; try { unid = this.getNameFromInternalAddress(url); } catch (Exception e) { LOGGER.error(e); } if (isValidUNID(unid) || (url.equals("/"))) { // is a document this.setCollection(true); } else { this.setCollection(false); } // Memorize the url requested try { this.setPublicHref(URLEncoder.encode(url, "UTF-8")); } catch (UnsupportedEncodingException e) { LOGGER.error(e); } this.setPublicHref(url); // Get the file-path and a new file LOGGER.info("Input url=" + url); String fpath = rep.getInternalAddressFromExternalUrl(url, "DAVREsourceDomino-setup"); // Keep the address IDAVAddressInformation repAdr = (IDAVAddressInformation) this.getRepository(); LOGGER.info("-----repositoryInternalAddr=" + repAdr.getInternalAddress()); LOGGER.info("FPATH=" + fpath); LOGGER.info("-----repositorypubhref=" + repAdr.getPublicHref()); LOGGER.info("url=" + url); // if(repAdr.getInternalAddress().equals(fpath) && // (!url.startsWith(repAdr.getPublicHref()))){ // throw new DAVNotFoundException(); // } if (fpath.equals("")) { throw new DAVNotFoundException(); } this.setInternalAddress(fpath); // LOGGER.info("Output url="+fpath); // FIXME XXX TODO Borked code! // Next check -- if Repository and Resource have the same path then the // resource it top level if (fpath.equals(((IDAVAddressInformation) rep).getInternalAddress())) { // LOGGER.info("Repository and Resource address match:"+fpath); this.setName(((IDAVAddressInformation) rep).getName()); // LOGGER.info(this.getName()+" is the repository-resource at "+this.getInternalAddress()); this.setCollection(true); this.setResourceType("DominoRepository"); this.setMember(false); } else { // It is a notes artifact String newName = null; try { newName = this.getNameFromInternalAddress(this.getInternalAddress()); } catch (Exception e) { LOGGER.error(e); } try { newName = java.net.URLDecoder.decode(newName, "utf-8"); } catch (Exception e) { } this.setName(newName); this.setDominoResourceType(); this.validateResourceExists(); String intAddress = this.getInternalAddress(); int lastFile = intAddress.lastIndexOf("/$File/"); if (lastFile > 0) { intAddress = intAddress.substring(0, lastFile); // LOGGER.info("Try resolve doc with internal address="+intAddress); Base notesObj = DominoProxy.resolve(intAddress); if (notesObj == null) { } else { if (notesObj instanceof Document) { Document curDoc = (Document) notesObj; try { this.setDocumentUniqueID(curDoc.getUniversalID()); boolean readOnly = this.checkReadOnlyAccess(curDoc); this.setReadOnly(readOnly); // LOGGER.info("Resolved to info doc "+curDoc.getUniversalID()); Date curCreationDate = curDoc.getCreated().toJavaDate(); if (curDoc.hasItem("DAVCreated")) { @SuppressWarnings("rawtypes") Vector times = curDoc.getItemValueDateTimeArray("DAVCreated"); if (times != null) { Object time = times.elementAt(0); if (time != null) { if (time.getClass().getName().endsWith("DateTime")) { curCreationDate = ((DateTime) time).toJavaDate(); if (curCreationDate == null) { curCreationDate = curDoc.getCreated().toJavaDate(); } } } } } Date curChangeDate = curDoc.getLastModified().toJavaDate(); if (curDoc.hasItem("DAVModified")) { @SuppressWarnings("rawtypes") Vector times = curDoc.getItemValueDateTimeArray("DAVModified"); if (times != null) { Object time = times.elementAt(0); if (time != null) { if (time.getClass().getName().endsWith("DateTime")) { curChangeDate = ((DateTime) time).toJavaDate(); if (curChangeDate == null) { curChangeDate = curDoc.getLastModified().toJavaDate(); } } } } } this.setCreationDate(curCreationDate); this.setLastModified(curChangeDate); EmbeddedObject curAtt = curDoc.getAttachment(this.getName()); // Content length if (curAtt != null) { this.setContentLength(new Long(curAtt.getFileSize()).longValue()); } } catch (NotesException e) { } } else { } } // end else if // TODO: figure out read/write access LOGGER.debug(this.getName() + " is a " + this.getResourceType() + " resource at " + this.getInternalAddress()); } else { Base notesObj = DominoProxy.resolve(intAddress); if (notesObj == null) { } else { if (notesObj instanceof Document) { Document curDoc = (Document) notesObj; try { this.setDocumentUniqueID(curDoc.getUniversalID()); boolean readOnly = this.checkReadOnlyAccess(curDoc); this.setReadOnly(readOnly); String name = curDoc.getItemValueString( ((DAVRepositoryDominoDocuments) (this.getRepository())).getDirectoryField()); this.setName(name); } catch (NotesException ne) { } } } } } this.setMember(isMember); if (!this.isMember()) { // search for members (children) this.fetchChildren(); } } private boolean isValidUNID(String unid) { if (unid.length() != 32) { return false; } for (int i = 0; i < 16; i++) { if (!(((unid.charAt(i) <= '9') && (unid.charAt(i) >= '0')) || ((unid.charAt(i) <= 'F') && (unid.charAt(i) >= 'A')))) { return false; } } return true; } public String getTempfileName() { // We check for a directory with the UNID of the resource // and write the file there String unid = this.getDocumentUniqueID(); File returnFile = null; // Check for the root temp Dir String rootTempDir = this.getRepository().getTempDir(); // Get the username in base64 encoded, so we can use it as temp file // name String userDir = null; try { String userName = DominoProxy.getUserName(); userDir = Base64.encode(userName.getBytes()); } catch (Exception e) { LOGGER.error(e); userDir = "Anonymous"; } // Save the values for reuse this.tempFileDir = rootTempDir + File.separator + userDir + File.separator + unid; // Create the directory if needed File curTempDir = new File(this.tempFileDir); if (!curTempDir.exists()) { // Create the directory structure - we keep the user dir curTempDir.mkdirs(); } else if (!curTempDir.isDirectory()) { // Very bad LOGGER.error("Tempdir exists and is not a directory: " + this.tempFileDir); return null; } // Update the full value this.tempFileDir = curTempDir.getAbsolutePath(); // Now create the file object String trueFileName = this.tempFileDir + File.separator + this.getName(); returnFile = new File(trueFileName); if (returnFile.exists()) { return trueFileName; } return ""; } public void patchCreationDate(Date date) { Document curDoc = null; String notesURL = this.getInternalAddress(); curDoc = DominoProxy.getDocument(notesURL); if (curDoc == null) { return; } if (curDoc instanceof Document) { try { Session ses = DominoProxy.getUserSession(); DateTime dt = ses.createDateTime(date); curDoc.replaceItemValue("DAVCreated", dt); curDoc.save(true); this.setCreationDate(date); } catch (Exception ne) { LOGGER.info("Error. Can not change DAVCreated"); } } } public void patchLastModified(Date date) { Document curDoc = null; String notesURL = this.getInternalAddress(); curDoc = DominoProxy.getDocument(notesURL); if (curDoc == null) { return; } if (curDoc instanceof Document) { try { Session ses = DominoProxy.getUserSession(); DateTime dt = ses.createDateTime(date); curDoc.replaceItemValue("DAVModified", dt); curDoc.save(true); this.setLastModified(date); } catch (Exception ne) { LOGGER.info("Error. Can not change DAVCModified"); } } } public Document getDocument() { String intAddress = this.getInternalAddress(); Base notesObj = DominoProxy.resolve(intAddress); if (notesObj == null) { return null; } if (notesObj instanceof Document) { return (Document) notesObj; } return null; } }