Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Fleck2016-06-21 07:28:08 +0000
committerGerrit Code Review @ Eclipse.org2016-06-27 15:17:57 +0000
commit0a4fa8933935a3160633e4122eb26a14a0c4aa35 (patch)
tree75133884b80a14a6c9456eddc24e293368569757 /plugins/uml/org.eclipse.papyrus.uml.modelrepair
parent4c1f28e71861ba3c933a6ca4d46d7c90644bb878 (diff)
downloadorg.eclipse.papyrus-0a4fa8933935a3160633e4122eb26a14a0c4aa35.tar.gz
org.eclipse.papyrus-0a4fa8933935a3160633e4122eb26a14a0c4aa35.tar.xz
org.eclipse.papyrus-0a4fa8933935a3160633e4122eb26a14a0c4aa35.zip
Bug 496307: [Profile Migration] Restrictive package pattern matching
- Add ProfileNamespaceURIPatterns to split namespace URIs into a versionless, identifying namespace URI and the version information. A namespace URI is matched by a given Regex pattern. The versionless namespace URI is a concatenation of all parts of the matches that are not in groups. The version information is a formatted string consisting of the parts matched through the groups in the pattern and therefore may be spread across the URI. The format of the resulting version string can be customized using a dedicated MessageFormat. - Add extension point for profile namespace URI patterns. - Add pattern registry that is initialized with extension points. - Add usage of profile namespace URI patterns when comparing URIs in the zombie stereotypes descriptor, if there is no perfect equality. If no registered pattern handles the URIs, the previous behavior is used as default. - Bump plugin version to 1.2.1 Includes tests for the pattern matching and splitting. Includes tests to test reported behavior and the improved behavior in the zombie stereotypes descriptor. Change-Id: I5f7744c2a19bb20ea2572247f6d47f948504f7b4 Signed-off-by: Martin Fleck <mfleck@eclipsesource.com>
Diffstat (limited to 'plugins/uml/org.eclipse.papyrus.uml.modelrepair')
-rw-r--r--plugins/uml/org.eclipse.papyrus.uml.modelrepair/META-INF/MANIFEST.MF3
-rw-r--r--plugins/uml/org.eclipse.papyrus.uml.modelrepair/plugin.xml1
-rw-r--r--plugins/uml/org.eclipse.papyrus.uml.modelrepair/pom.xml2
-rw-r--r--plugins/uml/org.eclipse.papyrus.uml.modelrepair/schema/profileNamespaceURIPattern.exsd173
-rw-r--r--plugins/uml/org.eclipse.papyrus.uml.modelrepair/src/org/eclipse/papyrus/uml/modelrepair/internal/stereotypes/ZombieStereotypesDescriptor.java26
-rw-r--r--plugins/uml/org.eclipse.papyrus.uml.modelrepair/src/org/eclipse/papyrus/uml/modelrepair/internal/uripattern/ProfileNamespaceURIPattern.java160
-rw-r--r--plugins/uml/org.eclipse.papyrus.uml.modelrepair/src/org/eclipse/papyrus/uml/modelrepair/internal/uripattern/ProfileNamespaceURIPatternComparison.java116
-rw-r--r--plugins/uml/org.eclipse.papyrus.uml.modelrepair/src/org/eclipse/papyrus/uml/modelrepair/internal/uripattern/ProfileNamespaceURIPatternMatchResult.java231
-rw-r--r--plugins/uml/org.eclipse.papyrus.uml.modelrepair/src/org/eclipse/papyrus/uml/modelrepair/internal/uripattern/ProfileNamespaceURIPatternRegistry.java235
9 files changed, 940 insertions, 7 deletions
diff --git a/plugins/uml/org.eclipse.papyrus.uml.modelrepair/META-INF/MANIFEST.MF b/plugins/uml/org.eclipse.papyrus.uml.modelrepair/META-INF/MANIFEST.MF
index 82a6f36772f..7b725191468 100644
--- a/plugins/uml/org.eclipse.papyrus.uml.modelrepair/META-INF/MANIFEST.MF
+++ b/plugins/uml/org.eclipse.papyrus.uml.modelrepair/META-INF/MANIFEST.MF
@@ -3,6 +3,7 @@ Export-Package: org.eclipse.papyrus.uml.modelrepair,
org.eclipse.papyrus.uml.modelrepair.handler,
org.eclipse.papyrus.uml.modelrepair.internal.participants;x-internal:=true,
org.eclipse.papyrus.uml.modelrepair.internal.stereotypes;x-friends:="org.eclipse.papyrus.migration.rsa",
+ org.eclipse.papyrus.uml.modelrepair.internal.uripattern,
org.eclipse.papyrus.uml.modelrepair.internal.validation;x-internal:=true,
org.eclipse.papyrus.uml.modelrepair.service,
org.eclipse.papyrus.uml.modelrepair.ui,
@@ -15,7 +16,7 @@ Require-Bundle: org.eclipse.papyrus.uml.extensionpoints;bundle-version="[1.2.0,2
org.eclipse.uml2.uml.edit;bundle-version="[5.1.0,6.0.0)"
Bundle-Vendor: Eclipse Modeling Project
Bundle-ActivationPolicy: lazy
-Bundle-Version: 1.2.0.qualifier
+Bundle-Version: 1.2.1.qualifier
Bundle-Name: Model Repair
Bundle-Activator: org.eclipse.papyrus.uml.modelrepair.Activator
Bundle-ManifestVersion: 2
diff --git a/plugins/uml/org.eclipse.papyrus.uml.modelrepair/plugin.xml b/plugins/uml/org.eclipse.papyrus.uml.modelrepair/plugin.xml
index aa3de8549fe..139bc9c5224 100644
--- a/plugins/uml/org.eclipse.papyrus.uml.modelrepair/plugin.xml
+++ b/plugins/uml/org.eclipse.papyrus.uml.modelrepair/plugin.xml
@@ -2,6 +2,7 @@
<?eclipse version="3.4"?>
<plugin>
<extension-point id="org.eclipse.papyrus.uml.modelrepair.profileSwitchPreconditions" name="Profile Switch Preconditions" schema="schema/profileSwitchPreconditions.exsd"/>
+ <extension-point id="org.eclipse.papyrus.uml.modelrepair.profileNamespaceURIPattern" name="Profile Namespace URI Pattern" schema="schema/profileNamespaceURIPattern.exsd"/>
<extension
point="org.eclipse.ui.menus">
<menuContribution
diff --git a/plugins/uml/org.eclipse.papyrus.uml.modelrepair/pom.xml b/plugins/uml/org.eclipse.papyrus.uml.modelrepair/pom.xml
index c5fe2b7f076..a844c7378ce 100644
--- a/plugins/uml/org.eclipse.papyrus.uml.modelrepair/pom.xml
+++ b/plugins/uml/org.eclipse.papyrus.uml.modelrepair/pom.xml
@@ -7,6 +7,6 @@
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>org.eclipse.papyrus.uml.modelrepair</artifactId>
- <version>1.2.0-SNAPSHOT</version>
+ <version>1.2.1-SNAPSHOT</version>
<packaging>eclipse-plugin</packaging>
</project>
diff --git a/plugins/uml/org.eclipse.papyrus.uml.modelrepair/schema/profileNamespaceURIPattern.exsd b/plugins/uml/org.eclipse.papyrus.uml.modelrepair/schema/profileNamespaceURIPattern.exsd
new file mode 100644
index 00000000000..031ed27ce8b
--- /dev/null
+++ b/plugins/uml/org.eclipse.papyrus.uml.modelrepair/schema/profileNamespaceURIPattern.exsd
@@ -0,0 +1,173 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.papyrus.uml.modelrepair" xmlns="http://www.w3.org/2001/XMLSchema">
+<annotation>
+ <appinfo>
+ <meta.schema plugin="org.eclipse.papyrus.uml.modelrepair" id="profileNamespaceURIPattern" name="Profile Namespace URI Pattern"/>
+ </appinfo>
+ <documentation>
+ This extension point is for supporting the profile migration mechanism in Papyrus.
+It provides a regex pattern that identifies the namespace URIs of a profile and enables to extract version information from the URI through pattern groups.
+During the migration, only the namespace URIs minus the version information is used to identify profiles.
+Even if no version information is encoded in the URI, profile providers may use this extension point to enable the automatic migration of their profiles within Papyrus.
+ </documentation>
+ </annotation>
+
+ <element name="extension">
+ <annotation>
+ <appinfo>
+ <meta.element />
+ </appinfo>
+ </annotation>
+ <complexType>
+ <sequence minOccurs="1" maxOccurs="unbounded">
+ <element ref="profileNamespaceURIPattern"/>
+ </sequence>
+ <attribute name="point" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="id" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="name" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appinfo>
+ <meta.attribute translatable="true"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="profileNamespaceURIPattern">
+ <complexType>
+ <attribute name="uriPattern" type="string" use="required">
+ <annotation>
+ <documentation>
+ Regex pattern identifying profile namespace URIs during the profile migration. Groups in the pattern are used to extract versioning information.
+Backslashes (&apos;\&apos;) should not be escaped.
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="versionFormat" type="string">
+ <annotation>
+ <documentation>
+ MessageFormat string to produce the versioning string from the groups extracted by the uriPattern. Indices in the format correspond to the indices of the groups matched by the pattern, e.g., {0} refers to group zero holding the entire matched namespace URI and {1} refers to the first matched group. If no format is provided, a comma-separated version string is produced.
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <annotation>
+ <appinfo>
+ <meta.section type="since"/>
+ </appinfo>
+ <documentation>
+ 1.2.1
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appinfo>
+ <meta.section type="examples"/>
+ </appinfo>
+ <documentation>
+ &lt;p&gt;&lt;strong&gt;Namespace URI Matching&lt;/strong&gt;&lt;/p&gt;
+&lt;pre class=&quot;Example&quot;&gt;
+&lt;span class=&quot;code SchemaTag&quot;&gt;&amp;lt;extension point=&lt;/span&gt;&lt;span class=&quot;code SchemaCstring&quot;&gt;&quot;org.eclipse.papyrus.uml.modelrepair.profileNamespaceURIPattern&quot;&lt;/span&gt;&lt;span class=&quot;code SchemaTag&quot;&gt;&amp;gt;&lt;/span&gt;
+ &lt;span class=&quot;code SchemaTag&quot;&gt;&amp;lt;profileNamespaceURIPattern&lt;/span&gt; &lt;span class=&quot;code SchemaTag&quot;&gt;uriPattern=&lt;/span&gt;&lt;span class=&quot;code SchemaCstring&quot;&gt;&quot;^http://www\.eclipse\.org/my/profile/version/([^/]+)/Language/([^/]+)/.*$&quot;&lt;/span&gt; &lt;span class=&quot;code SchemaTag&quot;&gt;/&amp;gt;&lt;/span&gt;
+&lt;span class=&quot;code SchemaTag&quot;&gt;&amp;lt;/extension&amp;gt;&lt;/span&gt;
+&lt;/pre&gt;
+
+&lt;p&gt;Input URI A: http://www.eclipse.org/my/profile/version/7/Language/7.0.1/PackageA&lt;/p&gt;
+&lt;ul&gt;
+ &lt;li&gt;Matched Namespace URI: &quot;http://www.eclipse.org/my/profile/version/7/Language/7.0.1/PackageA&quot;&lt;/li&gt;
+ &lt;li&gt;Versionless Namespace URI: &quot;http://www.eclipse.org/my/profile/version//Language//PackageA&quot;&lt;/li&gt;
+ &lt;li&gt;Version: &quot;7,7.0.1&quot; (default format)&lt;/li&gt;
+&lt;/ul&gt;
+
+&lt;p&gt;Input URI B: http://www.eclipse.org/my/profile/version/7/Language/7.0.1/PackageB&lt;/p&gt;
+&lt;ul&gt;
+ &lt;li&gt;Matched Namespace URI: &quot;http://www.eclipse.org/my/profile/version/7/Language/7.0.1/PackageA&quot;&lt;/li&gt;
+ &lt;li&gt;Versionless Namespace URI: &quot;http://www.eclipse.org/my/profile/version//Language//PackageB&quot;&lt;/li&gt;
+ &lt;li&gt;Version: &quot;7,7.0.1&quot; (default format)&lt;/li&gt;
+&lt;/ul&gt;
+
+&lt;p&gt;Input URI C: http://www.eclipse.org/my/profile/version/6/Language/6.0/PackageB&lt;/p&gt;
+&lt;ul&gt;
+ &lt;li&gt;Matched Namespace URI: &quot;http://www.eclipse.org/my/profile/version/6/Language/6.0/PackageB&quot;&lt;/li&gt;
+ &lt;li&gt;Versionless Namespace URI: &quot;http://www.eclipse.org/my/profile/version//Language//PackageB&quot;&lt;/li&gt;
+ &lt;li&gt;Version: &quot;6,6.0&quot; (default format)&lt;/li&gt;
+&lt;/ul&gt;
+
+&lt;p&gt;During the migration, input B and C are treated as the same profile, just with a different version, whereas input A is considered as a different profile.&lt;/p&gt;
+
+&lt;p&gt;&lt;strong&gt;Version Formatting&lt;/strong&gt;&lt;/p&gt;
+&lt;pre class=&quot;Example&quot;&gt;
+&lt;span class=&quot;code SchemaTag&quot;&gt;&amp;lt;profileNamespaceURIPattern ... &lt;/span&gt;&lt;span class=&quot;code SchemaTag&quot;&gt;versionFormat=&lt;/span&gt;&lt;span class=&quot;code SchemaCstring&quot;&gt;&quot;-{1}-&quot;&lt;/span&gt;&lt;span class=&quot;code SchemaTag&quot;&gt;/&amp;gt;&lt;/span&gt;
+&lt;/pre&gt;
+
+&lt;p&gt;Input URI A: http://www.eclipse.org/my/profile/version/7/Language/PackageA&lt;/p&gt;
+&lt;ul&gt;
+ &lt;li&gt;Version: &quot;-7-&quot;&lt;/li&gt;
+&lt;/ul&gt;
+
+&lt;pre class=&quot;Example&quot;&gt;
+&lt;span class=&quot;code SchemaTag&quot;&gt;&amp;lt;profileNamespaceURIPattern ... &lt;/span&gt;&lt;span class=&quot;code SchemaTag&quot;&gt;versionFormat=&lt;/span&gt;&lt;span class=&quot;code SchemaCstring&quot;&gt;&quot;{1} - {2}&quot;&lt;/span&gt;&lt;span class=&quot;code SchemaTag&quot;&gt;/&amp;gt;&lt;/span&gt;
+&lt;/pre&gt;
+
+&lt;p&gt;Input URI A: http://www.eclipse.org/my/profile/version/7/Language/7.0.1/PackageA&lt;/p&gt;
+&lt;ul&gt;
+ &lt;li&gt;Version: &quot;7 - 7.0.1&quot;&lt;/li&gt;
+&lt;/ul&gt;
+
+&lt;pre class=&quot;Example&quot;&gt;
+&lt;span class=&quot;code SchemaTag&quot;&gt;&amp;lt;profileNamespaceURIPattern ... &lt;/span&gt;&lt;span class=&quot;code SchemaTag&quot;&gt;versionFormat=&lt;/span&gt;&lt;span class=&quot;code SchemaCstring&quot;&gt;&quot;{0} | {1}&quot;&lt;/span&gt;&lt;span class=&quot;code SchemaTag&quot;&gt;/&amp;gt;&lt;/span&gt;
+&lt;/pre&gt;
+
+&lt;p&gt;Input URI A: http://www.eclipse.org/my/profile/version/7/Language/7.0.1/PackageA&lt;/p&gt;
+&lt;ul&gt;
+ &lt;li&gt;Version: &quot;http://www.eclipse.org/my/profile/version/7/Language/7.0.1/PackageA | 7&quot;&lt;/li&gt;
+&lt;/ul&gt;
+
+&lt;p&gt;Special index zero conforms to group zero of the pattern match, which is the entire matched namespace URI.&lt;/p&gt;
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appinfo>
+ <meta.section type="apiinfo"/>
+ </appinfo>
+ <documentation>
+ An internal registry (ProfileNamespaceURIPatternRegistry) is used to control the registering and unregistering of the profile namespace URI patterns.
+This registry is initialized with all extension points, but a programatical removal of provided patterns is possible.
+ </documentation>
+ </annotation>
+
+
+ <annotation>
+ <appinfo>
+ <meta.section type="copyright"/>
+ </appinfo>
+ <documentation>
+ Copyright (c) 2016 EclipseSource and others.
+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
+ </documentation>
+ </annotation>
+
+</schema>
diff --git a/plugins/uml/org.eclipse.papyrus.uml.modelrepair/src/org/eclipse/papyrus/uml/modelrepair/internal/stereotypes/ZombieStereotypesDescriptor.java b/plugins/uml/org.eclipse.papyrus.uml.modelrepair/src/org/eclipse/papyrus/uml/modelrepair/internal/stereotypes/ZombieStereotypesDescriptor.java
index 1cc14a00c2c..fd764104127 100644
--- a/plugins/uml/org.eclipse.papyrus.uml.modelrepair/src/org/eclipse/papyrus/uml/modelrepair/internal/stereotypes/ZombieStereotypesDescriptor.java
+++ b/plugins/uml/org.eclipse.papyrus.uml.modelrepair/src/org/eclipse/papyrus/uml/modelrepair/internal/stereotypes/ZombieStereotypesDescriptor.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2015 CEA, Christian W. Damus, and others.
+ * Copyright (c) 2014, 2016 CEA, Christian W. Damus, and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
@@ -9,8 +9,9 @@
* Contributors:
* Christian W. Damus (CEA) - Initial API and implementation
* Christian W. Damus - bug 399859
- * Christian W. Damus - bug 451338
+ * Christian W. Damus - bug 451338
* Christian W. Damus - bug 436666
+ * Martin Fleck - bug 496307
*
*/
package org.eclipse.papyrus.uml.modelrepair.internal.stereotypes;
@@ -41,6 +42,8 @@ import org.eclipse.emf.ecore.util.FeatureMapUtil;
import org.eclipse.papyrus.infra.core.utils.AdapterUtils;
import org.eclipse.papyrus.infra.services.labelprovider.service.LabelProviderService;
import org.eclipse.papyrus.uml.modelrepair.internal.participants.StereotypesUtil;
+import org.eclipse.papyrus.uml.modelrepair.internal.uripattern.ProfileNamespaceURIPatternComparison;
+import org.eclipse.papyrus.uml.modelrepair.internal.uripattern.ProfileNamespaceURIPatternRegistry;
import org.eclipse.papyrus.uml.tools.helper.IProfileApplicationDelegate;
import org.eclipse.papyrus.uml.tools.helper.ProfileApplicationDelegateRegistry;
import org.eclipse.uml2.uml.Element;
@@ -53,6 +56,7 @@ import org.eclipse.uml2.uml.util.UMLUtil;
import com.google.common.base.Function;
import com.google.common.base.Objects;
+import com.google.common.base.Optional;
import com.google.common.base.Predicate;
import com.google.common.base.Supplier;
import com.google.common.base.Suppliers;
@@ -178,7 +182,7 @@ public class ZombieStereotypesDescriptor {
* <li>adapts to {@link EPackage} to provide the EMF schema that is unresolved or otherwise broken</li>
* <li>may possibly adapt to {@link IStereotypeOrphanGroup} representing stereotype applications from a broken schema that are not repairable by profile migration and so are treated separately with a distinct set of available actions
* </ul>
- *
+ *
* @return the zombie schemas that are detected
*/
public Collection<? extends IAdaptable> getZombieSchemas() {
@@ -308,7 +312,7 @@ public class ZombieStereotypesDescriptor {
/**
* Obtains a repair action of the specified {@code kind} for a broken {@code schema}, if it is available.
- *
+ *
* @param schema
* a schema to repair
* @param kind
@@ -454,9 +458,20 @@ public class ZombieStereotypesDescriptor {
result = schema1 == schema2;
if (!result && (schema1 != null)) { // Implies that schema2 != null, also
- result = Objects.equal(schema1.getNsURI(), schema2.getNsURI());
+ String schema1uri = schema1.getNsURI();
+ String schema2uri = schema2.getNsURI();
+ result = Objects.equal(schema1uri, schema2uri);
if (!result) {
+ // No perfect equality, try to use provided profile package patterns
+
+ // Try to find find a pattern comparison that matches both URIs
+ Optional<ProfileNamespaceURIPatternComparison> comparison = ProfileNamespaceURIPatternRegistry.INSTANCE.tryFindComparison(schema1uri, schema2uri);
+ if (comparison.isPresent()) {
+ return comparison.get().isEqualVersionlessNamespaceURI();
+ }
+
+ // No pattern found that handles the URIs
// Maybe one is a proxy whose URI is the schema-location of the other (being a demand-created package)
URI uri1 = guessURI(schema1);
URI uri2 = guessURI(schema2);
@@ -479,6 +494,7 @@ public class ZombieStereotypesDescriptor {
}
return result;
+
}
static URI guessURI(EPackage schema) {
diff --git a/plugins/uml/org.eclipse.papyrus.uml.modelrepair/src/org/eclipse/papyrus/uml/modelrepair/internal/uripattern/ProfileNamespaceURIPattern.java b/plugins/uml/org.eclipse.papyrus.uml.modelrepair/src/org/eclipse/papyrus/uml/modelrepair/internal/uripattern/ProfileNamespaceURIPattern.java
new file mode 100644
index 00000000000..4805e64d123
--- /dev/null
+++ b/plugins/uml/org.eclipse.papyrus.uml.modelrepair/src/org/eclipse/papyrus/uml/modelrepair/internal/uripattern/ProfileNamespaceURIPattern.java
@@ -0,0 +1,160 @@
+/*******************************************************************************
+ * Copyright (c) 2016 EclipseSource Services GmbH and others.
+ * 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:
+ * Martin Fleck - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.papyrus.uml.modelrepair.internal.uripattern;
+
+import java.text.MessageFormat;
+import java.util.regex.Pattern;
+
+/**
+ * A profile namespace URI pattern consists of a Regex pattern and an optional version format.
+ * The {@link Pattern} can split profile namespace URIs into versionless namespace URIs which can be used as identification and and the version part.
+ * The version format allows for individual formatting of the extracted version information and needs to conform to the {@link MessageFormat}.
+ *
+ * @author Martin Fleck <mfleck@eclipsesource.com>
+ */
+public class ProfileNamespaceURIPattern {
+
+ /** Regex pattern to split the URI into the profile-identifying part and the versioning part. */
+ private final Pattern pattern;
+
+ /** Message format to format the version parts extracted from the namespace URI */
+ private final MessageFormat versionFormat;
+
+ /**
+ * Creates a new profile namespace URI pattern with the given namespace URI pattern.
+ * The URI pattern is a Regex that can split namespace URIs into the profile-identifying part (without version) and the versioning part.
+ * This constructor uses the default versioning formatting producing a comma-separated version string.
+ *
+ * @param pattern
+ * pattern used to split the namespace URI
+ */
+ public ProfileNamespaceURIPattern(final String pattern) {
+ this(pattern, null);
+ }
+
+ /**
+ * Creates a new profile namespace URI pattern with the given namespace URI pattern and the provided version format.
+ * The URI pattern is a Regex that can split namespace URIs into the profile-identifying part (without version) and the versioning part.
+ * The version format allows for individual formatting of the extracted version information and needs to conform to the {@link MessageFormat}.
+ * Indices in the format correspond to the indices of the groups matched by the pattern, e.g., {0} refers to group zero holding the entire pattern and {1} refers to the first matched group.
+ *
+ * @param pattern
+ * Regex pattern
+ * @param versionFormat
+ * format for the versioning part of the matched namespace URI
+ * @see Pattern
+ * @see MessageFormat
+ */
+ public ProfileNamespaceURIPattern(final String pattern, final String versionFormat) {
+ this.pattern = Pattern.compile(pattern);
+ if (versionFormat != null) {
+ this.versionFormat = new MessageFormat(versionFormat);
+ } else {
+ this.versionFormat = null;
+ }
+ }
+
+ /**
+ * Returns the Regex pattern that can split namespace URIs into the profile-identifying part and the versioning part.
+ *
+ * @return the Regex pattern
+ */
+ public Pattern getRegexPattern() {
+ return pattern;
+ }
+
+ /**
+ * Returns the format that is used to create the {@link ProfileNamespaceURIPatternMatchResult#getVersion() version} string from the groups
+ * of the {@link #getRegexPattern() namespace URI pattern}. If no such format was given, this method returns null.
+ *
+ * @return the versionFormat or null if no such format was given
+ */
+ public MessageFormat getVersionFormat() {
+ return versionFormat;
+ }
+
+
+ /**
+ * Compares the two given URIs based on how they {@link ProfileNamespaceURIPatternMatchResult match} this pattern.
+ * Only if both URIs match the pattern, a {@link ProfileNamespaceURIPatternComparison#isValid() valid} comparison result is returned.
+ *
+ * @param lhsUri
+ * left-hand side URI for the comparison
+ * @param rhsUri
+ * right-hand side URI for the comparison
+ * @return a non-null comparison result, which may or may not be valid
+ */
+ public ProfileNamespaceURIPatternComparison compare(final String lhsUri, final String rhsUri) {
+ final ProfileNamespaceURIPatternMatchResult lhsPattern = match(lhsUri);
+ if (lhsPattern.hasMatched()) {
+ final ProfileNamespaceURIPatternMatchResult rhsPattern = match(rhsUri);
+ if (rhsPattern.hasMatched()) {
+ // both uris match
+ return new ProfileNamespaceURIPatternComparison(lhsPattern, rhsPattern);
+ }
+ }
+ // none or only one uri matches
+ return ProfileNamespaceURIPatternComparison.INVALID;
+ }
+
+ /**
+ * Matches the given uri with this namespace URI pattern.
+ *
+ * @param uri
+ * uri to match
+ * @return a non-null match result, which may or may not {@link ProfileNamespaceURIPatternMatchResult#hasMatched() have matched}.
+ */
+ public ProfileNamespaceURIPatternMatchResult match(final String uri) {
+ if (uri == null) {
+ return ProfileNamespaceURIPatternMatchResult.NO_MATCH;
+ }
+ return new ProfileNamespaceURIPatternMatchResult(pattern.matcher(uri), versionFormat);
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((pattern == null) ? 0 : pattern.pattern().hashCode());
+ result = prime * result + ((versionFormat == null) ? 0 : versionFormat.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ ProfileNamespaceURIPattern other = (ProfileNamespaceURIPattern) obj;
+ if (pattern == null) {
+ if (other.pattern != null) {
+ return false;
+ }
+ } else if (!pattern.pattern().equals(other.pattern.pattern())) {
+ return false;
+ }
+ if (versionFormat == null) {
+ if (other.versionFormat != null) {
+ return false;
+ }
+ } else if (!versionFormat.equals(other.versionFormat)) {
+ return false;
+ }
+ return true;
+ }
+}
+
diff --git a/plugins/uml/org.eclipse.papyrus.uml.modelrepair/src/org/eclipse/papyrus/uml/modelrepair/internal/uripattern/ProfileNamespaceURIPatternComparison.java b/plugins/uml/org.eclipse.papyrus.uml.modelrepair/src/org/eclipse/papyrus/uml/modelrepair/internal/uripattern/ProfileNamespaceURIPatternComparison.java
new file mode 100644
index 00000000000..b7531a30553
--- /dev/null
+++ b/plugins/uml/org.eclipse.papyrus.uml.modelrepair/src/org/eclipse/papyrus/uml/modelrepair/internal/uripattern/ProfileNamespaceURIPatternComparison.java
@@ -0,0 +1,116 @@
+/*******************************************************************************
+ * Copyright (c) 2016 EclipseSource Services GmbH and others.
+ * 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:
+ * Martin Fleck - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.papyrus.uml.modelrepair.internal.uripattern;
+
+/**
+ * This convenience class providing comparison methods for two {@link ProfileNamespaceURIPatternMatchResult}es.
+ *
+ * @author Martin Fleck <mfleck@eclipsesource.com>
+ */
+public class ProfileNamespaceURIPatternComparison {
+
+ /** Constant representing an invalid comparison */
+ public static final ProfileNamespaceURIPatternComparison INVALID = new ProfileNamespaceURIPatternComparison(
+ ProfileNamespaceURIPatternMatchResult.NO_MATCH, ProfileNamespaceURIPatternMatchResult.NO_MATCH);
+
+ /** Left-hand side pattern match of the comparison */
+ private final ProfileNamespaceURIPatternMatchResult lhsPatternMatch;
+
+ /** Right-hand side pattern match of the comparison */
+ private final ProfileNamespaceURIPatternMatchResult rhsPatternMatch;
+
+ /**
+ * Creates a new comparison based on the given two matches.
+ * The resulting comparison is only valid if both matches have actually matched.
+ * All comparisons on an invalid comparison yield false as return value.
+ *
+ * @param lhsPatternMatch
+ * first match
+ * @param rhsPatternMatch
+ * second match
+ * @see ProfileNamespaceURIPattern
+ * @see ProfileNamespaceURIPatternRegistry
+ */
+ public ProfileNamespaceURIPatternComparison(final ProfileNamespaceURIPatternMatchResult lhsPatternMatch,
+ final ProfileNamespaceURIPatternMatchResult rhsPatternMatch) {
+ this.lhsPatternMatch = lhsPatternMatch;
+ this.rhsPatternMatch = rhsPatternMatch;
+ }
+
+ /**
+ * Left-hand side pattern match given when constructing this comparison.
+ *
+ * @return left-hand side pattern match
+ */
+ public ProfileNamespaceURIPatternMatchResult getLHSPatternMatch() {
+ return lhsPatternMatch;
+ }
+
+ /**
+ * Right-hand side pattern match given when constructing this comparison.
+ *
+ * @return second pattern match
+ */
+ public ProfileNamespaceURIPatternMatchResult getRHSPatternMatch() {
+ return rhsPatternMatch;
+ }
+
+ /**
+ * This comparison is valid if both pattern matches have matched.
+ *
+ * @return true if both pattern matches are valid, false otherwise
+ */
+ public boolean isValid() {
+ return getLHSPatternMatch() != null && getRHSPatternMatch() != null
+ && getLHSPatternMatch().hasMatched() && getRHSPatternMatch().hasMatched();
+ }
+
+ /**
+ * Returns true if both pattern matches have the same {@link ProfileNamespaceURIPatternMatchResult#getVersion() version string}.
+ * If this comparison is invalid, then this method returns false.
+ *
+ * @return true if both pattern matches refer to the same version, false otherwise or if this comparison is invalid
+ */
+ public boolean isEqualVersion() {
+ return isValid()
+ && getLHSPatternMatch().getVersion().equals(getRHSPatternMatch().getVersion());
+ }
+
+ /**
+ * Returns true if both pattern matches have the same {@link ProfileNamespaceURIPatternMatchResult#getVersionlessNamespaceURI() versionless namespace URI}.
+ * If this comparison is invalid, then this method returns false.
+ *
+ * @return true if both pattern matches refer to the same versionless namespace URI, false otherwise or if this comparison is invalid
+ */
+ public boolean isEqualVersionlessNamespaceURI() {
+ return isValid()
+ && getLHSPatternMatch().getVersionlessNamespaceURI().equals(getRHSPatternMatch().getVersionlessNamespaceURI());
+ }
+
+ /**
+ * Returns true if both pattern matches have the same {@link ProfileNamespaceURIPatternMatchResult#getNamespaceURI() namespace URI}.
+ * If this comparison is invalid, then this method returns false.
+ *
+ * @return true if both pattern matches refer to the same namespace URI, false otherwise or if this comparison is invalid
+ */
+ public boolean isEqualNamespaceURI() {
+ return isValid()
+ && getLHSPatternMatch().getNamespaceURI().equals(getRHSPatternMatch().getNamespaceURI());
+ }
+
+ @Override
+ public String toString() {
+ if (!isValid()) {
+ return "Invalid comparison.";
+ }
+ return getLHSPatternMatch() + " versus " + getRHSPatternMatch();
+ }
+}
diff --git a/plugins/uml/org.eclipse.papyrus.uml.modelrepair/src/org/eclipse/papyrus/uml/modelrepair/internal/uripattern/ProfileNamespaceURIPatternMatchResult.java b/plugins/uml/org.eclipse.papyrus.uml.modelrepair/src/org/eclipse/papyrus/uml/modelrepair/internal/uripattern/ProfileNamespaceURIPatternMatchResult.java
new file mode 100644
index 00000000000..7238931d98b
--- /dev/null
+++ b/plugins/uml/org.eclipse.papyrus.uml.modelrepair/src/org/eclipse/papyrus/uml/modelrepair/internal/uripattern/ProfileNamespaceURIPatternMatchResult.java
@@ -0,0 +1,231 @@
+/*******************************************************************************
+ * Copyright (c) 2016 EclipseSource Services GmbH and others.
+ * 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:
+ * Martin Fleck - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.papyrus.uml.modelrepair.internal.uripattern;
+
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.regex.MatchResult;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * This class evaluates a {@link Pattern#matches(String, CharSequence) pattern match} with regards to a {@link ProfileNamespaceURIPattern}
+ * and provides convenience methods to access the profile-identifying part (without version) and versioning part of the matched URI.
+ *
+ * @author Martin Fleck <mfleck@eclipsesource.com>
+ */
+public class ProfileNamespaceURIPatternMatchResult {
+
+ /** Constant representing an unsuccessful match */
+ public static final ProfileNamespaceURIPatternMatchResult NO_MATCH = new ProfileNamespaceURIPatternMatchResult(null, null);
+
+ /** Result from the matching process, null if the matching was not successful */
+ private MatchResult regexMatchResult;
+
+ /** Format used to format the versioning part of the matched URI */
+ private MessageFormat versionFormat;
+
+ /** Cached strings for all group parts in the match */
+ private String[] groups;
+
+ /** Cached strings for all non-group parts in the match */
+ private String[] nonGroups;
+
+ /** The entire matched namespace URI */
+ private String namespaceURI;
+
+ /** The profile-identifying, versionless part of the match, i.e., a concatenation of the non-group parts in the match */
+ private String versionlessNamespaceURI;
+
+ /** The formatted versioning string of the match based on the given message format and the matched groups */
+ private String version;
+
+ /**
+ * Creates a new match result based on the given matcher.
+ * If the matcher does not match the {@link Matcher#matches() entire string}, then this match result is considered {@link #hasMatched() unsuccessful}
+ * and all methods querying the result will return null.
+ *
+ * @param matcher
+ * match engine
+ * @see ProfileNamespaceURIPattern
+ * @see ProfileNamespaceURIPatternRegistry
+ */
+ public ProfileNamespaceURIPatternMatchResult(final Matcher matcher) {
+ this(matcher, null);
+ }
+
+ /**
+ * Creates a new match based on the given matcher and the provided format for the versioning part of the match.
+ * If the matcher does not match the {@link Matcher#matches() entire string}, then this match result is considered {@link #hasMatched() unsuccessful}
+ * and all methods querying the result will return null.
+ * The version format allows for individual formatting of the extracted version information and needs to conform to the {@link MessageFormat}.
+ * Indices in the format correspond to the indices of the groups matched by the pattern, e.g., {0} refers to group zero holding the entire pattern and {1} refers to the first matched group.
+ * The version format will only be used if the match is successful and is used to produce the {@link #getVersion() version string} of the matched URI.
+ *
+ * @param matcher
+ * match engine
+ * @param versionFormat
+ * format for the versioning part of the matched namespace URI
+ * @see ProfileNamespaceURIPattern
+ * @see ProfileNamespaceURIPatternRegistry
+ */
+ public ProfileNamespaceURIPatternMatchResult(final Matcher matcher, final MessageFormat versionFormat) {
+ if (matcher != null && matcher.matches()) {
+ this.regexMatchResult = matcher.toMatchResult();
+ this.versionFormat = versionFormat;
+ }
+ }
+
+ /**
+ * Returns the format used to produce the {@link #getVersion() version string} from all version parts extracted from the matched URI.
+ * Indices in the format correspond to the indices of the groups matched by the pattern, e.g., {0} refers to group zero holding the entire pattern and {1} refers to the first matched group.
+ *
+ * @return the versionFormat
+ */
+ public MessageFormat getVersionFormat() {
+ return versionFormat;
+ }
+
+ /**
+ * Returns true if a successful match could be produced for the given URI considering the underlying pattern, false otherwise.
+ * If no successful match could be produced, all methods querying the result will return null.
+ *
+ * @return true if the match was successful, false otherwise.
+ */
+ public boolean hasMatched() {
+ return getRegexMatchResult() != null;
+ }
+
+ /**
+ * Returns the entire matched namespace URI. If the pattern did not match, null is returned.
+ *
+ * @return matched namespace URI or null
+ */
+ public String getNamespaceURI() {
+ if (!hasMatched()) {
+ return null;
+ }
+ if (namespaceURI == null) {
+ namespaceURI = getRegexMatchResult().group(0);
+ }
+ return namespaceURI;
+ }
+
+ /**
+ * Returns the versionless namespace URI of the matched URI or null the underlying pattern was not matched.
+ * The versionless namespace URI may be used to identify a profile, independent of its version.
+ *
+ * @return profile-identifying, versionless namespace URI or null if there is no match
+ */
+ public String getVersionlessNamespaceURI() {
+ if (!hasMatched()) {
+ return null;
+ }
+ if (versionlessNamespaceURI == null) {
+ versionlessNamespaceURI = String.join("", getNonGroups());
+ }
+ return versionlessNamespaceURI;
+ }
+
+ /**
+ * Returns the version of the matched namespace URI or null if the underlying pattern was not matched.
+ * The version string is formatted using the {@link #getVersionFormat() version format} provided when constructing this result.
+ * If no format was provided, the version parts get concatenated via comma.
+ *
+ * @return version string of the matched namespace URI or null if there is no match
+ */
+ public String getVersion() {
+ if (!hasMatched()) {
+ return null;
+ }
+ if (version == null) {
+ if (versionFormat != null) {
+ version = versionFormat.format(getGroups());
+ } else {
+ // by default just concatenate version parts via comma without the entire match (group 0)
+ version = String.join(",", Arrays.copyOfRange(getGroups(), 1, getGroups().length));
+ }
+ }
+ return version;
+ }
+
+ /**
+ * Returns the Regex match result produced from the matcher given in the constructor.
+ * If there was no match, the match result is null.
+ *
+ * @return match result or null if there is no match
+ */
+ protected MatchResult getRegexMatchResult() {
+ return regexMatchResult;
+ }
+
+ /**
+ * Returns all group strings of the underlying match result. If no match result is present, null is returned.
+ * The indices of the groups match the indices of the returned array.
+ * Please note that group zero (at index zero) holds the entire matched pattern.
+ *
+ * @return group strings or null
+ */
+ protected String[] getGroups() {
+ if (!hasMatched()) {
+ return null;
+ }
+ if (groups == null) {
+ final int groupCount = getRegexMatchResult().groupCount();
+ // group 0 has complete match and is not included in group count
+ groups = new String[groupCount + 1];
+ for (int i = 0; i <= groupCount; i++) {
+ groups[i] = getRegexMatchResult().group(i);
+ }
+ }
+ return groups;
+ }
+
+ /**
+ * Returns all non-group strings of the underlying match result.
+ * If no match result is present, null is returned.
+ *
+ * @return non-group strings or null
+ */
+ protected String[] getNonGroups() {
+ if (!hasMatched()) {
+ return null;
+ }
+ if (nonGroups == null) {
+ final int groupCount = getRegexMatchResult().groupCount();
+ final ArrayList<String> nonGroupList = new ArrayList<String>();
+ String nonGroup;
+ int start = getRegexMatchResult().start();
+ for (int i = 1; i <= groupCount; i++) {
+ nonGroup = getNamespaceURI().substring(start, getRegexMatchResult().start(i));
+ if (!nonGroup.isEmpty()) {
+ nonGroupList.add(nonGroup);
+ }
+ start = getRegexMatchResult().end(i);
+ }
+ nonGroup = getNamespaceURI().substring(start, getRegexMatchResult().end());
+ if (!nonGroup.isEmpty()) {
+ nonGroupList.add(nonGroup);
+ }
+ nonGroups = nonGroupList.toArray(new String[nonGroupList.size()]);
+ }
+ return nonGroups;
+ }
+
+ @Override
+ public String toString() {
+ if (!hasMatched()) {
+ return "No match.";
+ }
+ return getVersionlessNamespaceURI() + " [" + getVersion() + "]";
+ }
+}
diff --git a/plugins/uml/org.eclipse.papyrus.uml.modelrepair/src/org/eclipse/papyrus/uml/modelrepair/internal/uripattern/ProfileNamespaceURIPatternRegistry.java b/plugins/uml/org.eclipse.papyrus.uml.modelrepair/src/org/eclipse/papyrus/uml/modelrepair/internal/uripattern/ProfileNamespaceURIPatternRegistry.java
new file mode 100644
index 00000000000..d044c04b762
--- /dev/null
+++ b/plugins/uml/org.eclipse.papyrus.uml.modelrepair/src/org/eclipse/papyrus/uml/modelrepair/internal/uripattern/ProfileNamespaceURIPatternRegistry.java
@@ -0,0 +1,235 @@
+/*******************************************************************************
+ * Copyright (c) 2016 EclipseSource Services GmbH and others.
+ * 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:
+ * Martin Fleck - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.papyrus.uml.modelrepair.internal.uripattern;
+
+import static org.eclipse.papyrus.uml.modelrepair.Activator.PLUGIN_ID;
+import static org.eclipse.papyrus.uml.modelrepair.Activator.log;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.Platform;
+
+import com.google.common.base.Optional;
+import com.google.common.collect.Lists;
+
+/**
+ * This registry holds all profile namespace URI patterns that have been provided through the profile namespace
+ * URI pattern extension point or via the API of this registry.
+ *
+ * @author Martin Fleck <mfleck@eclipsesource.com>
+ */
+public class ProfileNamespaceURIPatternRegistry {
+
+ /** Singleton instance of this registry */
+ public static final ProfileNamespaceURIPatternRegistry INSTANCE = new ProfileNamespaceURIPatternRegistry();
+
+ /** ID under which extension points are registered */
+ private static final String EXTENSION_ID = PLUGIN_ID + ".profileNamespaceURIPattern"; //$NON-NLS-1$
+
+ /** Name of the profile namespace URI pattern configuration element */
+ private static final String NAME = "profileNamespaceURIPattern"; //$NON-NLS-1$
+
+ /** Attribute of the profile namespace URI pattern configuration element holding the URI pattern */
+ private static final String URI_PATTERN = "uriPattern"; //$NON-NLS-1$
+
+ /** Attribute of the profile namespace URI pattern configuration element holding the version format */
+ private static final String VERSION_FORMAT = "versionFormat"; //$NON-NLS-1$
+
+ /** List of registered profile namespace URI patterns */
+ private List<ProfileNamespaceURIPattern> profileNamespaceURIPatterns = new ArrayList<ProfileNamespaceURIPattern>();
+
+ /**
+ * Private constructor to avoid creation in favor of singleton instance.
+ */
+ private ProfileNamespaceURIPatternRegistry() {
+ initFromExtensionPoints();
+ }
+
+ /**
+ * Reads profile namespace URI patterns from the extension points and adds them to the list of patterns.
+ */
+ private void initFromExtensionPoints() {
+ final IConfigurationElement[] config = Platform.getExtensionRegistry().getConfigurationElementsFor(EXTENSION_ID);
+
+ // read data from plugins
+ for (IConfigurationElement element : config) {
+ try {
+ if (NAME.equals(element.getName())) {
+ ProfileNamespaceURIPattern pattern = processProfileNamespaceURIPattern(element);
+ register(pattern);
+ }
+ } catch (Exception ex) {
+ log.error(ex);
+ }
+ }
+ }
+
+ /**
+ * Reads the necessary data from the provided configuration element to create a new profile namespace URI pattern.
+ *
+ * @param element
+ * configuration element
+ * @return newly created profile namespace URI pattern
+ */
+ private ProfileNamespaceURIPattern processProfileNamespaceURIPattern(IConfigurationElement element) {
+ final String uriPattern = element.getAttribute(URI_PATTERN);
+ final String versionFormat = element.getAttribute(VERSION_FORMAT); // is optional, may return null
+ return new ProfileNamespaceURIPattern(uriPattern, versionFormat);
+ }
+
+ /**
+ * Returns an unmodifiable list of all registered profile namespace URI patterns.
+ *
+ * @return list of registered profile namespace URI patterns
+ */
+ public List<ProfileNamespaceURIPattern> getProfileNamespaceURIPatterns() {
+ return Collections.unmodifiableList(profileNamespaceURIPatterns);
+ }
+
+ /**
+ * Adds the provided profile namespace URI pattern to this registry.
+ *
+ * @param profileNamespaceURIPattern
+ * pattern to be registered
+ */
+ public void register(ProfileNamespaceURIPattern profileNamespaceURIPattern) {
+ profileNamespaceURIPatterns.add(profileNamespaceURIPattern);
+ }
+
+ /**
+ * Removes the given profile namespace URI patterns from this registry.
+ * If the pattern can not be found, the registry remains unchanged.
+ *
+ * @param profileNamespaceURIPattern
+ * pattern to be unregistered, if present
+ */
+ public void unregister(ProfileNamespaceURIPattern profileNamespaceURIPattern) {
+ profileNamespaceURIPatterns.remove(profileNamespaceURIPattern);
+ }
+
+ /**
+ * Returns an {@link Optional} containing the first pattern that matches the given uri,
+ * if such a pattern exists.
+ *
+ * @param namespaceURI
+ * namespace URI to be matched
+ * @return Optional containing the first matching pattern, if such a pattern exists
+ */
+ public Optional<ProfileNamespaceURIPattern> tryFindPattern(String namespaceURI) {
+ for (ProfileNamespaceURIPattern pattern : getProfileNamespaceURIPatterns()) {
+ ProfileNamespaceURIPatternMatchResult match = pattern.match(namespaceURI);
+ if (match.hasMatched()) {
+ return Optional.of(pattern);
+ }
+ }
+ return Optional.absent();
+ }
+
+ /**
+ * Returns a list of patterns that match the given namespace URI.
+ * If no such pattern exist, an empty list is returned.
+ *
+ * @param namespaceURI
+ * namespace URI to be matched
+ * @return list of matching patterns
+ */
+ public List<ProfileNamespaceURIPattern> findPatterns(String namespaceURI) {
+ List<ProfileNamespaceURIPattern> patterns = Lists.newArrayList();
+ for (ProfileNamespaceURIPattern pattern : getProfileNamespaceURIPatterns()) {
+ ProfileNamespaceURIPatternMatchResult match = pattern.match(namespaceURI);
+ if (match.hasMatched()) {
+ patterns.add(pattern);
+ }
+ }
+ return patterns;
+ }
+
+ /**
+ * Returns an {@link Optional} containing the first pattern match that matches the given namespace URI,
+ * if such a pattern match exists.
+ *
+ * @param namespaceURI
+ * namespace URI to be matched
+ * @return Optional containing the first matching pattern match, if such a pattern match exists
+ */
+ public Optional<ProfileNamespaceURIPatternMatchResult> tryFindMatch(String namespaceURI) {
+ for (ProfileNamespaceURIPattern pattern : getProfileNamespaceURIPatterns()) {
+ ProfileNamespaceURIPatternMatchResult match = pattern.match(namespaceURI);
+ if (match.hasMatched()) {
+ return Optional.of(match);
+ }
+ }
+ return Optional.absent();
+ }
+
+ /**
+ * Returns a list of pattern matches that match the given namespace URI.
+ * If no such pattern match exist, an empty list is returned.
+ *
+ * @param namespaceURI
+ * namespace URI to be matched
+ * @return list of matching pattern matches
+ */
+ public List<ProfileNamespaceURIPatternMatchResult> findMatches(String namespaceURI) {
+ List<ProfileNamespaceURIPatternMatchResult> matches = Lists.newArrayList();
+ for (ProfileNamespaceURIPattern pattern : getProfileNamespaceURIPatterns()) {
+ ProfileNamespaceURIPatternMatchResult match = pattern.match(namespaceURI);
+ if (match.hasMatched()) {
+ matches.add(match);
+ }
+ }
+ return matches;
+ }
+
+ /**
+ * Returns an {@link Optional} containing the first valid pattern comparison that matches both namespace URIs,
+ * if such a comparison exists.
+ *
+ * @param lhsNamespaceUri
+ * left-hand side namespace URI of the comparison
+ * @param rhsNamespaceUri
+ * right-hand side namespace URI of the comparison
+ * @return Optional containing the first valid pattern comparison, if such a comparison exists
+ */
+ public Optional<ProfileNamespaceURIPatternComparison> tryFindComparison(String lhsNamespaceUri, String rhsNamespaceUri) {
+ for (ProfileNamespaceURIPattern pattern : getProfileNamespaceURIPatterns()) {
+ ProfileNamespaceURIPatternComparison comparison = pattern.compare(lhsNamespaceUri, rhsNamespaceUri);
+ if (comparison.isValid()) {
+ return Optional.of(comparison);
+ }
+ }
+ return Optional.absent();
+ }
+
+ /**
+ * Returns a list of valid pattern comparisons that match both namespace URIs.
+ * If no such comparison exist, an empty list is returned.
+ *
+ * @param lhsNamespaceUri
+ * left-hand side namespace URI of the comparison
+ * @param rhsNamespaceUri
+ * right-hand side namespace URI of the comparison
+ * @return list of valid comparisons between the given namespace URIs
+ */
+ public List<ProfileNamespaceURIPatternComparison> findComparisons(String lhsNamespaceUri, String rhsNamespaceUri) {
+ List<ProfileNamespaceURIPatternComparison> comparisons = Lists.newArrayList();
+ for (ProfileNamespaceURIPattern pattern : getProfileNamespaceURIPatterns()) {
+ ProfileNamespaceURIPatternComparison comparison = pattern.compare(lhsNamespaceUri, rhsNamespaceUri);
+ if (comparison.isValid()) {
+ comparisons.add(comparison);
+ }
+ }
+ return comparisons;
+ }
+}

Back to the top