From 104dfca0657fbbe9e068d5198e4d77b5a9f2e15b Mon Sep 17 00:00:00 2001 From: Camille Letavernier Date: Mon, 5 May 2014 16:21:52 +0200 Subject: 434106: [Performances - EMF Facet] Major performance degration when using OCL queries in EMF Facet Customizations https://bugs.eclipse.org/bugs/show_bug.cgi?id=434106 --- .../query/QueryImplementationFactoryRegistry.java | 91 ++++++++++++---------- .../internal/evaluator/OclQueryImplementation.java | 86 ++++++++++---------- 2 files changed, 95 insertions(+), 82 deletions(-) (limited to 'plugins/facet') diff --git a/plugins/facet/org.eclipse.papyrus.emf.facet.efacet.core/src/org/eclipse/papyrus/emf/facet/efacet/core/internal/query/QueryImplementationFactoryRegistry.java b/plugins/facet/org.eclipse.papyrus.emf.facet.efacet.core/src/org/eclipse/papyrus/emf/facet/efacet/core/internal/query/QueryImplementationFactoryRegistry.java index 6df882e3d4e..29fb70de1e0 100644 --- a/plugins/facet/org.eclipse.papyrus.emf.facet.efacet.core/src/org/eclipse/papyrus/emf/facet/efacet/core/internal/query/QueryImplementationFactoryRegistry.java +++ b/plugins/facet/org.eclipse.papyrus.emf.facet.efacet.core/src/org/eclipse/papyrus/emf/facet/efacet/core/internal/query/QueryImplementationFactoryRegistry.java @@ -11,7 +11,9 @@ package org.eclipse.papyrus.emf.facet.efacet.core.internal.query; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IConfigurationElement; @@ -31,10 +33,15 @@ import org.eclipse.papyrus.emf.facet.util.emf.core.ICatalogSetManagerFactory; import org.osgi.framework.Bundle; public class QueryImplementationFactoryRegistry { + private static final String EXT_ID = "org.eclipse.papyrus.emf.facet.efacet.core.queryImplementationRegistration"; //$NON-NLS-1$ + private static final String CLASS = "class"; //$NON-NLS-1$ + public static final QueryImplementationFactoryRegistry INSTANCE = new QueryImplementationFactoryRegistry(); + private static final Map cache = new HashMap(); + private final List factories = new ArrayList(); public QueryImplementationFactoryRegistry() { @@ -44,17 +51,17 @@ public class QueryImplementationFactoryRegistry { private void initRegisteredEntries() { final IExtensionRegistry registry = Platform.getExtensionRegistry(); final IExtensionPoint extPoint = registry.getExtensionPoint(QueryImplementationFactoryRegistry.EXT_ID); - if (extPoint != null) { - for (final IExtension ext : extPoint.getExtensions()) { - for (final IConfigurationElement configElt : ext.getConfigurationElements()) { + if(extPoint != null) { + for(final IExtension ext : extPoint.getExtensions()) { + for(final IConfigurationElement configElt : ext.getConfigurationElements()) { try { final Object impl = configElt.createExecutableExtension(QueryImplementationFactoryRegistry.CLASS); - if (impl instanceof IQueryImplementationFactory) { - final IQueryImplementationFactory factory = (IQueryImplementationFactory) impl; + if(impl instanceof IQueryImplementationFactory) { + final IQueryImplementationFactory factory = (IQueryImplementationFactory)impl; this.factories.add(factory); } else { Logger.logError("Invalid extension in " + ext.getNamespaceIdentifier() + "." + //$NON-NLS-1$ //$NON-NLS-2$ - ". The factory must be an instance of " + IQueryImplementationFactory.class.getName(), Activator.getDefault()); //$NON-NLS-1$ + ". The factory must be an instance of " + IQueryImplementationFactory.class.getName(), Activator.getDefault()); //$NON-NLS-1$ } } catch (final CoreException e) { Logger.logError(e, Activator.getDefault()); @@ -66,49 +73,55 @@ public class QueryImplementationFactoryRegistry { /** * Returns the query evaluator that handles the given type of query - * + * * @param query - * the type of query for which an {@link IQueryImplementation} is searched + * the type of query for which an {@link IQueryImplementation} is searched * @return the {@link IQueryImplementation} * @throws DerivedTypedElementException - * if no factory implementation was registered for the type of the given query + * if no factory implementation was registered for the type of the given query */ - public IQueryImplementation getEvaluatorFor(final Query query, final IDerivedTypedElementManager manager) - throws DerivedTypedElementException { - if (query == null) { + public IQueryImplementation getEvaluatorFor(final Query query, final IDerivedTypedElementManager manager) throws DerivedTypedElementException { + if(query == null) { throw new IllegalArgumentException("query cannot be null"); //$NON-NLS-1$ } - IQueryImplementation queryImpl = null; - boolean factoryFound = false; - for (final IQueryImplementationFactory queryImplFactory : this.factories) { - factoryFound = queryImplFactory.getManagedQueryType() == query.eClass(); - if (factoryFound) { - final Resource queryResource = query.eResource(); - Bundle bundle = null; - if (queryResource != null) { - bundle = ICatalogSetManagerFactory.DEFAULT.createICatalogSetManager(query.eResource().getResourceSet()).getBundleByResource(queryResource); + + if(!cache.containsKey(query)) { + + IQueryImplementation queryImpl = null; + boolean factoryFound = false; + for(final IQueryImplementationFactory queryImplFactory : this.factories) { + factoryFound = queryImplFactory.getManagedQueryType() == query.eClass(); + if(factoryFound) { + final Resource queryResource = query.eResource(); + Bundle bundle = null; + if(queryResource != null) { + bundle = ICatalogSetManagerFactory.DEFAULT.createICatalogSetManager(query.eResource().getResourceSet()).getBundleByResource(queryResource); + } + queryImpl = queryImplFactory.create(query, bundle, manager); + break; } - queryImpl = queryImplFactory.create(query, bundle, manager); - break; } - } - if (!factoryFound) { - final StringBuffer buffer = new StringBuffer(); - buffer.append("No factory implementation found for "); //$NON-NLS-1$ - buffer.append(QueryUtils.getQueryDescription(query)); - buffer.append(".\nA factory should be registered through the "); //$NON-NLS-1$ - buffer.append(QueryImplementationFactoryRegistry.EXT_ID); - buffer.append(" extension point."); //$NON-NLS-1$ // NOPMD: cannot merge with extracted constant string - buffer.append("\nAvailable Query types are: "); //$NON-NLS-1$ - for (int i = 0; i < this.factories.size(); i++) { - if (i > 0) { - buffer.append(", "); //$NON-NLS-1$ + if(!factoryFound) { + final StringBuffer buffer = new StringBuffer(); + buffer.append("No factory implementation found for "); //$NON-NLS-1$ + buffer.append(QueryUtils.getQueryDescription(query)); + buffer.append(".\nA factory should be registered through the "); //$NON-NLS-1$ + buffer.append(QueryImplementationFactoryRegistry.EXT_ID); + buffer.append(" extension point."); //$NON-NLS-1$ // NOPMD: cannot merge with extracted constant string + buffer.append("\nAvailable Query types are: "); //$NON-NLS-1$ + for(int i = 0; i < this.factories.size(); i++) { + if(i > 0) { + buffer.append(", "); //$NON-NLS-1$ + } + final IQueryImplementationFactory factory = this.factories.get(i); + buffer.append(factory.getManagedQueryType().getName()); } - final IQueryImplementationFactory factory = this.factories.get(i); - buffer.append(factory.getManagedQueryType().getName()); + throw new DerivedTypedElementException(buffer.toString()); } - throw new DerivedTypedElementException(buffer.toString()); + + cache.put(query, queryImpl); } - return queryImpl; + + return cache.get(query); } } diff --git a/plugins/facet/org.eclipse.papyrus.emf.facet.query.ocl.core/src/org/eclipse/papyrus/emf/facet/query/ocl/core/internal/evaluator/OclQueryImplementation.java b/plugins/facet/org.eclipse.papyrus.emf.facet.query.ocl.core/src/org/eclipse/papyrus/emf/facet/query/ocl/core/internal/evaluator/OclQueryImplementation.java index b17f704e90a..244efdea0e6 100644 --- a/plugins/facet/org.eclipse.papyrus.emf.facet.query.ocl.core/src/org/eclipse/papyrus/emf/facet/query/ocl/core/internal/evaluator/OclQueryImplementation.java +++ b/plugins/facet/org.eclipse.papyrus.emf.facet.query.ocl.core/src/org/eclipse/papyrus/emf/facet/query/ocl/core/internal/evaluator/OclQueryImplementation.java @@ -1,11 +1,11 @@ /** * Copyright (c) 2012 Mia-Software. - * + * * 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: * Alban Ménager (Soft-Maint) - Bug 387470 - [EFacet][Custom] Editors * Grégoire Dupé (Mia-Software) - Bug 387470 - [EFacet][Custom] Editors @@ -16,6 +16,8 @@ import java.util.List; import org.eclipse.emf.ecore.EClassifier; import org.eclipse.emf.ecore.EObject; +import org.eclipse.ocl.ParserException; +import org.eclipse.ocl.expressions.OCLExpression; import org.eclipse.papyrus.emf.facet.efacet.core.IFacetManager; import org.eclipse.papyrus.emf.facet.efacet.core.exception.DerivedTypedElementException; import org.eclipse.papyrus.emf.facet.efacet.core.query.IQueryImplementation; @@ -24,70 +26,68 @@ import org.eclipse.papyrus.emf.facet.efacet.metamodel.v0_2_0.efacet.ParameterVal import org.eclipse.papyrus.emf.facet.efacet.metamodel.v0_2_0.efacet.extensible.Query; import org.eclipse.papyrus.emf.facet.query.ocl.core.util.OclQueryUtil; import org.eclipse.papyrus.emf.facet.query.ocl.metamodel.oclquery.OclQuery; -import org.eclipse.ocl.ParserException; -import org.eclipse.ocl.expressions.OCLExpression; /** * Concrete implementation of {@link IQueryImplementation} for the OCL query. */ public class OclQueryImplementation implements IQueryImplementation { - public void setValue(final Query query, final DerivedTypedElement feature, - final EObject source, final List parameterValues, - final Object newValue) throws DerivedTypedElementException { + protected OCLExpression oclExpression; + + @Override + public void setValue(final Query query, final DerivedTypedElement feature, final EObject source, final List parameterValues, final Object newValue) throws DerivedTypedElementException { throw new UnsupportedOperationException("not implemented yet"); //$NON-NLS-1$ } + @Override public boolean isCheckResultType() { return true; } - public Object getValue(final Query query, - final DerivedTypedElement feature, final EObject source, - final List parameterValues, - final IFacetManager facetManager) - throws DerivedTypedElementException { - if (!(query instanceof OclQuery)) { - throw new IllegalArgumentException( - "The given DerivedTypedElement does not have a OclQuery"); //$NON-NLS-1$ + @Override + public Object getValue(final Query query, final DerivedTypedElement feature, final EObject source, final List parameterValues, final IFacetManager facetManager) throws DerivedTypedElementException { + if(!(query instanceof OclQuery)) { + throw new IllegalArgumentException("The given DerivedTypedElement does not have a OclQuery"); //$NON-NLS-1$ } try { - return executeOclQuery(source, parameterValues, (OclQuery) query); + return executeOclQuery(source, parameterValues, (OclQuery)query); } catch (Exception e) { throw new DerivedTypedElementException(e); } } - protected static Object executeOclQuery(final EObject source, - final List parameterValues, final OclQuery oclQuery) - throws ParserException { + protected Object executeOclQuery(final EObject source, final List parameterValues, final OclQuery oclQuery) throws ParserException { Object evaluateQuery = null; - OCLExpression oclExpression = null; - String stringExpression = oclQuery.getOclExpression(); + final EClassifier context = oclQuery.getContext(); - // We replace all the occurrence of the parameters in the query by the - // corresponding value. - if (stringExpression != null) { - if (parameterValues != null) { - for (final ParameterValue paramValue : parameterValues) { - final String tmp = stringExpression; - final String name = paramValue.getParameter().getName(); - final Object value = paramValue.getValue(); - String string; - if (value == null) { - string = "null"; //$NON-NLS-1$ - } else { - string = value.toString(); - } - stringExpression = tmp.replaceAll(name, string); - } - } - oclExpression = OclQueryUtil.createOCLExpression(context, - stringExpression); + + if(oclExpression == null) { + String stringExpression = oclQuery.getOclExpression(); + + // We replace all the occurrence of the parameters in the query by the + // corresponding value. + // if (stringExpression != null) { + // if (parameterValues != null) { + // for (final ParameterValue paramValue : parameterValues) { + // final String tmp = stringExpression; + // final String name = paramValue.getParameter().getName(); + // final Object value = paramValue.getValue(); + // String string; + // if (value == null) { + // string = "null"; //$NON-NLS-1$ + // } else { + // string = value.toString(); + // } + // stringExpression = tmp.replaceAll(name, string); + // } + // } + // } + + oclExpression = OclQueryUtil.createOCLExpression(context, stringExpression); } - if (oclExpression != null) { - evaluateQuery = OclQueryUtil.evaluateQuery(context, oclExpression, - source); + + if(oclExpression != null) { + evaluateQuery = OclQueryUtil.evaluateQuery(context, oclExpression, source); } return evaluateQuery; } -- cgit v1.2.1