/** ========================================================================= *
* 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;
}
}