// ============================================================================ // // 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(); } }