Package de.innovationgate.webgate.api

Source Code of de.innovationgate.webgate.api.WGArea$SessionData

/*******************************************************************************
* Copyright 2009, 2010 Innovation Gate GmbH. All Rights Reserved.
*
* This file is part of the OpenWGA server platform.
*
* OpenWGA is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* In addition, a special exception is granted by the copyright holders
* of OpenWGA called "OpenWGA plugin exception". You should have received
* a copy of this exception along with OpenWGA in file COPYING.
* If not, see <http://www.openwga.com/gpl-plugin-exception>.
*
* OpenWGA is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenWGA in file COPYING.
* If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/
package de.innovationgate.webgate.api;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

import de.innovationgate.webgate.api.WGSessionContext.DocumentContext;
import de.innovationgate.webgate.api.WGStructEntry.SessionData;
import de.innovationgate.webgate.api.locking.ResourceIsLockedException;

/**
* <p>Represents an area of the content database, containing content documents.
* Areas are treated as separated regions of the content, where each has it's own access controlling.</p>
*/
public class WGArea extends WGSchemaDocument implements PageHierarchyNode {
   
    public class SessionData {
       
        private List backendEditors;

        public List getBackendEditors() {
            return backendEditors;
        }

        public void setBackendEditors(List backendEditors) {
            this.backendEditors = backendEditors;
        }
       
        private List backendReaders;

        public List getBackendReaders() {
            return backendReaders;
        }

        public void setBackendReaders(List backendEditors) {
            this.backendReaders = backendEditors;
        }
       
    }
 
    public static final String META_READERS = "READERS";
    public static final MetaInfo METAINFO_READERS = new MetaInfo(META_READERS, String.class, Collections.EMPTY_LIST);
    static {
        METAINFO_READERS.setMultiple(true);
        METAINFO_READERS.setLuceneIndexType(MetaInfo.LUCENE_INDEXTYPE_FULLTEXT);
        METAINFO_READERS.setInputConverter(new MetaConverter() {

            public Object convert(WGDocument doc, MetaInfo metaInfo, Object value) throws WGAPIException {
                List readers = (List) value;
                   
                // Test if the current user is contained in the list. If not, he is added to avoid self disclosure
                if (!WGDatabase.anyoneAllowed(readers) && !doc.getDatabase().isMemberOfUserList(readers)) {
                    readers.add(doc.getDatabase().getSessionContext().getUser());
                }
                return readers;
            }
           
        });
    };
   
  public static final String META_EDITORS = "EDITORS";
    public static final MetaInfo METAINFO_EDITORS = new MetaInfo(META_EDITORS, String.class, Collections.EMPTY_LIST);
    static { METAINFO_EDITORS.setMultiple(true); };
   
    public static final String META_SYSTEM = "SYSTEM";
    public static final MetaInfo METAINFO_SYSTEM = new MetaInfo(META_SYSTEM, Boolean.class, Boolean.FALSE);
    static {
        METAINFO_SYSTEM.setExtdata(true);
    }
 
  private WGDocumentListCache rootEntries = null;

  /**
   * @throws WGAPIException
   * @see de.innovationgate.webgate.api.WGDocument#WGDocument(WGDatabase, WGDocumentCore)
   */
  public WGArea(WGDatabase db, WGDocumentCore doc) throws WGAPIException {
    super(db, doc);
  }
 
  /**
   * Returns the name of this area.
   * @throws WGAPIException
   */
  public String getName() throws WGAPIException {
    return String.valueOf(this.getMetaData(META_NAME));
  }
 
  /**
   * Returns a list of all root entries in this area.
   * @return WGStructEntryList
   * @throws WGSystemException
   * @throws WGBackendException
   */
  public synchronized WGStructEntryList getRootEntries() throws WGAPIException {

//       Double checked cache (un-synchronized and synchronized)
      List entries = getDatabase().fetchDocumentListCache(this.rootEntries, WGDocument.TYPE_STRUCTENTRY);
    if (!isCachingEnabled() || entries == null) {
      WGOperationKey op = db.obtainOperationKey(WGOperationKey.OP_STRUCT_ROOTS, getName());
            synchronized (op) {
                try {
                    op.setUsed(true);
               entries = getDatabase().fetchDocumentListCache(this.rootEntries, WGDocument.TYPE_STRUCTENTRY);
         
            if (!isCachingEnabled() || entries == null) {
              entries = this.db.getRootEntries(this);
              if (isCachingEnabled() && getDatabase().getSessionContext().isCacheWritingEnabled()) {
                this.rootEntries = WGDocumentListCache.buildFromDocuments(entries);
              }
            }
                }
                finally {
                    op.setUsed(false);
                }
      }
    }
    return WGStructEntryList.create(entries);

  }

  /**
   * Returns a list of allowed content editors in this area.
   * @return List
   * @throws WGAPIException
   */
  public List getEditors() throws WGAPIException {
    List editors = (List) this.getMetaData(WGArea.META_EDITORS);
    if (editors != null) {
      return editors;
    }
    else {
      return new ArrayList();
    }
  }
 
     /**
     * Returns a list of allowed readers of contents in this area. This is only supported on content stores of version 5.
     * @return List
     * @throws WGAPIException
     */
    public List getReaders() throws WGAPIException {
        List readers = (List) this.getMetaData(WGArea.META_READERS);
        if (readers != null) {
            return readers;
        }
        else {
            return new ArrayList();
        }
    }
 
  /**
   * Sets the allowed editors for this area.
   * @param list
   * @throws WGAPIException
   */
  public boolean setEditors(List list) throws WGAPIException {
    return setMetaData(META_EDITORS, list);
  }
 
     /**
     * Sets the allowed readers for this area. This is only supported on content stores of version 5.
     * @param list
     * @throws WGAPIException
     */
    public boolean setReaders(List list) throws WGAPIException {
        return setMetaData(META_READERS, list);
    }
 
  /**
   * Tests if the current user is allowed to edit documents in this area.
   * @return boolean
   * @throws WGAPIException
   */
  public boolean mayEditAreaChildren() throws WGAPIException {
     
      if( this.db.getSessionContext().getAccessLevel() == WGDatabase.ACCESSLEVEL_MANAGER ){
            return true;
        }
     
      List readers = (List) getEffectiveReaders();
      if (!WGDatabase.anyoneAllowed(readers) && !this.db.isMemberOfUserList(readers)) {
          return false;
        }
 
    List editors = (List) this.getEffectiveEditors();
    if (!WGDatabase.anyoneAllowed(editors) && !this.db.isMemberOfUserList(editors)) {
            return false;
        }
   
    return true;
  }
 
  /**
   * Returns the list of currently effective readers. These may differ from the currently set readers in a yet unsaved document.
   * @throws WGAPIException
   */
  public List getEffectiveReaders() throws WGAPIException {
     
        List readers = getSessionData().getBackendReaders();
        if (readers == null) {
            readers = getReaders();
        }
        return readers;
     
  }
 
     /**
     * Returns the list of currently effective editors. These may differ from the currently set editors in a yet unsaved document.
     * @throws WGAPIException
     */
    public List getEffectiveEditors() throws WGAPIException {
       
        List editors = getSessionData().getBackendEditors();
        if (editors == null) {
            editors = getEditors();
        }
        return editors;
       
    }
 
  /**
   * Creates a new root entry for this area.
   * @param contentType The content type for this new entry.
   * @param title The title of this new entry.
   * @return A newly created root entry
   * @throws WGAPIException
   */
  public WGStructEntry createRootEntry(WGContentType contentType, String title) throws WGAPIException {
    return getDatabase().createStructEntry(this, contentType, title);
  }
 
  /**
   * Creates a new root page, including struct entry and content.
   * Both documents are already saved when the method exists.
   * @param contentType The content type of the page
   * @param title The title of the page that will be used for both struct entry
   * @param language The language of the content to create. Leave null to use databases default language.
   * @return The content of the created page
   * @throws WGAPIException
   */
  public WGContent createRootPage(WGContentType contentType, String title, String language) throws WGAPIException {
     
      if (language == null) {
          language = getDatabase().getDefaultLanguage();
      }
     
      WGLanguage lang = getDatabase().getLanguage(language);
      performRootPageCreationCheck(contentType, lang);
     
      WGStructEntry entry = createRootEntry(contentType, title);
      entry.save();
      WGContent content = entry.createContent(lang, title);
      content.save();
      return content;
     
  }
 
  /**
   * Variant of {@link #createRootPage(WGContentType, String, String)} that always uses default language.
   * @param contentType
   * @param title
   * @return The content of the created page
   * @throws WGAPIException
   */
  public WGContent createRootPage(WGContentType contentType, String title) throws WGAPIException {
      return createRootPage(contentType, title, null);
  }
 
  /**
   * @throws WGAPIException
   * @see WGDocument#dropCache()
   */
  public void dropCache() throws WGAPIException {
    dropRelations();
    super.dropCache();
  }

  /* (non-Javadoc)
   * @see de.innovationgate.webgate.api.WGDocument#dropRelations()
   */
  protected void dropRelations() {
    this.rootEntries = null;
  }




 
  /**
   * Sets the name of this area.
   * @throws WGAPIException
   */
  protected boolean setName(String name) throws WGAPIException {
    return setMetaData(META_NAME, name);
  }

  /*
   * @see de.innovationgate.webgate.api.WGDocument#createClone(de.innovationgate.webgate.api.WGDatabase)
   */
  public WGDocument createClone(WGDatabase db) throws WGAPIException {
   
        WGArea newArea = db.createArea(getName());
    try {
            pushData(newArea);
            if (newArea.save(getLastModified())) {
                return newArea;
            }
            else {
                return null;
            }
        } catch (WGAPIException e) {
            // try to remove previous created area
            try {
                newArea.remove();
            }
            catch (WGAPIException e1) {
            }

            throw e;
        }       

   
   
  }

    /* (non-Javadoc)
     * @see de.innovationgate.webgate.api.WGDocument#pushData(de.innovationgate.webgate.api.WGDocument)
     */
    public void pushData(WGDocument doc) throws WGAPIException {
        super.pushData(doc);
        WGArea area = (WGArea) doc;
        area.setDescription(getDescription());
    area.setEditors(new ArrayList(getEditors()));
    area.setReaders(new ArrayList(getReaders()));
    }

    /* (Kein Javadoc)
   * @see de.innovationgate.webgate.api.WGDocument#remove()
   */
  public boolean remove() throws WGAPIException {
   
        // We must explicitly call the removal check before innerRemove() because we are gonna delete document before we reach this method
    performRemoveCheck();
   
    if (!db.hasFeature(WGDatabase.FEATURE_AUTOCASCADES_DELETIONS) && db.getSessionContext().isCascadeDeletions()) {
      Iterator doomed = getRootEntries().iterator();
      while (doomed.hasNext()) {
        WGStructEntry doomedEntry = (WGStructEntry) doomed.next();
        if (!doomedEntry.isDeleted()) {
          doomedEntry.remove();
        }
      }
    }
   
   
    return innerRemove();
  }

    public void performRemoveCheck() throws WGAPIException {
        super.performRemoveCheck();
       
        if (db.getSessionContext().getAccessLevel() < WGDatabase.ACCESSLEVEL_MANAGER) {
      throw new WGAuthorisationException("You are not authorized to delete areas in this database");
    }
       
        if (!getDatabase().isDoctypeModifiable(WGDocument.TYPE_AREA)) {
            throw new WGAuthorisationException("Removing areas via WGAPI is not permitted in this database");
        }
       
        if (!mayEditAreaChildren()) {
            throw new WGAuthorisationException("You are not authorized to delete this area");
        }
       
        // Perform removal check on all child entries
        Iterator entries = getRootEntries().iterator();
        while (entries.hasNext()) {
            ((WGStructEntry) entries.next()).performRemoveCheck();
        }       

    }
 
  /**
   * Creates a new content object as root in this area. This is only usable in content stores without struct entries (e.g. all descendants of SimpleContentSource).
   * @param key The key for the new content
   * @param title The title of the new content
   * @return Newly created content object
   * @throws WGAPIException
   */
  public WGContent createContent(Object key, String title) throws WGAPIException {
    return getDatabase().createContent(this, key, title);
  }
 
  /**
   * Creates a new content as root for this area. This is only usable in content stores without struct entries (e.g. all descendants of SimpleContentSource).
   * @return Newly created root content.
   * @throws WGAPIException
   */
  public WGContent createContent() throws WGAPIException {
    return createContent(null, "");
  }

    public Class getChildNodeType() {
        return WGStructEntry.class;
    }

    public List getChildNodes() throws WGAPIException {
        return new ArrayList(getRootEntries());
    }

    public PageHierarchyNode getParentNode() throws WGAPIException {
        return getDatabase().getAllDocumentsHierarchy().getCollectionForType(WGDocument.TYPE_AREA);
    }

    public String getNodeKey() throws WGAPIException {
        return getDocumentKey().toString();
    }
   
    public String getNodeTitle(String language) throws WGAPIException {
        return getName();
    }

    public void performSaveCheck() throws ResourceIsLockedException, WGAPIException {
        super.performSaveCheck();
       
        List readers = (List) getEffectiveReaders();
        if (!WGDatabase.anyoneAllowed(readers) && !this.db.isMemberOfUserList(readers)) {
            throw new WGAuthorisationException("Updating areas via WGAPI is not permitted in this database");
        }
   
        List editors = (List) getEffectiveEditors();
        if (!WGDatabase.anyoneAllowed(editors) && !this.db.isMemberOfUserList(editors)) {
            throw new WGAuthorisationException("You are not authorized to modify this area");
        }
       
        if (!getDatabase().isDoctypeModifiable(WGDocument.TYPE_AREA)) {
            throw new WGAuthorisationException("Updating areas via WGAPI is not permitted in this database");
        }
    }
   
    /**
     * Implements the visitor pattern on the page hierarchy of this area. The visitor visits all struct entries and all of their (non-archived) contents.
     * @param visitor
     * @throws WGAPIException
     */
    public void visit(WGPageVisitor visitor) throws WGAPIException {
       
        visitor.visit(this);
       
        List<WGStructEntry> roots = getRootEntries().asList();
        for (WGStructEntry root : roots) {
            root.visit(visitor);
        }
       
    }
   
    /**
     * Checks if the current user may create a new root struct entry of the given content type. If so the method exits normally. Otherwise an exception is thrown.
     * @param ct The content type to use.
     * @throws WGAPIException If the user may not create the document. The exception informs about the reason.
     */
    public void performRootCreationCheck(WGContentType ct) throws WGAPIException {
        getDatabase().performStructCreationCheck(null, this, ct);
    }

    /**
     * Checks if the current user may create a new root page with the given data. If so the method exits normally. Otherwise an exception is thrown.
     * @param ct The content type to use for the struct entry
     * @param lang The language to use for the content
     * @throws WGAPIException If the user may not create the document. The exception informs about the reason.
     */
    public void performRootPageCreationCheck(WGContentType ct, WGLanguage lang) throws WGAPIException {
        performRootCreationCheck(ct);
        getDatabase().performContentCreationCheck(null, lang);
    }

    @Override
    public int getType() {
        return WGDocument.TYPE_AREA;
    }
   
    public boolean isSystemArea() throws WGAPIException {
        return (Boolean) getMetaData(META_SYSTEM);
    }
   
    public void setSystemArea(boolean system) throws WGAPIException {
        setMetaData(META_SYSTEM, system);
    }
   
    private SessionData getSessionData() {
       
        DocumentContext con = getDocumentSessionContext();
        SessionData data = (SessionData) con.getCustomData();
        if (data == null) {
            data = new SessionData();
            con.setCustomData(data);
        }
        return data;
    }
   
    protected void updateBackendCaches(WGDocumentCore core) {
        super.updateBackendCaches(core);
       
        try {
            de.innovationgate.webgate.api.WGArea.SessionData sessionData = getSessionData();
            sessionData.setBackendEditors((List) core.getMetaData(WGArea.META_EDITORS));
            sessionData.setBackendReaders((List) core.getMetaData(WGArea.META_READERS));
        }
        catch (WGAPIException e) {
            WGFactory.getLogger().error("Error updating area backend cache", e);
        }
    }
   
    /**
     * Tests if the current user may read contents in this area
     * @throws WGAPIException
     */
    public boolean mayReadContent() throws WGAPIException {
       
        // Are hierarchical reader fields enabled ?
        if (!getDatabase().isPageReadersEnabled()) {
            return true;
        }
       
        List readers = getEffectiveReaders();
        return (WGDatabase.anyoneAllowed(readers, true) || getDatabase().isMemberOfUserList(readers));
       
    }
}
TOP

Related Classes of de.innovationgate.webgate.api.WGArea$SessionData

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.