/******************************************************************************* * Copyright (c) 2009 Red Hat, Inc. * Distributed under license by Red Hat, Inc. All rights reserved. * This program is 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: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ package org.jboss.tools.smooks.configuration.validate; import java.io.IOException; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.emf.common.command.BasicCommandStack; import org.eclipse.emf.common.notify.AdapterFactory; import org.eclipse.emf.common.util.BasicDiagnostic; import org.eclipse.emf.common.util.Diagnostic; import org.eclipse.emf.common.util.DiagnosticChain; import org.eclipse.emf.common.util.URI; import org.eclipse.emf.ecore.EClass; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.resource.Resource; import org.eclipse.emf.ecore.util.Diagnostician; import org.eclipse.emf.edit.domain.AdapterFactoryEditingDomain; import org.eclipse.emf.edit.domain.EditingDomain; import org.eclipse.emf.edit.provider.ComposedAdapterFactory; import org.eclipse.emf.edit.provider.IItemLabelProvider; import org.eclipse.emf.edit.provider.ReflectiveItemProviderAdapterFactory; import org.eclipse.emf.edit.provider.resource.ResourceItemProviderAdapterFactory; import org.eclipse.swt.widgets.Display; import org.eclipse.wst.validation.AbstractValidator; import org.eclipse.wst.validation.ValidationResult; import org.eclipse.wst.validation.ValidationState; import org.eclipse.wst.validation.internal.provisional.core.IReporter; import org.eclipse.wst.validation.internal.provisional.core.IValidationContext; import org.eclipse.wst.validation.internal.provisional.core.IValidator; import org.jboss.tools.smooks.model.common.provider.CommonItemProviderAdapterFactory; import org.jboss.tools.smooks.model.freemarker.provider.FreemarkerItemProviderAdapterFactory; import org.jboss.tools.smooks.model.medi.provider.MEdiItemProviderAdapterFactory; import org.jboss.tools.smooks.model.smooks.provider.SmooksItemProviderAdapterFactory; import org.jboss.tools.smooks.model.smooks.util.SmooksResourceFactoryImpl; /** * @author Dart (dpeng@redhat.com) * <p> * Apr 14, 2009 */ public class SmooksModelValidator extends AbstractValidator implements IValidator, ISmooksValidator { Collection<?> selectedObjects; EditingDomain domain; private boolean starting = false; private boolean waiting = false; private Object lock = new Object(); private AdapterFactoryEditingDomain innerEditingDomain; private SmooksMarkerHelper markerHelper = new SmooksMarkerHelper(); private long watingTime = 300; private List<ISmooksModelValidateListener> listeners = new ArrayList<ISmooksModelValidateListener>(); private List<ISmooksValidator> validatorList = new ArrayList<ISmooksValidator>(); private ComposedAdapterFactory adapterFactory; public SmooksModelValidator(Collection<?> selectedObjects, EditingDomain domain) { this(); this.selectedObjects = selectedObjects; this.domain = domain; } public SmooksModelValidator() { validatorList.add(new ClassFieldEditorValidator()); validatorList.add(new DuplicatedBeanIDValidator()); validatorList.add(new BeanIdRefValidator()); validatorList.add(new SelectorValidator()); validatorList.add(new PropertyValidator()); validatorList.add(new SetterMethodValidator()); // validatorList.add(new DecoderTypeValidator()); innerEditingDomain = newEditingDomain(); } public void addValidateListener(ISmooksModelValidateListener l) { if (!listeners.contains(l)) listeners.add(l); } public void removeValidateListener(ISmooksModelValidateListener l) { listeners.remove(l); } public List<Diagnostic> validate(Collection<?> selectedObjects, EditingDomain editingDomain) { this.selectedObjects = selectedObjects; domain = editingDomain; return validate(new NullProgressMonitor()); } public List<Diagnostic> validate(Collection<?> selectedObjects, EditingDomain editingDomain, IProgressMonitor monitor) { this.selectedObjects = selectedObjects; domain = editingDomain; return validate(monitor); } public List<Diagnostic> validate(final IProgressMonitor progressMonitor) { EObject eObject = (EObject) selectedObjects.iterator().next(); int count = 0; for (Iterator<?> i = eObject.eAllContents(); i.hasNext(); i.next()) { ++count; } progressMonitor.beginTask("", count); //$NON-NLS-1$ final AdapterFactory adapterFactory = domain instanceof AdapterFactoryEditingDomain ? ((AdapterFactoryEditingDomain) domain) .getAdapterFactory() : null; Diagnostician diagnostician = new Diagnostician() { @Override public String getObjectLabel(EObject eObject) { if (adapterFactory != null && !eObject.eIsProxy()) { IItemLabelProvider itemLabelProvider = (IItemLabelProvider) adapterFactory.adapt(eObject, IItemLabelProvider.class); if (itemLabelProvider != null) { return itemLabelProvider.getText(eObject); } } return super.getObjectLabel(eObject); } @Override public boolean validate(EClass eClass, EObject eObject, DiagnosticChain diagnostics, Map<Object, Object> context) { progressMonitor.worked(1); return super.validate(eClass, eObject, diagnostics, context); } }; progressMonitor.setTaskName(Messages.SmooksModelValidator_Task_Validating); Diagnostic diagnostic = diagnostician.validate(eObject); List<Diagnostic> list = new ArrayList<Diagnostic>(); list.add(diagnostic); try { for (Iterator<?> iterator = this.validatorList.iterator(); iterator.hasNext();) { ISmooksValidator validator = (ISmooksValidator) iterator.next(); validator.initValidator(selectedObjects, domain); List<Diagnostic> d = validator.validate(selectedObjects, domain); if (d != null) { for (Iterator<?> iterator2 = d.iterator(); iterator2.hasNext();) { Diagnostic diagnostic2 = (Diagnostic) iterator2.next(); ((BasicDiagnostic) diagnostic).add(diagnostic2); } } } } catch (Exception e) { } return list; } public void startValidate(final Collection<?> selectedObjects, final EditingDomain editingDomain) { if (starting) { synchronized (lock) { waiting = true; } return; } Thread thread = new Thread() { public void run() { synchronized (lock) { starting = true; waiting = true; } while (waiting) { try { waiting = false; Thread.sleep(watingTime); Thread.yield(); } catch (InterruptedException e) { e.printStackTrace(); } } try { for (Iterator<?> iterator = listeners.iterator(); iterator.hasNext();) { final ISmooksModelValidateListener l = (ISmooksModelValidateListener) iterator.next(); Display.getDefault().syncExec(new Runnable() { /* * (non-Javadoc) * * @see java.lang.Runnable#run() */ public void run() { l.validateStart(); } }); } final List<Diagnostic> d = validate(selectedObjects, editingDomain); for (Iterator<?> iterator = listeners.iterator(); iterator.hasNext();) { final ISmooksModelValidateListener l = (ISmooksModelValidateListener) iterator.next(); Display dis = Display.getDefault(); if (dis != null && !dis.isDisposed()) { dis.syncExec(new Runnable() { /* * (non-Javadoc) * * @see java.lang.Runnable#run() */ public void run() { l.validateEnd(d); } }); } } } finally { waiting = false; starting = false; } } }; thread.setName(Messages.SmooksModelValidator_Task_Validating_Smooks_Model); thread.start(); } private AdapterFactoryEditingDomain newEditingDomain() { BasicCommandStack commandStack = new BasicCommandStack(); if (innerEditingDomain == null) { innerEditingDomain = new AdapterFactoryEditingDomain(getAdapterFactory(), commandStack, new HashMap<Resource, Boolean>()); } return innerEditingDomain; } public ComposedAdapterFactory getAdapterFactory() { if (adapterFactory == null) { adapterFactory = new ComposedAdapterFactory(ComposedAdapterFactory.Descriptor.Registry.INSTANCE); adapterFactory.addAdapterFactory(new ResourceItemProviderAdapterFactory()); adapterFactory.addAdapterFactory(new FreemarkerItemProviderAdapterFactory()); adapterFactory.addAdapterFactory(new CommonItemProviderAdapterFactory()); adapterFactory.addAdapterFactory(new SmooksItemProviderAdapterFactory()); adapterFactory.addAdapterFactory(new MEdiItemProviderAdapterFactory()); adapterFactory.addAdapterFactory(new ReflectiveItemProviderAdapterFactory()); } return adapterFactory; } @Override public ValidationResult validate(IResource resource, int kind, ValidationState state, IProgressMonitor monitor) { AdapterFactoryEditingDomain editingDomain = newEditingDomain(); if (editingDomain == null) return null; Object smooksModel = null; Resource smooksResource = new SmooksResourceFactoryImpl().createResource(URI.createPlatformResourceURI(resource .getFullPath().toPortableString(), false)); editingDomain.getResourceSet().getResources().add(smooksResource); try { smooksResource.load(Collections.emptyMap()); smooksModel = smooksResource.getContents().get(0); } catch (IOException e) { return null; } if (smooksModel == null) { return null; } List<Object> list = new ArrayList<Object>(); list.add(smooksModel); final List<Diagnostic> d = this.validate(list, editingDomain, monitor); try { markerHelper.deleteMarkers(smooksResource); for (Iterator<?> iterator = d.iterator(); iterator.hasNext();) { Diagnostic diagnostic = (Diagnostic) iterator.next(); if (resource != null && diagnostic.getSeverity() != Diagnostic.OK) { for (Diagnostic childDiagnostic : diagnostic.getChildren()) { markerHelper.createMarkers(smooksResource, childDiagnostic); } } } } catch (Exception e) { e.printStackTrace(); } return null; } public void cleanup(IReporter reporter) { } public void validate(IValidationContext helper, IReporter reporter) { } public void initValidator(Collection<?> selectedObjects, EditingDomain editingDomain) { // TODO Auto-generated method stub } }