// ============================================================================
//
// Copyright (C) 2006-2016 Talend Inc. - www.talend.com
//
// This source code is available under agreement available at
// %InstallDIR%\features\org.talend.rcp.branding.%PRODUCTNAME%\%PRODUCTNAME%license.txt
//
// You should have received a copy of the agreement
// along with this program; if not, write to Talend SA
// 9 rue Pages 92150 Suresnes, France
//
// ============================================================================
package com.amalto.workbench.detailtabs.sections.composites;
import org.eclipse.emf.common.notify.Adapter;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.Notifier;
import org.eclipse.emf.common.util.EList;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.xsd.XSDAnnotation;
import org.eclipse.xsd.XSDComponent;
import org.eclipse.xsd.XSDElementDeclaration;
import org.eclipse.xsd.XSDFactory;
import org.eclipse.xsd.XSDParticle;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import com.amalto.workbench.detailtabs.sections.ElementFKSection;
import com.amalto.workbench.i18n.Messages;
public class FKIntegrityComposite extends Composite {
private static final String X_FK_INTEGRITY_OVERRIDE = "X_FKIntegrity_Override"; //$NON-NLS-1$
private static final String X_FK_INTEGRITY = "X_FKIntegrity"; //$NON-NLS-1$
private final Button btnAllowFkIntegrity;
private final Button btnEnforceFkIntegrity;
private final ViewRefreshAdapter refreshAdapter = new ViewRefreshAdapter();
private XSDElementDeclaration xsdComponent;
private ElementFKSection elementFKSection;
/**
* Create the composite.
*
* @param parent
* @param style
* @param elementFKSection
* @param curXSDComponent
* @param xsdElementDeclaration
*/
public FKIntegrityComposite(Composite parent, int style,
XSDComponent xsdComponent, ElementFKSection elementFKSection) {
super(parent, style);
GridLayout gridLayout = new GridLayout(1, false);
gridLayout.marginWidth = 0;
gridLayout.marginHeight = 0;
gridLayout.horizontalSpacing = 10;
setLayout(gridLayout);
btnEnforceFkIntegrity = new Button(this, SWT.FLAT | SWT.CHECK);
btnEnforceFkIntegrity.setText(Messages.FKIntegrityComposite_EnforceFKIntegrity);
btnEnforceFkIntegrity.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
boolean enforceFK = btnEnforceFkIntegrity.getSelection();
btnAllowFkIntegrity.setEnabled(enforceFK);
if (!enforceFK) {
// Disable allow fk override once fk integrity is disabled.
btnAllowFkIntegrity.setSelection(false);
}
updateModel();
}
});
btnEnforceFkIntegrity.setLayoutData(new GridData(SWT.FILL, SWT.FILL,
false, false, 1, 1));
btnEnforceFkIntegrity.setSelection(true);
btnAllowFkIntegrity = new Button(this, SWT.CHECK);
btnAllowFkIntegrity.setText(Messages.FKIntegrityComposite_AllowFKIntergrityOverride);
btnAllowFkIntegrity.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
updateModel();
}
});
btnAllowFkIntegrity.setLayoutData(new GridData(SWT.FILL, SWT.FILL,
false, false, 1, 1));
btnAllowFkIntegrity.setSelection(false);
this.elementFKSection = elementFKSection;
}
@Override
protected void checkSubclass() {
// Disable the check that prevents subclassing of SWT components
}
@Override
public void dispose() {
super.dispose();
// Remove listener on disposal (no more need to keep view in sync with
// model)
xsdComponent.eAdapters().remove(refreshAdapter);
}
private void refresh() {
XSDAnnotation annotation = xsdComponent.getAnnotation();
if (annotation == null) {
annotation = XSDFactory.eINSTANCE.createXSDAnnotation();
}
Element fkIntegrityElement = null;
Element fkIntegrityOverrideElement = null;
EList<Element> appInfo = annotation.getApplicationInformation();
for (Element currentElement : appInfo) {
String source = currentElement.getAttribute("source"); //$NON-NLS-1$
if (X_FK_INTEGRITY.endsWith(source)) {
fkIntegrityElement = currentElement;
} else if (X_FK_INTEGRITY_OVERRIDE.endsWith(source)) {
fkIntegrityOverrideElement = currentElement;
}
}
if (fkIntegrityElement != null) {
String textContent = fkIntegrityElement.getTextContent();
boolean enabled = textContent == null ? true : Boolean
.valueOf(textContent);
btnEnforceFkIntegrity.setSelection(enabled);
} else {
btnEnforceFkIntegrity.setSelection(true); // default is true
}
if (fkIntegrityOverrideElement != null) {
String textContent = fkIntegrityOverrideElement.getTextContent();
boolean enabled = textContent == null ? true : Boolean
.valueOf(textContent);
btnAllowFkIntegrity.setSelection(enabled);
} else {
btnAllowFkIntegrity.setSelection(false); // default is false for override
}
// refresh buttion enabled
if (xsdComponent.getAnnotation() == null) {
btnEnforceFkIntegrity.setEnabled(false);
btnAllowFkIntegrity.setEnabled(false);
} else {
btnEnforceFkIntegrity.setEnabled(true);
btnAllowFkIntegrity.setEnabled(btnEnforceFkIntegrity.getSelection());
}
}
private void updateModel() {
XSDAnnotation annotation = xsdComponent.getAnnotation();
if (annotation == null) {
annotation = XSDFactory.eINSTANCE.createXSDAnnotation();
xsdComponent.setAnnotation(annotation);
}
Element fkIntegrityElement = null;
Element fkIntegrityOverrideElement = null;
EList<Element> appInfo = annotation.getApplicationInformation();
for (Element currentElement : appInfo) {
String source = currentElement.getAttribute("source"); //$NON-NLS-1$
if (X_FK_INTEGRITY.endsWith(source)) {
fkIntegrityElement = currentElement;
} else if (X_FK_INTEGRITY_OVERRIDE.endsWith(source)) {
fkIntegrityOverrideElement = currentElement;
}
}
updateModelElement(xsdComponent, fkIntegrityElement, X_FK_INTEGRITY,
btnEnforceFkIntegrity.getSelection());
updateModelElement(xsdComponent, fkIntegrityOverrideElement,
X_FK_INTEGRITY_OVERRIDE, btnAllowFkIntegrity.getSelection());
this.elementFKSection.autoCommit();
}
private static void updateModelElement(XSDElementDeclaration xsdComponent,
Element property, String type, boolean value) {
Element xsdDeclarationDomElement = xsdComponent.getElement();
if (property == null) {
Document ownerDocument = xsdDeclarationDomElement
.getOwnerDocument();
property = ownerDocument.createElementNS(
xsdDeclarationDomElement.getNamespaceURI(), "appinfo"); //$NON-NLS-1$
property.setPrefix("xsd"); //$NON-NLS-1$
property.setAttribute("source", type); //$NON-NLS-1$
property.setTextContent(Boolean.toString(value));
xsdComponent.getAnnotation().getApplicationInformation()
.add(property);
xsdComponent.getAnnotation().getElement().appendChild(property);
} else {
xsdComponent.getAnnotation().getApplicationInformation()
.remove(property);
property.setTextContent(Boolean.toString(value));
xsdComponent.getAnnotation().getApplicationInformation()
.add(property);
}
}
private class ViewRefreshAdapter implements Adapter {
private Notifier notifier;
public void setTarget(Notifier notifier) {
this.notifier = notifier;
}
public void notifyChanged(Notification event) {
if (!event.isTouch()) {
refresh();
}
}
public boolean isAdapterForType(Object obj) {
return obj instanceof XSDElementDeclaration;
}
public Notifier getTarget() {
return notifier;
}
}
public void setXSDComponent(XSDComponent xsdComponent) {
if (xsdComponent == null) {
throw new IllegalArgumentException(
Messages.FKIntegrityComposite_ArgCannotbeNull);
}
if (!(xsdComponent instanceof XSDParticle)) {
throw new IllegalArgumentException(Messages.bind(Messages.FKIntegrityComposite_ExceptionInfo,
XSDElementDeclaration.class.getName(), xsdComponent.getClass().getName()));
}
// Take into account only component change
if (xsdComponent != this.xsdComponent) {
if (this.xsdComponent != null) {
this.xsdComponent.eAdapters().remove(refreshAdapter);
}
this.xsdComponent = (XSDElementDeclaration) ((XSDParticle) xsdComponent)
.getContent();
this.xsdComponent.eAdapters().add(refreshAdapter);
}
// Update UI with the information in the XSDComponent
refresh();
}
}