Package de.innovationgate.wgpublisher.design.fs

Source Code of de.innovationgate.wgpublisher.design.fs.FileSystemDesignProvider

/*******************************************************************************
* 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.wgpublisher.design.fs;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.vfs.AllFileSelector;
import org.apache.commons.vfs.Capability;
import org.apache.commons.vfs.FileObject;
import org.apache.commons.vfs.FileSystemException;
import org.apache.commons.vfs.FileType;
import org.apache.log4j.Logger;

import de.innovationgate.utils.WGUtils;
import de.innovationgate.webgate.api.WGAPIException;
import de.innovationgate.webgate.api.WGAuthorisationException;
import de.innovationgate.webgate.api.WGBackendException;
import de.innovationgate.webgate.api.WGCreationException;
import de.innovationgate.webgate.api.WGDatabase;
import de.innovationgate.webgate.api.WGDesignChangeListener;
import de.innovationgate.webgate.api.WGDesignDocument;
import de.innovationgate.webgate.api.WGDocument;
import de.innovationgate.webgate.api.WGDocumentCore;
import de.innovationgate.webgate.api.WGDocumentKey;
import de.innovationgate.webgate.api.WGSessionContext;
import de.innovationgate.wga.common.DesignDirectory;
import de.innovationgate.wga.common.beans.csconfig.v1.InvalidCSConfigVersionException;
import de.innovationgate.wga.config.DesignReference;
import de.innovationgate.wgpublisher.WGACore;
import de.innovationgate.wgpublisher.design.DesignProviderCoreWrapper;
import de.innovationgate.wgpublisher.design.OverlayDesignProvider;
import de.innovationgate.wgpublisher.design.WGADesignProvider;
import de.innovationgate.wgpublisher.design.sync.WGDesignSyncException;

public class FileSystemDesignProvider extends FileSystemDesignManager implements WGADesignProvider {

    private boolean _strictFCDateDetermination;
    private DesignReference _designReference;
    private String _variantSuffix;
   
    public FileSystemDesignProvider(DesignReference ref, WGACore core, WGDatabase db, String path, Map<String,String> options) throws WGDesignSyncException, IOException, WGAPIException, InstantiationException,
            IllegalAccessException, InvalidCSConfigVersionException {
        super(core, db, path, options);
        _designReference = ref;
        _name = "Design Directory " + getBaseFolder().getURL().toString();
        _strictFCDateDetermination = true;
        _lookupVariants = WGUtils.getBooleanMapValue(options, OPTION_DESIGNVARIANTS, false);
        _variantSuffix = "." + getDB().getDbReference();
    }

    private String _name;
    public static final String OPTION_SYNC = "sync";
    public boolean providesType(int type) {
        return _syncedDoctypes.contains(new Integer(type));
    }

    public void addDesignChangeListener(WGDesignChangeListener changeListener) {
    }

    public WGDocumentCore createDesignDocument(int type, String name, String mediaKey) throws WGAuthorisationException, WGCreationException {
       
        try {
            switch (type) {
               
                case WGDocument.TYPE_TML:{
                    FileObject newTml = getTmlFolder().resolveFile(mediaKey.toLowerCase() + "/" + name.replace(":", "/") + ".tml");
                    if (newTml.exists()) {
                        throw new WGCreationException("Document already exists: " + (new WGDocumentKey(type, name, mediaKey)).toString());
                    }
                    newTml.createFile();
                    break;
                }
                   
                   
                case WGDocument.TYPE_CSSJS: {
                    String suffix = DesignDirectory.getScriptInformation(mediaKey).getSuffix();
                    FileObject newScript = getScriptTypeFolder(mediaKey).resolveFile(mediaKey.toLowerCase() + "/" + name.replace(":", "/") + suffix);
                    if (newScript.exists()) {
                        throw new WGCreationException("Document already exists: " + (new WGDocumentKey(type, name, mediaKey)).toString());
                    }
                    newScript.createFile();
                    break;
                }
                   
                   
                case WGDocument.TYPE_FILECONTAINER: {
                    FileObject newFC = getFilesFolder().resolveFile(name.replace(":", "/"));
                    if (newFC.exists()) {
                        throw new WGCreationException("Document already exists: " + (new WGDocumentKey(type, name, mediaKey)).toString());
                    }
                    newFC.createFolder();
                    break;
                }
               
               
            }
           
            return getDesignObject(type, name, mediaKey);
        }
        catch (Exception e) {
            throw new WGCreationException("Exception creating design document " + (new WGDocumentKey(type, name, mediaKey)).toString(), e);
        }
       
    }

    public void dispose() {
        close();
    }

    public WGDocumentCore getDesignObject(int type, String name, String strMediaKey) throws WGBackendException {

        try {
            switch (type) {

                case WGDocument.TYPE_TML: {
                    ModuleFile file = getTMLModuleFile(name, strMediaKey);
                    if (file == null || !file.getFile().exists()) {
                        refreshIfUpdatable(getFsResources().getTmlFolder());
                        file = getTMLModuleFile(name, strMediaKey);
                    }
                   
                    if (file != null) {
                        return wrapVariantCore(new DesignFileDocument(this, file));
                    }
                    break;
                }

                case WGDocument.TYPE_CSSJS: {
                    ModuleFile file = getScriptModuleFile(name, strMediaKey);
                    if (file == null || !file.getFile().exists()) {
                        refreshIfUpdatable(getFsResources().getScriptFolder());
                        file = getScriptModuleFile(name, strMediaKey);
                    }
                   
                    if (file != null) {
                        return wrapVariantCore(new DesignFileDocument(this, file));
                    }
                    break;
                }

                case WGDocument.TYPE_FILECONTAINER: {
                    ModuleFile file = getFileContainerFile(name);
                    if (file == null || !file.getFile().exists()) {
                        refreshIfUpdatable(getFsResources().getFilesFolder());
                        file = getFileContainerFile(name);
                    }
                   
                    if (file != null) {
                        return wrapVariantCore(new DesignFileDocument(this, file));
                    }
                    break;
                }
            }

            return null;
        }
        catch (Exception e) {
            throw new WGBackendException("Exception retrieving design document '" + name + "' of type " + WGDocument.doctypeNumberToName(type), e);
        }

    }
   
    public WGDocumentCore wrapVariantCore(WGDocumentCore core) throws WGAPIException {
       
        if (_lookupVariants) {
            String name = (String) core.getMetaData(WGDesignDocument.META_NAME);
            if (name.endsWith(_variantSuffix)) {
                return new DesignProviderCoreWrapper(core, this, true, false);
            }
            else {
                return core;
            }
        }
        else {
            return core;
        }
       
    }

    @Override
    protected ModuleFile getFileContainerFile(String name) throws FileSystemException, WGDesignSyncException {

        if (_lookupVariants) {
            ModuleFile file = super.getFileContainerFile(name + _variantSuffix);
            if (file != null) {
                return file;
            }
        }
       
        return super.getFileContainerFile(name);
    }

    @Override
    protected ModuleFile getScriptModuleFile(String name, String codetype) throws FileSystemException, WGDesignSyncException {
       
        if (_lookupVariants) {
            ModuleFile file = super.getScriptModuleFile(name + _variantSuffix, codetype);
            if (file != null) {
                return file;
            }
        }
       
        return super.getScriptModuleFile(name, codetype);
    }

    @Override
    protected ModuleFile getTMLModuleFile(String name, String strMediaKey) throws FileSystemException, WGDesignSyncException {
       
        if (_lookupVariants) {
            ModuleFile file = super.getTMLModuleFile(name + _variantSuffix, strMediaKey);
            if (file != null) {
                return file;
            }
        }
        return super.getTMLModuleFile(name, strMediaKey);
    }

    public List<WGDocumentCore> getDesignObjects(int type) throws WGBackendException {

        try {
            switch (type) {

                case WGDocument.TYPE_TML: {
                    refreshIfUpdatable(getFsResources().getTmlFolder());
                    List<ModuleFile> files = getTMLModuleFiles();
                    return wrapModuleFiles(files);
                }

                case WGDocument.TYPE_CSSJS: {
                    refreshIfUpdatable(getFsResources().getScriptFolder());
                    List<ModuleFile> files = getScriptModuleFiles();
                    return wrapModuleFiles(files);
                }

                case WGDocument.TYPE_FILECONTAINER: {
                    refreshIfUpdatable(getFsResources().getFilesFolder());
                    List<ModuleFile> files = getFileContainerFiles();
                    return wrapFileContainerFiles(files);
                }
            }

            return null;
        }
        catch (Exception e) {
            throw new WGBackendException("Exception retrieving design document list of type " + WGDocument.doctypeNumberToName(type), e);
        }

    }

    private void refreshIfUpdatable(FileObject tmlFolder) throws FileSystemException {
        if (getFsResources().isUpdateableFileSystem()) {
            tmlFolder.refresh();
        }
    }

    public String getName() {
        return _name;
    }

    public boolean isNotifying() {
        return false;
    }

    public boolean isProviderCore(WGDocumentCore core) {
        return (core instanceof DesignFileDocument);
    }

    public void removeDesignChangeListener(WGDesignChangeListener changeListener) {
    }

    protected List<WGDocumentCore> wrapFileContainerFiles(List<ModuleFile> files) {
   
        List<WGDocumentCore> list = new ArrayList<WGDocumentCore>();
        Set<String> addedNames = new HashSet<String>();
        for (ModuleFile file : files) {
            try {
                WGDocumentCore core = wrapVariantCore(new DesignFileDocument(this, file));
               
                // Filter out base versions of variants
                if (_lookupVariants) {
                    String coreName = (String) core.getMetaData(WGDesignDocument.META_NAME);
                   
                    // If we try to add a doc that already has been added and is NO variant, we know that this is the base version which was
                    // overwritten by a variant. So we skip it.
                    if (addedNames.contains(coreName) && !Boolean.TRUE.equals(core.getMetaData(WGDesignDocument.META_VARIANT))) {
                        continue;
                    }
                    else {
                        addedNames.add(coreName);
                    }
                }
               
                list.add(core);
            }
            catch (Exception e) {
                getLog().error("Exception wrapping file container file as WGAPI document: " + file.getFile().getName().getPath(), e);
            }
   
        }
        return list;
   
    }

    protected List<WGDocumentCore> wrapModuleFiles(List<ModuleFile> files) {
   
        Iterator<ModuleFile> it = files.iterator();
        Set<String> addedNames = new HashSet<String>();
        List<WGDocumentCore> list = new ArrayList<WGDocumentCore>();
        while (it.hasNext()) {
            ModuleFile moduleFile = (ModuleFile) it.next();
            try {
                WGDocumentCore core = wrapVariantCore(new DesignFileDocument(this, moduleFile));
               
                // Filter out base versions of variants
                if (_lookupVariants) {
                    String coreName = (String) core.getMetaData(WGDesignDocument.META_NAME);
                   
                    // If we try to add a doc that already has been added and is NO variant, we know that this is the base version which was
                    // overwritten by a variant. So we skip it.
                    if (addedNames.contains(coreName) && !Boolean.TRUE.equals(core.getMetaData(WGDesignDocument.META_VARIANT))) {
                        continue;
                    }
                    else {
                        addedNames.add(coreName);
                    }
                }
               
                list.add(core);
            }
            catch (Exception e) {
                getLog().error("Exception wrapping module file as WGAPI document: " + moduleFile.getFile().getName().getPath(), e);
            }
   
        }
        return list;
   
    }

    protected boolean isStrictFCDateDetermination() {
        return _strictFCDateDetermination;
    }

    public WGDatabase getConsumerDatabase() {
        return getDB();
    }

    public boolean isLookupVariants() {
        return _lookupVariants;
    }

    public void closeSession() {
    }

    public void openSession(WGSessionContext context) {
       
        if (_lookupVariants && getFsResources().isUpdateableFileSystem()) {
            try {
                getFsResources().refreshAll();
            }
            catch (FileSystemException e) {
                // We dont want a failure of cache refreshing kill the whole session, so we log it instead
                Logger.getLogger("wga.design").error("Exception refreshing file system design cache", e);
            }
        }
       
       
        try {
            updateConfiguration();
        }
        catch (Exception e) {
            Logger.getLogger("wga.design").error("Exception updating file system design configuration", e);
        }
       
       
    }

    public int designHashCode() {
        return super.designHashCode();
    }

    public DesignReference getDesignReference() {
        return _designReference;
    }

    public void importOverlayResources(FileSystemDesignProvider sourceDesignProvider) throws FileSystemException, WGDesignSyncException {
       
         for (FileObject mediaKeyFolder : sourceDesignProvider.getTmlFolder().getChildren()) {
             FileObject overlayFolder = mediaKeyFolder.resolveFile(OverlayDesignProvider.OVERLAY_FOLDER);
             if (overlayFolder.exists()) {
                 FileObject targetMediaKeyFolder = getTmlFolder().resolveFile(mediaKeyFolder.getName().getBaseName());
                 copyNewResources(overlayFolder, targetMediaKeyFolder);
             }
         }
        
         for (FileObject scriptTypeFolder : sourceDesignProvider.getScriptFolder().getChildren()) {
             FileObject overlayFolder = scriptTypeFolder.resolveFile(OverlayDesignProvider.OVERLAY_FOLDER);
             if (overlayFolder.exists()) {
                 FileObject targetScriptTypeFolder = getScriptFolder().resolveFile(scriptTypeFolder.getName().getBaseName());
                 copyNewResources(overlayFolder, targetScriptTypeFolder);
             }
         }
        
         FileObject overlayFolder = sourceDesignProvider.getFilesFolder().resolveFile(OverlayDesignProvider.OVERLAY_FOLDER);
         if (overlayFolder.exists()) {
             FileObject targetFCFolder = getFilesFolder();
             copyNewResources(overlayFolder, targetFCFolder);
         }
        
         // Copy an overlay flag file to the system file container
         FileObject targetFCFolder = getFilesFolder();
         FileObject systemFC = targetFCFolder.resolveFile("system");
         if (!systemFC.exists()) {
             systemFC.createFolder();
         }
         FileObject overlayFlag = systemFC.resolveFile("overlay.flg");
         if (!overlayFlag.exists()) {
             overlayFlag.createFile();
         }
    }

    private void copyNewResources(FileObject source, FileObject target) throws FileSystemException, WGDesignSyncException {

        for (FileObject sourceFile : source.getChildren()) {
            if (!isValidDesignFile(sourceFile)) {
                continue;
            }
           
            FileObject targetFile = target.resolveFile(sourceFile.getName().getBaseName());
            if (sourceFile.getType().equals(FileType.FOLDER)) {
                if (!targetFile.exists()) {
                    getLog().info("Adding new overlay folder " + getBaseFolder().getName().getRelativeName(targetFile.getName()));
                    targetFile.createFolder();
                }
                else if (targetFile.getType().equals(FileType.FILE)) {
                    throw new WGDesignSyncException("Unable to apply overlay. Folder '" +  getBaseFolder().getName().getRelativeName(targetFile.getName()) + " already exists as file. Delete it enable overlay management again");
                }
                copyNewResources(sourceFile, targetFile);
            }
            else if (sourceFile.getType().equals(FileType.FILE)) {
                if (!targetFile.exists()) {
                    getLog().info("Adding new overlay resource " + getBaseFolder().getName().getRelativeName(targetFile.getName()));
                    targetFile.copyFrom(sourceFile, new AllFileSelector());
                }
            }
        }
       
    }

}
TOP

Related Classes of de.innovationgate.wgpublisher.design.fs.FileSystemDesignProvider

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.