All Downloads are FREE. Search and download functionalities are using the official Maven repository.

cdc.mf.model.MfLocation Maven / Gradle / Ivy

The newest version!
package cdc.mf.model;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

import cdc.issues.locations.AbstractLocation;
import cdc.issues.locations.Location;
import cdc.issues.locations.Locations;
import cdc.util.lang.Checks;

/**
 * Implementation of {@link Location} dedicated to MF elements.
 * 

* It is equivalent to a list of {@link MfLocationPart MfLocationParts}.
* The full path is not encoded, just the necessary parts to reference an identified element * and give enough information to user. * */ public final class MfLocation extends AbstractLocation { public static final Pattern PATH_PATTERN = Pattern.compile("[A-Z]+@[^\\[]*\\[[^\\[\\]]*\\](/[A-Z]+@[^\\[]*\\[[^\\[\\]]*\\])*"); public static final char SEPARATOR = '/'; public static final String TAG = "MfLocation"; public static final String SEP = Character.toString(SEPARATOR); private static final Pattern ID_PATTERN = Pattern.compile("\\[[^\\[\\]]*\\]"); static { Locations.register(TAG, MfLocation::of); } private final String path; private final String anchor; private MfLocation(String path, String anchor) { this.path = Checks.isNotNullOrEmpty(path, "path"); this.anchor = anchor; // May be null Checks.isTrue(PATH_PATTERN.matcher(path).matches(), "Invalid path: '" + path + "'"); } private MfLocation(MfElement element, String anchor) { final List parts = element.getHierarchy() .stream() .map(MfElement::getLocationPart) .toList(); this.path = MfLocationPart.compress(parts, true) .stream() .map(Object::toString) .collect(Collectors.joining(SEP)); this.anchor = anchor; } public static void elaborate() { // Ignore } /** * @param element The element. * @param anchor The anchor * @return A new instance of MfLocation. */ public static MfLocation of(MfElement element, String anchor) { return new MfLocation(element, anchor); } /** * @param element The element. * @return A new instance of MfLocation. */ public static MfLocation of(MfElement element) { return new MfLocation(element, null); } /** * @param path The path. * @param anchor The anchor. * @return A new instance of MfLocation. */ public static MfLocation of(String path, String anchor) { return new MfLocation(path, anchor); } /** * @param path The path. * @return A new instance of MfLocation. */ public static MfLocation of(String path) { return of(path, null); } @Override public String getTag() { return TAG; } @Override public String getPath() { return path; } @Override public String getAnchor() { return anchor; } /** * @return The location parts encoded in the path. */ public List getParts() { final List tmp = new ArrayList<>(); final Matcher m = ID_PATTERN.matcher(path); int from = 0; while (from < path.length()) { final boolean found = m.find(from); if (found) { final int to = m.end(); final MfLocationPart next = MfLocationPart.of(path.substring(from, to)); tmp.add(next); // Possibly skip '/' if (to < path.length()) { Checks.assertTrue(path.charAt(to) == SEPARATOR, "Expected " + SEPARATOR + " at " + to + " in '" + path + "'"); } from = to + 1; } else { final MfLocationPart next = MfLocationPart.of(path.substring(from)); tmp.add(next); from = path.length(); } } return tmp; } /** * Returns the element corresponding to this location in a model. *

* It is the caller responsibility to make sure that the location and model are consistent. * * @param model The model. * @return The element corresponding to this location in {@code model}. */ public Optional resolve(MfModel model) { final List parts = getParts(); // Index of the last part that has a valid id int lastValidId = parts.size() - 1; while (lastValidId >= 0 && !parts.get(lastValidId).hasValidId()) { lastValidId--; } if (lastValidId >= 0) { final String id = parts.get(lastValidId).getId(); return model.getItemWithId(id); } else { return Optional.empty(); } } @Override public int hashCode() { return super.hashCode(); } @Override public boolean equals(Object object) { return super.equals(object); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy