Skip to content

Commit

Permalink
io module: improve references management and tests
Browse files Browse the repository at this point in the history
  • Loading branch information
yvrng committed Jun 9, 2017
1 parent 00637c3 commit c01de65
Show file tree
Hide file tree
Showing 11 changed files with 2,210 additions and 20,785 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@
import org.eclipse.emf.ecore.EStructuralFeature;

import java.util.ArrayDeque;
import java.util.Arrays;
import java.util.Deque;
import java.util.concurrent.atomic.AtomicInteger;

import javax.annotation.Nonnull;
import javax.annotation.ParametersAreNonnullByDefault;
Expand Down Expand Up @@ -112,15 +114,29 @@ public void onReference(BasicReference reference) {
// Checks that the reference is well a reference
if (EReference.class.isInstance(feature)) {
EReference eReference = EReference.class.cast(feature);
reference.isContainment(eReference.isContainment());
reference.isMany(eReference.isMany());

EClass referenceType = eReference.getEReferenceType();
reference.metaclassReference(new BasicMetaclass(
BasicNamespace.Registry.getInstance().getFromUri(referenceType.getEPackage().getNsURI()),
referenceType.getName()));
AtomicInteger index = new AtomicInteger();

notifyReference(reference);
Arrays.stream(reference.idReference().value().split(" "))
.map(String::trim)
.filter(s -> !s.isEmpty())
.map(s -> {
BasicReference newReference = new BasicReference(reference.name());
newReference.id(reference.id());

newReference.index(eReference.isMany() && !eReference.isContainment() ? index.getAndIncrement() : -1);
newReference.idReference(BasicId.original(s));
newReference.isContainment(eReference.isContainment());
newReference.isMany(eReference.isMany());

EClass referenceType = eReference.getEReferenceType();
newReference.metaclassReference(new BasicMetaclass(
BasicNamespace.Registry.getInstance().getFromUri(referenceType.getEPackage().getNsURI()),
referenceType.getName()));

return newReference;
})
.forEach(this::notifyReference);
}

// Otherwise redirect to the attribute handler
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,12 @@
import fr.inria.atlanmod.neoemf.util.log.Log;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
Expand All @@ -46,26 +44,12 @@
@ParametersAreNonnullByDefault
public abstract class AbstractXmiStreamReader extends AbstractStreamReader {

/**
* Regular expression of an attribute containing one or several references.
*/
@RegEx
private static final String REGEX_REFERENCE = "(/{1,2}@\\w+(\\.\\d+)?[ ]?)+";

/**
* Regular expression of a prefixed value.
*/
@RegEx
private static final String REGEX_PREFIXED_VALUE = "(\\w+):(\\w+)";

/**
* Pattern of an attribute containing one or several references (XPath reference). Multiple references must be
* separated by a space.
* <p>
* Example of recognized strings : {@code "//@&lt;name1&gt;.&lt;index1&gt;/@&lt;name2&gt;"}
*/
private static final Pattern PATTERN_REFERENCE = Pattern.compile(REGEX_REFERENCE, Pattern.UNICODE_CASE);

/**
* Pattern of a prefixed value.
* <p>
Expand Down Expand Up @@ -192,27 +176,12 @@ protected void readEndElement() {
* @return a list of {@link BasicFeature} that can be empty.
*
* @see #processAttributes(String, String)
* @see #processReferences(String, Iterable)
*/
@Nonnull
private List<BasicFeature> processFeatures(@Nullable String prefix, String name, String value) {
List<BasicFeature> features;

if (!processSpecialFeature(prefix, name, value)) {
List<String> references = parseReference(value);

if (!references.isEmpty()) {
features = processReferences(name, references);
}
else {
features = processAttributes(name, value);
}
}
else {
features = Collections.emptyList();
}

return features;
return !processSpecialFeature(prefix, name, value)
? processAttributes(name, value)
: Collections.emptyList();
}

/**
Expand Down Expand Up @@ -264,43 +233,6 @@ else if (Objects.equals(XmiConstants.NAME, name)) {
return isSpecialFeature;
}

/**
* Returns a list of {@link String} representing XPath references, or {@code null} if the {@code value} does not
* match with {@link #PATTERN_REFERENCE}.
*
* @param value the value to parse
*
* @return a list of {@link String} representing XPath references, or {@code null} if the {@code value} does not
* match with {@link #PATTERN_REFERENCE}
*
* @see #PATTERN_REFERENCE
*/
@Nonnull
private List<String> parseReference(String value) {
List<String> references;

if (!value.trim().isEmpty()) {
references = Arrays.stream(value.split(" "))
.map(String::trim)
.filter(s -> !s.isEmpty())
.collect(Collectors.toList());

boolean isReference = true;
for (int i = 0; i < references.size() && isReference; i++) {
isReference = PATTERN_REFERENCE.matcher(references.get(i)).matches();
}

if (!isReference) {
references = Collections.emptyList();
}
}
else {
references = Collections.emptyList();
}

return references;
}

/**
* Processes an attribute.
*
Expand All @@ -322,31 +254,6 @@ private List<BasicFeature> processAttributes(String name, String value) {
return features;
}

/**
* Processes a list of {@code references} and returns a list of {@link BasicReference}.
*
* @param name the name of the reference
* @param references the list that holds the identifier of referenced elements
*
* @return a list of {@link BasicReference} from the given {@code references}
*/
@Nonnull
private List<BasicFeature> processReferences(String name, Iterable<String> references) {
List<BasicFeature> features = new ArrayList<>();

int index = 0;
for (String rawReference : references) {
BasicReference ref = new BasicReference(name);
ref.index(index);
ref.idReference(BasicId.generated(rawReference));

features.add(ref);
index++;
}

return features;
}

/**
* Processes a metaclass attribute from the {@code prefixedValue}, and defines is as the metaclass of the given
* {@code element}.
Expand Down
Loading

0 comments on commit c01de65

Please sign in to comment.