/*******************************************************************************
* 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;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.apache.commons.vfs.FileSystemException;
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.WGDocumentCore;
import de.innovationgate.webgate.api.WGSessionContext;
import de.innovationgate.wga.config.DesignReference;
import de.innovationgate.wgpublisher.WGACore;
import de.innovationgate.wgpublisher.design.db.DBDesignProvider;
import de.innovationgate.wgpublisher.design.db.PluginDesignProvider;
import de.innovationgate.wgpublisher.design.db.PluginDesignSource;
import de.innovationgate.wgpublisher.design.fs.FileSystemDesignProvider;
import de.innovationgate.wgpublisher.design.fs.FileSystemDesignSource;
import de.innovationgate.wgpublisher.design.sync.WGDesignSyncException;
public class OverlayDesignProvider implements WGADesignProvider {
public static final String OVERLAY_FOLDER = "overlay";
public static final String OVERLAY_PREFIX = OVERLAY_FOLDER + ":";
private WGACore _core;
private FileSystemDesignProvider _overlay;
private PluginDesignProvider _original;
private WGDatabase _consumer;
public static final void applyOverlayDesign(WGACore core, WGDatabase db, WGADesign originalDesign, Map<String,String> originalOptions, WGADesign overlayDesign, Map<String,String> overlayOptions) throws WGADesignConfigurationException, WGAPIException {
try {
if (!(originalDesign.getSource() instanceof PluginDesignSource)) {
throw new WGADesignConfigurationException("Overlay designs can only be used with a plugin design as basis");
}
if (!(overlayDesign.getSource() instanceof FileSystemDesignSource)) {
throw new WGADesignConfigurationException("Overlay designs can only be file system designs");
}
PluginDesignProvider original = (PluginDesignProvider) originalDesign.createDesignProvider(db, originalOptions);
FileSystemDesignProvider overlay = (FileSystemDesignProvider) overlayDesign.createDesignProvider(db, overlayOptions);
OverlayDesignProvider provider = new OverlayDesignProvider(core, db, overlay, original);
db.setDesignProvider(provider);
db.setAllowDesignModification(false);
core.getLog().info("Application " + db.getDbReference() + " uses design \"" + original.getName() + "\" with overlay \"" + overlay.getName() + "\"");
}
catch (Exception e) {
throw new WGADesignConfigurationException("Exception applying overlay design", e);
}
}
public OverlayDesignProvider(WGACore core, WGDatabase consumer, FileSystemDesignProvider overlayProvider, PluginDesignProvider originalProvider) throws FileSystemException, WGDesignSyncException {
_core = core;
_consumer = consumer;
_overlay = overlayProvider;
_original = originalProvider;
overlayProvider.importOverlayResources(originalProvider.getSourceDesignProvider());
}
public WGDatabase getConsumerDatabase() {
return _consumer;
}
public boolean isLookupVariants() {
return false;
}
public void addDesignChangeListener(WGDesignChangeListener changeListener) {
_original.addDesignChangeListener(changeListener);
_overlay.addDesignChangeListener(changeListener);
}
public void closeSession() throws WGBackendException {
_overlay.closeSession();
_original.closeSession();
}
public WGDocumentCore createDesignDocument(int type, String name, String mediaKey) throws WGAuthorisationException, WGCreationException {
throw new WGCreationException("This design cannot create design documents");
}
public int designHashCode() {
return (new HashCodeBuilder()).append(_overlay.designHashCode()).append(_original.designHashCode()).toHashCode();
}
public void dispose() {
_overlay.dispose();
_original.dispose();
}
public WGDocumentCore getDesignObject(int type, String name, String strMediaKey) throws WGAPIException {
// Ask the overlay if the prefix is on
if (name.startsWith(OVERLAY_PREFIX)) {
String overlayName = name.substring(OVERLAY_PREFIX.length());
WGDocumentCore core = _overlay.getDesignObject(type, overlayName, strMediaKey);
if (core != null) {
return new DesignProviderCoreWrapper(core, this, false, true);
}
}
return _original.getDesignObject(type, name, strMediaKey);
}
public List getDesignObjects(int type) throws WGAPIException {
Map<String,WGDocumentCore> designs = new HashMap<String, WGDocumentCore>();
for (WGDocumentCore core : _original.getDesignObjects(type)) {
designs.put((String) core.getMetaData(WGDesignDocument.META_NAME), core);
}
for (WGDocumentCore core : _overlay.getDesignObjects(type)) {
core = new DesignProviderCoreWrapper(core, this, false, true);
designs.put((String) core.getMetaData(WGDesignDocument.META_NAME), core);
}
return new ArrayList(designs.values());
}
public String getName() {
return _original.getName() + " with overlay \"" + _overlay.getName() + "\"";
}
public boolean isNotifying() {
// We can do this bc. both used provider types do never notify (PluginDesignProvider backed by a FS, FSDesignProvider)
return false;
}
public boolean isProviderCore(WGDocumentCore core) {
// TODO Auto-generated method stub
return false;
}
public void openSession(WGSessionContext context) throws WGBackendException {
_original.openSession(context);
_overlay.openSession(context);
}
public boolean providesType(int type) {
return _original.providesType(type);
}
public void removeDesignChangeListener(WGDesignChangeListener changeListener) {
_original.removeDesignChangeListener(changeListener);
_overlay.removeDesignChangeListener(changeListener);
}
}