Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/uml')
-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