/*******************************************************************************
* Copyright (c) 2009, 2010 Innovation Gate GmbH.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Innovation Gate GmbH - initial API and implementation
******************************************************************************/
package de.innovationgate.eclipse.utils.ui.model;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.ui.IDecoratorManager;
import de.innovationgate.eclipse.utils.Activator;
import de.innovationgate.eclipse.utils.ExternalResourceIds;
import de.innovationgate.eclipse.utils.wga.WGADesignStructureHelper;
import de.innovationgate.webgate.api.WGAPIException;
import de.innovationgate.webgate.api.schemadef.WGAreaDefinition;
import de.innovationgate.webgate.api.schemadef.WGContentItemDefinition;
import de.innovationgate.webgate.api.schemadef.WGContentTypeDefinition;
import de.innovationgate.webgate.api.schemadef.WGLanguageDefinition;
import de.innovationgate.webgate.api.schemadef.WGMetaFieldDefinition;
import de.innovationgate.webgate.api.schemadef.WGSchemaDefinition;
import de.innovationgate.webgate.api.schemadef.WGSchemaDocumentDefinition;
import de.innovationgate.webgate.api.schemadef.WGSchemaValidationException;
import de.innovationgate.wga.common.beans.csconfig.v1.Version;
import de.innovationgate.wga.model.ValidationError;
import de.innovationgate.wga.model.VersionCompliance;
import de.innovationgate.wga.model.WGADesignConfigurationModel;
public class WGADesignConfigurationModelWrapper extends WGADesignConfigurationModel implements WGASchemaDefinitionModel {
private IContainer _designContainer;
private boolean _directAccessDefaultChanged = false;
private boolean _lastDirectAccessDefault = false;
private WGSchemaDefinition _schema;
private Set<WGASchemaDefinitionModelListener> _schemaModelListener = new HashSet<WGASchemaDefinitionModelListener>();
public WGADesignConfigurationModelWrapper(IFile syncInfoFile) throws IOException {
super(syncInfoFile.getLocation().toFile());
_designContainer = syncInfoFile.getParent();
_lastDirectAccessDefault = isDirectAccessDefault();
if (getSchemaDefinitionFile() != null && getSchemaDefinitionFile().exists()) {
// handle empty schema.xml
InputStream schemaIn = null;
try {
schemaIn = getSchemaDefinitionFile().getContents();
if (schemaIn.read() == -1) {
// schema.xml is empty
_schema = new WGSchemaDefinition();
} else {
try {
_schema = WGSchemaDefinition.read(getSchemaDefinitionFile().getContents());
}
catch (Exception e) {
IOException ioe = new IOException("Unable to read schema definition '" + getSchemaDefinitionFile().getLocation() + "'.");
ioe.setStackTrace(e.getStackTrace());
throw ioe;
}
}
} catch (CoreException e) {
IOException ioe = new IOException("Unable to read schema definition '" + getSchemaDefinitionFile().getLocation() + "'.");
ioe.setStackTrace(e.getStackTrace());
throw ioe;
} finally {
if (schemaIn != null) {
schemaIn.close();
}
}
}
}
@Override
public void reload() throws IOException {
super.reload();
if (getSchemaDefinitionFile() != null && getSchemaDefinitionFile().exists()) {
try {
_schema = WGSchemaDefinition.read(getSchemaDefinitionFile().getContents());
}
catch (Exception e) {
IOException ioe = new IOException("Unable to read schema definition '" + getSchemaDefinitionFile().getLocation() + "'.");
ioe.setStackTrace(e.getStackTrace());
throw ioe;
}
} else {
_schema = null;
}
}
@Override
public boolean isFeatureSupported(String featureID) {
if (featureID.equals(FEATURE_SCHEMADEFINITION)) {
Version version = VersionCompliance.toWGAVersion(getVersionCompliance());
return (version != null && version.isAtLeast(5, 2)) || (getSchemaDefinitionFile() != null && getSchemaDefinitionFile().exists());
}
return super.isFeatureSupported(featureID);
}
public IFile getSchemaDefinitionFile() {
if (_designContainer != null) {
return _designContainer.getFolder(new Path("files").append("system")).getFile("schema.xml");
} else {
return null;
}
}
@Override
public void saveChanges() throws IOException {
WGADesignStructureHelper helper = new WGADesignStructureHelper(_designContainer);
try {
helper.makeDesignConfigWriteable();
} catch (CoreException e) {
IOException ioe = new IOException("Unable to save design config changes. Configuration is readonly.");
ioe.setStackTrace(e.getStackTrace());
throw ioe;
}
super.saveChanges();
if (_schema != null) {
OutputStream out = new FileOutputStream(getSchemaDefinitionFile().getLocation().toFile());
try {
_schema.write(out);
} catch (Exception e) {
IOException ioe = new IOException("Unable to save design config changes.");
ioe.setStackTrace(e.getStackTrace());
throw ioe;
} finally {
out.close();
}
}
try {
new WGADesignStructureHelper(_designContainer).enforceDesignEncoding();
_designContainer.refreshLocal(IResource.DEPTH_INFINITE, new NullProgressMonitor());
} catch (CoreException e) {
}
if (_directAccessDefaultChanged) {
IDecoratorManager decoratorManager = Activator.getDefault().getWorkbench().getDecoratorManager();
if (decoratorManager.getEnabled(ExternalResourceIds.DECORATOR_TML_FILE)) {
decoratorManager.update(ExternalResourceIds.DECORATOR_TML_FILE);
}
}
_directAccessDefaultChanged = false;
}
// @Override
// public void setDirectAccessDefault(boolean value) {
// super.setDirectAccessDefault(value);
// _directAccessDefaultChanged = true;
// }
public IContainer getDesignContainer() {
return _designContainer;
}
@Override
public void fireModelChanged() {
super.fireModelChanged();
if (_lastDirectAccessDefault && !isDirectAccessDefault()) {
_directAccessDefaultChanged = true;
} else if (!_lastDirectAccessDefault && isDirectAccessDefault()) {
_directAccessDefaultChanged = true;
}
_lastDirectAccessDefault = isDirectAccessDefault();
}
@Override
public void addLibrary(File file) throws IOException {
super.addLibrary(file);
refreshSystemFileContainer(IResource.DEPTH_ONE);
}
@Override
public boolean deleteLibrary(String filename) {
boolean result = super.deleteLibrary(filename);
refreshSystemFileContainer(IResource.DEPTH_ONE);
return result;
}
private void refreshSystemFileContainer(int depth) {
if (_designContainer != null) {
WGADesignStructureHelper helper = new WGADesignStructureHelper(_designContainer);
IFolder systemContainer = helper.getFileContainer("system");
if (systemContainer != null) {
try {
systemContainer.refreshLocal(depth, new NullProgressMonitor());
} catch (CoreException e) {
}
}
}
}
public List<WGAreaDefinition> getAreaDefinitions() {
List<WGAreaDefinition> areaDefs = new ArrayList<WGAreaDefinition>();
if (_schema != null) {
Iterator<WGSchemaDocumentDefinition> defs = _schema.getDocumentDefinitions().iterator();
while (defs.hasNext()) {
WGSchemaDocumentDefinition def = defs.next();
if (def instanceof WGAreaDefinition) {
areaDefs.add((WGAreaDefinition)def);
}
}
}
return Collections.unmodifiableList(areaDefs);
}
public List<WGLanguageDefinition> getLanguageDefinitions() {
List<WGLanguageDefinition> langDefs = new ArrayList<WGLanguageDefinition>();
if (_schema != null) {
Iterator<WGSchemaDocumentDefinition> defs = _schema.getDocumentDefinitions().iterator();
while (defs.hasNext()) {
WGSchemaDocumentDefinition def = defs.next();
if (def instanceof WGLanguageDefinition) {
langDefs.add((WGLanguageDefinition)def);
}
}
}
return Collections.unmodifiableList(langDefs);
}
public List<WGContentTypeDefinition> getContentTypeDefinitions() {
List<WGContentTypeDefinition> ctDefs = new ArrayList<WGContentTypeDefinition>();
if (_schema != null) {
Iterator<WGSchemaDocumentDefinition> defs = _schema.getDocumentDefinitions().iterator();
while (defs.hasNext()) {
WGSchemaDocumentDefinition def = defs.next();
if (def instanceof WGContentTypeDefinition) {
ctDefs.add((WGContentTypeDefinition)def);
}
}
}
return Collections.unmodifiableList(ctDefs);
}
public WGContentTypeDefinition findContentTypeDefinition(WGMetaFieldDefinition metaDefinition) {
Iterator<WGContentTypeDefinition> ctDefs = getContentTypeDefinitions().iterator();
while (ctDefs.hasNext()) {
WGContentTypeDefinition def = ctDefs.next();
if (def.getMetadata().contains(metaDefinition)) {
return def;
}
}
return null;
}
public WGContentTypeDefinition findContentTypeDefinition(WGContentItemDefinition itemDefinition) {
Iterator<WGContentTypeDefinition> ctDefs = getContentTypeDefinitions().iterator();
while (ctDefs.hasNext()) {
WGContentTypeDefinition def = ctDefs.next();
if (def.getContentItemDefinitions().contains(itemDefinition)) {
return def;
}
}
return null;
}
public WGContentTypeDefinition createContentTypeDefinition() {
if (_schema == null && isFeatureSupported(FEATURE_SCHEMADEFINITION)) {
_schema = new WGSchemaDefinition();
fireSchemaModelChanged();
}
WGContentTypeDefinition cTypeDef = new WGContentTypeDefinition();
cTypeDef.setName("<name>");
_schema.addDocumentDefinition(cTypeDef);
fireSchemaModelChanged();
return cTypeDef;
}
public WGAreaDefinition createAreaDefinition() {
if (_schema == null && isFeatureSupported(FEATURE_SCHEMADEFINITION)) {
_schema = new WGSchemaDefinition();
fireSchemaModelChanged();
}
WGAreaDefinition def = new WGAreaDefinition();
def.setName("<name>");
_schema.addDocumentDefinition(def);
fireSchemaModelChanged();
return def;
}
public WGLanguageDefinition createLanguageDefinition() {
if (_schema == null && isFeatureSupported(FEATURE_SCHEMADEFINITION)) {
_schema = new WGSchemaDefinition();
fireSchemaModelChanged();
}
WGLanguageDefinition def = new WGLanguageDefinition();
def.setName("<name>");
_schema.addDocumentDefinition(def);
fireSchemaModelChanged();
return def;
}
public void addListener(WGASchemaDefinitionModelListener listener) {
_schemaModelListener.add(listener);
}
public void removeListener(WGASchemaDefinitionModelListener listener) {
_schemaModelListener.remove(listener);
}
private void fireSchemaModelChanged() {
for (WGASchemaDefinitionModelListener listener : _schemaModelListener) {
listener.modelChanged();
}
fireModelChanged();
}
public void removeSchemaDocumentDefintion(WGSchemaDocumentDefinition def) {
if (_schema.getDocumentDefinitions().remove(def)) {
fireSchemaModelChanged();
}
}
public void remove(WGContentItemDefinition def) {
WGContentTypeDefinition cTypeDef = findContentTypeDefinition(def);
if (cTypeDef != null) {
if (cTypeDef.getContentItemDefinitions().remove(def)) {
fireSchemaModelChanged();
}
}
}
public void remove(WGMetaFieldDefinition def) {
WGContentTypeDefinition cTypeDef = findContentTypeDefinition(def);
if (cTypeDef != null) {
if (cTypeDef.getMetadata().remove(def)) {
fireSchemaModelChanged();
}
}
}
@Override
public List<ValidationError> validate() {
List<ValidationError> errors = super.validate();
if (_schema != null) {
try {
_schema.validate();
} catch (Exception e) {
errors.add(new ValidationError(e.getMessage(), new String[] {PROPERTY_HINT_SCHEMADEF}));
}
}
return errors;
}
}