| /** |
| * Copyright (c) 2011 Forschungszentrum Juelich GmbH |
| * 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: |
| * Carsten Karbach, FZ Juelich |
| */ |
| |
| package org.eclipse.ptp.rm.lml.internal.core.nodedisplay; |
| |
| import java.math.BigInteger; |
| |
| import org.eclipse.ptp.rm.lml.internal.core.elements.ObjectFactory; |
| import org.eclipse.ptp.rm.lml.internal.core.elements.SchemeElement; |
| |
| /** |
| * Saves a mask for creating implicit names |
| * calculates the length of the output, which this mask will print out |
| * @author Carsten Karbach |
| * |
| */ |
| public class Mask { |
| |
| private static final String number = "\\s*(-|\\+)?(0x|0X)?([a-fA-F\\d]+)";//Regular expression for a printed integer |
| |
| private String maskstring; |
| |
| private String regularMask;//regular expression which printouts must match for this mask |
| |
| private int outputlength; |
| |
| private String pre, post;//text-pattern before and behind the printed digit |
| |
| private String[] names;//null, if no map-attribute specified, otherwise contains explicitly allowed names |
| |
| private SchemeElement scheme;//scheme-element which contains mask-definition |
| |
| private int[] numbers = null;//contains numbers of elements defined by scheme (list=1,17,2 => numbers={1,17,2}) |
| |
| /** |
| * @param pscheme scheme-element which contains the mask-definition |
| */ |
| public Mask(SchemeElement pscheme) { |
| |
| scheme = pscheme; |
| |
| if (pscheme.getMap() != null) { |
| names = pscheme.getMap().split(","); |
| |
| outputlength = -1;//variable, because name lengths can be variable |
| |
| regularMask = pscheme.getMap().replace(',', '|'); |
| pre = ""; |
| post = ""; |
| maskstring = ""; |
| |
| } |
| else { |
| names = null; |
| |
| maskstring = pscheme.getMask(); |
| //regular expression in xsd (([^%])*%(\-|\+|\s|\#)*0(\-|\+|\s|\#)*(\d)+d([^%])*)|(([^%])*%(\-|\+|\s|\#)*d([^%])+) |
| if (maskstring.matches("([^%])*%(\\-|\\+|\\s|\\#)*d([^%])+")) {//length is unknown but there is a separator specified |
| outputlength = -1; |
| } |
| else {//there must be given a length within the mask |
| //Find length by printing out the number 1 with that mask |
| outputlength = String.format(maskstring, 1).length(); |
| } |
| |
| //create regular expression for this mask |
| int percent = maskstring.indexOf('%'); |
| int dpos = maskstring.indexOf('d'); |
| pre = maskstring.substring(0, percent); |
| post = maskstring.substring(dpos+1, maskstring.length()); |
| regularMask = pre + number + post; |
| } |
| |
| } |
| |
| /** |
| * Tests output against regular expression given by the mask |
| * Moreover outputlength must match the length of this output |
| * @param output number-output probably created through this mask |
| * @return true if output is allowed, false otherwise |
| */ |
| public boolean isOutputAllowed(String output) { |
| if (names == null) { |
| return output.matches(regularMask) && (outputlength == -1 || outputlength == output.length()); |
| } |
| //Just test if output is equal to one of the names |
| for (String name : names) { |
| if (name.equals(output)) { |
| return true; |
| } |
| } |
| |
| return false; |
| } |
| |
| /** |
| * Input is the part of the implicit name printed by this mask |
| * @param levelstring output part of implicit name |
| * @return id-nr for current level or -1, if id could not be parsed |
| */ |
| public int getNumberOfLevelstring(String levelstring) { |
| |
| if (names == null) { |
| |
| if (!isOutputAllowed(levelstring)) { |
| return -1;//For robustness of this function |
| } |
| |
| levelstring = levelstring.substring(pre.length()); //cut pre-text from inception |
| levelstring = levelstring.substring(0, levelstring.length()-post.length()); //cut post-text from end of levelstring |
| |
| char[] chars = levelstring.toCharArray(); |
| |
| int i = 0; |
| while (i < chars.length && chars[i] < '0' || chars[i] > '9') { |
| i++; |
| } |
| |
| //No digit at all? |
| if (i == chars.length) { |
| return -1; |
| } |
| |
| String number = String.valueOf(chars[i]); |
| i++; |
| while (i < chars.length && chars[i] >= '0' && chars[i] <= '9') { |
| number += chars[i]; |
| i++; |
| } |
| |
| return Integer.parseInt(number); |
| |
| } |
| else{//special names defined, search position of levelstring within names, map position to id |
| int pos = 0; |
| for (String name : names) { |
| if (name.equals(levelstring)) { |
| |
| if (scheme.getList() != null) { |
| |
| if (numbers == null) { |
| numbers = LMLCheck.getNumbersFromNumberlist(scheme.getList()); |
| } |
| |
| return numbers[pos]; |
| } |
| else { |
| int min = scheme.getMin().intValue(); |
| int max = min; |
| |
| if (scheme.getMax() != null) { |
| max = scheme.getMax().intValue(); |
| } |
| |
| int step = scheme.getStep().intValue(); |
| |
| return min + step * pos; |
| } |
| } |
| pos++; |
| } |
| } |
| //No matches |
| return -1; |
| } |
| |
| /** |
| * Inverse function of getNumberOfLevelstring, id is given and searched is the implicit name |
| * of the component with that id on this level. |
| * @param id |
| * @return implicit name of element with given id |
| */ |
| public String getImplicitLevelname(int id) { |
| return LMLCheck.getLevelName(scheme, id); |
| } |
| |
| public int getOutputLength() { |
| return outputlength; |
| } |
| |
| public String getMask() { |
| return maskstring; |
| } |
| |
| public static void main(String[] args) { |
| |
| ObjectFactory objf = new ObjectFactory(); |
| |
| SchemeElement scheme = objf.createSchemeElement(); |
| scheme.setMin(BigInteger.valueOf(5)); |
| scheme.setMax(BigInteger.valueOf(10)); |
| scheme.setStep(BigInteger.valueOf(1)); |
| scheme.setMap("hans,peter,jupp"); |
| |
| Mask m = new Mask(scheme); |
| System.out.println(m.getNumberOfLevelstring("peter")); |
| } |
| |
| } |
| |