/** * <copyright> * </copyright> * * $Id$ */ package org.eclipse.buckminster.model.common.impl; import java.util.List; import java.util.regex.PatternSyntaxException; import org.eclipse.buckminster.model.common.CommonPackage; import org.eclipse.buckminster.model.common.RxPart; import org.eclipse.buckminster.model.common.RxPattern; import org.eclipse.emf.common.notify.Notification; import org.eclipse.emf.ecore.EClass; import org.eclipse.emf.ecore.impl.ENotificationImpl; /** * <!-- begin-user-doc --> An implementation of the model object ' * <em><b>Rx Pattern</b></em>'. <!-- end-user-doc --> * <p> * The following features are implemented: * <ul> * <li> * {@link org.eclipse.buckminster.model.common.impl.RxPatternImpl#getPattern * <em>Pattern</em>}</li> * <li>{@link org.eclipse.buckminster.model.common.impl.RxPatternImpl#getPrefix * <em>Prefix</em>}</li> * <li>{@link org.eclipse.buckminster.model.common.impl.RxPatternImpl#getSuffix * <em>Suffix</em>}</li> * </ul> * </p> * * @generated */ public class RxPatternImpl extends RxPartImpl implements RxPattern { /** * The default value of the '{@link #getPattern() <em>Pattern</em>}' * attribute. <!-- begin-user-doc --> <!-- end-user-doc --> * * @see #getPattern() * @generated * @ordered */ protected static final String PATTERN_EDEFAULT = null; private static void addEscapedPattern(StringBuilder bld, String pattern, boolean willBeGroup) { // No capturing groups permitted. All groups must therefore be converted // into non capturing groups // int orDepth = -1; int startPos = bld.length(); int parenDepth = 0; boolean inCharGroup = false; boolean stripOuter = false; int top = pattern.length(); for (int idx = 0; idx < top;) { char c = pattern.charAt(idx++); switch (c) { case '\\': // Next is escaped // bld.append(c); if (idx < top) c = pattern.charAt(idx++); break; case '|': if (orDepth == -1 || orDepth > parenDepth) orDepth = parenDepth; break; case '[': inCharGroup = true; break; case ']': inCharGroup = false; break; case '(': if (inCharGroup) break; ++parenDepth; if (idx == top) break; if (pattern.charAt(idx) != '?') { // If the pattern starts with a group and this group // contains the whole pattern // then it should be stripped off // if (idx == 1) stripOuter = true; bld.append("(?"); //$NON-NLS-1$ c = ':'; } else { if (idx == 1 && top > 2) stripOuter = (pattern.charAt(2) == ':'); } break; case ')': if (inCharGroup) break; parenDepth--; if (parenDepth < 0) break; if (parenDepth == 0 && idx < top) stripOuter = false; break; } bld.append(c); } if (parenDepth != 0) throw new PatternSyntaxException("Unbalanced parenthesis", pattern, 0); if (stripOuter) { if (willBeGroup || orDepth != 1) { int tpos = startPos; int fpos = startPos + 3; // We strip '(?:' int epos = bld.length() - 1; // and ')' while (fpos < epos) bld.setCharAt(tpos++, bld.charAt(fpos++)); bld.setLength(tpos); } } else if (!willBeGroup && orDepth == 0) { // A group must be added to limit what's affected by the // OR expression // String subExpr = bld.substring(startPos, bld.length()); bld.setLength(startPos); bld.append("(?:"); //$NON-NLS-1$ bld.append(subExpr); bld.append(')'); } } private static void addQuotedString(StringBuilder bld, String str) { int top = str.length(); for (int idx = 0; idx < top; ++idx) { char c = str.charAt(idx); switch (c) { case '\\': case '(': case ')': case '[': case ']': case '{': case '}': case '.': case '?': case '+': case '*': case '|': case '^': case '$': bld.append('\\'); } bld.append(c); } } /** * The cached value of the '{@link #getPattern() <em>Pattern</em>}' * attribute. <!-- begin-user-doc --> <!-- end-user-doc --> * * @see #getPattern() * @generated * @ordered */ protected String pattern = PATTERN_EDEFAULT; /** * The default value of the '{@link #getPrefix() <em>Prefix</em>}' * attribute. <!-- begin-user-doc --> <!-- end-user-doc --> * * @see #getPrefix() * @generated * @ordered */ protected static final String PREFIX_EDEFAULT = null; /** * The cached value of the '{@link #getPrefix() <em>Prefix</em>}' attribute. * <!-- begin-user-doc --> <!-- end-user-doc --> * * @see #getPrefix() * @generated * @ordered */ protected String prefix = PREFIX_EDEFAULT; /** * The default value of the '{@link #getSuffix() <em>Suffix</em>}' * attribute. <!-- begin-user-doc --> <!-- end-user-doc --> * * @see #getSuffix() * @generated * @ordered */ protected static final String SUFFIX_EDEFAULT = null; /** * The cached value of the '{@link #getSuffix() <em>Suffix</em>}' attribute. * <!-- begin-user-doc --> <!-- end-user-doc --> * * @see #getSuffix() * @generated * @ordered */ protected String suffix = SUFFIX_EDEFAULT; /** * <!-- begin-user-doc --> <!-- end-user-doc --> * * @generated */ protected RxPatternImpl() { super(); } @Override public void addPattern(StringBuilder bld, List<RxPart> namedParts) { if (!isOptional()) { addInnerPattern(bld, namedParts, false); return; } // Everything must be in a group that is marked as optional // bld.append('('); if (prefix == null && suffix == null) { if (name == null) bld.append("?:"); // Non capturing group //$NON-NLS-1$ else namedParts.add(this); if (pattern != null) addEscapedPattern(bld, pattern, true); } else { // Group as a whole must be a non capturing group // bld.append("?:"); //$NON-NLS-1$ addInnerPattern(bld, namedParts, true); } bld.append(")?"); //$NON-NLS-1$ } /** * <!-- begin-user-doc --> <!-- end-user-doc --> * * @generated */ @Override public Object eGet(int featureID, boolean resolve, boolean coreType) { switch (featureID) { case CommonPackage.RX_PATTERN__PATTERN: return getPattern(); case CommonPackage.RX_PATTERN__PREFIX: return getPrefix(); case CommonPackage.RX_PATTERN__SUFFIX: return getSuffix(); } return super.eGet(featureID, resolve, coreType); } /** * <!-- begin-user-doc --> <!-- end-user-doc --> * * @generated */ @Override public boolean eIsSet(int featureID) { switch (featureID) { case CommonPackage.RX_PATTERN__PATTERN: return PATTERN_EDEFAULT == null ? pattern != null : !PATTERN_EDEFAULT.equals(pattern); case CommonPackage.RX_PATTERN__PREFIX: return PREFIX_EDEFAULT == null ? prefix != null : !PREFIX_EDEFAULT.equals(prefix); case CommonPackage.RX_PATTERN__SUFFIX: return SUFFIX_EDEFAULT == null ? suffix != null : !SUFFIX_EDEFAULT.equals(suffix); } return super.eIsSet(featureID); } /** * <!-- begin-user-doc --> <!-- end-user-doc --> * * @generated */ @Override public void eSet(int featureID, Object newValue) { switch (featureID) { case CommonPackage.RX_PATTERN__PATTERN: setPattern((String) newValue); return; case CommonPackage.RX_PATTERN__PREFIX: setPrefix((String) newValue); return; case CommonPackage.RX_PATTERN__SUFFIX: setSuffix((String) newValue); return; } super.eSet(featureID, newValue); } /** * <!-- begin-user-doc --> <!-- end-user-doc --> * * @generated */ @Override public void eUnset(int featureID) { switch (featureID) { case CommonPackage.RX_PATTERN__PATTERN: setPattern(PATTERN_EDEFAULT); return; case CommonPackage.RX_PATTERN__PREFIX: setPrefix(PREFIX_EDEFAULT); return; case CommonPackage.RX_PATTERN__SUFFIX: setSuffix(SUFFIX_EDEFAULT); return; } super.eUnset(featureID); } /** * <!-- begin-user-doc --> <!-- end-user-doc --> * * @generated */ @Override public String getPattern() { return pattern; } /** * <!-- begin-user-doc --> <!-- end-user-doc --> * * @generated */ @Override public String getPrefix() { return prefix; } /** * <!-- begin-user-doc --> <!-- end-user-doc --> * * @generated */ @Override public String getSuffix() { return suffix; } /** * <!-- begin-user-doc --> <!-- end-user-doc --> * * @generated */ @Override public void setPattern(String newPattern) { String oldPattern = pattern; pattern = newPattern; if (eNotificationRequired()) eNotify(new ENotificationImpl(this, Notification.SET, CommonPackage.RX_PATTERN__PATTERN, oldPattern, pattern)); } /** * <!-- begin-user-doc --> <!-- end-user-doc --> * * @generated */ @Override public void setPrefix(String newPrefix) { String oldPrefix = prefix; prefix = newPrefix; if (eNotificationRequired()) eNotify(new ENotificationImpl(this, Notification.SET, CommonPackage.RX_PATTERN__PREFIX, oldPrefix, prefix)); } /** * <!-- begin-user-doc --> <!-- end-user-doc --> * * @generated */ @Override public void setSuffix(String newSuffix) { String oldSuffix = suffix; suffix = newSuffix; if (eNotificationRequired()) eNotify(new ENotificationImpl(this, Notification.SET, CommonPackage.RX_PATTERN__SUFFIX, oldSuffix, suffix)); } /** * <!-- begin-user-doc --> <!-- end-user-doc --> * * @generated */ @Override public String toString() { if (eIsProxy()) return super.toString(); StringBuffer result = new StringBuffer(super.toString()); result.append(" (pattern: "); result.append(pattern); result.append(", prefix: "); result.append(prefix); result.append(", suffix: "); result.append(suffix); result.append(')'); return result.toString(); } /** * <!-- begin-user-doc --> <!-- end-user-doc --> * * @generated */ @Override protected EClass eStaticClass() { return CommonPackage.Literals.RX_PATTERN; } private void addInnerPattern(StringBuilder bld, List<RxPart> namedParts, boolean willBeGroup) { if (prefix != null) addQuotedString(bld, prefix); if (pattern != null) { if (getName() != null) { // Pattern must be a capturing group // bld.append('('); addEscapedPattern(bld, pattern, true); bld.append(')'); namedParts.add(this); } else addEscapedPattern(bld, pattern, willBeGroup && prefix == null && suffix == null); } if (suffix != null) addQuotedString(bld, suffix); } } // RxPatternImpl