/* * © Copyright FOCONIS AG, 2014 * * 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 org.openntf.domino.xsp.model; import java.lang.reflect.Method; import java.security.AccessController; import java.security.PrivilegedExceptionAction; import javax.faces.context.FacesContext; import lotus.domino.Database; import lotus.domino.Document; import lotus.domino.NotesException; import com.ibm.commons.util.StringUtil; import com.ibm.xsp.FacesExceptionEx; import com.ibm.xsp.acl.NoAccessSignal; import com.ibm.xsp.domino.ResourceHandler; import com.ibm.xsp.model.DocumentDataContainer; import com.ibm.xsp.model.domino.DominoDocumentData; import com.ibm.xsp.model.domino.DominoDocumentDataContainer; import com.ibm.xsp.model.domino.DominoUtils; import com.ibm.xsp.model.domino.wrapped.DominoDocument; /** * Here we inherit form the original XSP-datasource class ({@link DominoDocumentData}) and extend the doNew/doOpenDocument method to have * more control over some actions. Especially we want to replace the {@link DominoDocument} with our {@link OpenntfDominoDocument} * */ public class OpenntfDominoDocumentData extends DominoDocumentData { private static Method openDatabaseMethod; static { try { AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() { // thanks for making this private :) @Override public Object run() throws Exception { openDatabaseMethod = DominoDocumentData.class.getDeclaredMethod("openDatabase", (Class<?>[]) null); openDatabaseMethod.setAccessible(true); return null; } }); } catch (Exception e) { org.openntf.domino.utils.DominoUtils.handleException(e); } } /** * this calls the "private" method in {@link DominoDocument}. Maybe IBM makes this protected, then we would not need this. * * @return */ protected Database openDatabase() { try { return (Database) openDatabaseMethod.invoke(this, (Object[]) null); } catch (Exception e) { org.openntf.domino.utils.DominoUtils.handleException(e); return null; } } /** * Invoked if you call a xpage.xsp without a document ID */ @SuppressWarnings("nls") @Override public DocumentDataContainer doNewDocument(final FacesContext context) throws FacesExceptionEx { try { OpenntfDominoDocument ntfDoc = createDocument(); return new DominoDocumentDataContainer(getBeanId(), getUniqueId(), ntfDoc); } catch (Exception localException) { throw new FacesExceptionEx("Unable to create document", localException); } } /** * creates a new document and wraps it in an OpenntfDominoDocument * * @return * @throws NotesException */ protected OpenntfDominoDocument createDocument() throws NotesException { Database db = openDatabase(); String server = com.ibm.xsp.model.domino.DominoUtils.getCurrentDatabase().getServer(); if (!(StringUtil.isEmpty(server))) { String currentUser = com.ibm.xsp.model.domino.DominoUtils.getCurrentSession().getEffectiveUserName(); int i = db.queryAccessPrivileges(currentUser); if (((i & Database.DBACL_CREATE_DOCS) == 0) && ((i & Database.DBACL_WRITE_PUBLIC_DOCS) == 0)) { throw new NoAccessSignal("User " + currentUser + " is has not enough privileges to create documents in " + getDatabaseName()); } } DominoDocument dominoDoc = DominoDocument.wrap(getDatabaseName(), db, getParentId(), getFormName(), getComputeWithForm(), getConcurrencyMode(), isAllowDeletedDocs(), getSaveLinksAs(), getWebQuerySaveAgent()); OpenntfDominoDocument ntfDoc = wrap(dominoDoc, true); ntfDoc.setEditable(true); return ntfDoc; } /** * Invoked if you call a xpage.xsp with a document ID */ @Override public DocumentDataContainer doOpenDocument(final FacesContext context) throws FacesExceptionEx { try { String noteId = getDocumentId(); if (DominoUtils.isCategoryId(noteId)) { noteId = ""; } if (StringUtil.isEmpty(noteId)) { return doNewDocument(context); } OpenntfDominoDocument ntfDoc = openDocument(noteId); return new DominoDocumentDataContainer(getBeanId(), getUniqueId(), ntfDoc); } catch (Exception localException) { throw new FacesExceptionEx(ResourceHandler.getString("DominoDocumentData.Couldnotopenthedocument"), localException); } } /** * Opens the document with the given noteId * * @param noteId * @return * @throws NotesException */ protected OpenntfDominoDocument openDocument(final String noteId) throws NotesException { Database db = openDatabase(); boolean allowDelted = isAllowDeletedDocs(); Document backendDoc = com.ibm.xsp.model.domino.DominoUtils.getDocumentById(db, noteId, allowDelted); if (backendDoc != null) { // BackendBridge.setNoRecycle(backendDoc.getParentDatabase().getParent(), backendDoc, true); } DominoDocument dominoDoc = DominoDocument.wrap(getDatabaseName(), backendDoc, getComputeWithForm(), getConcurrencyMode(), allowDelted, getSaveLinksAs(), getWebQuerySaveAgent()); OpenntfDominoDocument ntfDoc = wrap(dominoDoc, false); boolean editMode = "editDocument".equals(getEffectiveAction()); ntfDoc.setEditable(editMode); return ntfDoc; } /** * Wraps a {@link DominoDocument} in an {@link OpenntfDominoDocument} (or something else) * * @param domino * @param isNew * @return */ protected OpenntfDominoDocument wrap(final DominoDocument domino, final boolean isNew) { return new OpenntfDominoDocument(domino); } }