Back to project page android-cassowary-layout.
The source code is released under:
Apache License
If you think the Android project android-cassowary-layout listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.
package no.agens.cassowarylayout;/* * Copyright (C) 2014 Agens AS//from ww w . jav a2 s. c o m * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import org.pybee.cassowary.Constraint; import org.pybee.cassowary.Expression; import org.pybee.cassowary.Strength; import org.pybee.cassowary.Variable; import java.util.ArrayList; import java.util.List; import java.util.Stack; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * Created by alex on 25/09/2014. */ public class ConstraintParser { private static final Pattern pattern = Pattern.compile("\\s*(.*?)\\s*(<=|==|>=|[GL]?EQ)\\s*(.*?)\\s*(!(required|strong|medium|weak))?"); final static String OPS = "-+/*^"; public interface CassowaryVariableResolver { Variable resolveVariable(String variableName); Expression resolveConstant(String name); } public static Constraint parseConstraint(String constraintString, CassowaryVariableResolver variableResolver) { Matcher matcher = pattern.matcher(constraintString); matcher.find(); if (matcher.matches()) { Variable variable = variableResolver.resolveVariable(matcher.group(1)); Constraint.Operator operator = parseOperator(matcher.group(2)); Expression expression = resolveExpression(matcher.group(3), variableResolver); Strength strength = parseStrength(matcher.group(4)); return new Constraint(variable, operator, expression, strength); } else { throw new RuntimeException("could not parse " + constraintString); } } private static Constraint.Operator parseOperator(String operatorString) { Constraint.Operator operator = null; if ("EQ".equals(operatorString) || "==".equals(operatorString)) { operator = Constraint.Operator.EQ; } else if ("GEQ".equals(operatorString) || ">=".equals(operatorString)) { operator = Constraint.Operator.GEQ; } else if ("LEQ".equals(operatorString) || "<=".equals(operatorString)) { operator = Constraint.Operator.LEQ; } return operator; } private static Strength parseStrength(String strengthString) { Strength strength = Strength.REQUIRED; if ("!required".equals(strengthString)) { strength = Strength.REQUIRED; } else if ("!strong".equals(strengthString)) { strength = Strength.STRONG; } else if ("!medium".equals(strengthString)) { strength = Strength.MEDIUM; } else if ("!weak".equals(strengthString)) { strength = Strength.WEAK; } return strength; } public static Expression resolveExpression(String expressionString, CassowaryVariableResolver variableResolver) { List<String> postFixExpression = infixToPostfix(tokenizeExpression(expressionString)); Stack<Expression> linearExpressionsStack = new Stack<Expression>(); for (String expression : postFixExpression) { if ("+".equals(expression)) { linearExpressionsStack.push(linearExpressionsStack.pop().plus(linearExpressionsStack.pop())); } else if ("-".equals(expression)) { linearExpressionsStack.push(linearExpressionsStack.pop().subtractFrom(linearExpressionsStack.pop())); } else if ("/".equals(expression)) { Expression denominator = linearExpressionsStack.pop(); Expression numerator = linearExpressionsStack.pop(); linearExpressionsStack.push(numerator.divide(denominator)); } else if ("*".equals(expression)) { linearExpressionsStack.push(linearExpressionsStack.pop().times(linearExpressionsStack.pop())); } else { Expression linearExpression = variableResolver.resolveConstant(expression); if (linearExpression == null) { linearExpression = new Expression(variableResolver.resolveVariable(expression)); } linearExpressionsStack.push(linearExpression); } } return linearExpressionsStack.pop(); } public static List<String> infixToPostfix(List<String> tokenList) { Stack<Integer> s = new Stack<Integer>(); List<String> postFix = new ArrayList<String>(); for (String token : tokenList) { char c = token.charAt(0); int idx = OPS.indexOf(c); if (idx != -1 && token.length() == 1) { if (s.isEmpty()) s.push(idx); else { while (!s.isEmpty()) { int prec2 = s.peek() / 2; int prec1 = idx / 2; if (prec2 > prec1 || (prec2 == prec1 && c != '^')) postFix.add(Character.toString(OPS.charAt(s.pop()))); else break; } s.push(idx); } } else if (c == '(') { s.push(-2); } else if (c == ')') { while (s.peek() != -2) postFix.add(Character.toString(OPS.charAt(s.pop()))); s.pop(); } else { postFix.add(token); } } while (!s.isEmpty()) postFix.add(Character.toString(OPS.charAt(s.pop()))); return postFix; } public static List<String> tokenizeExpression(String expressionString) { ArrayList<String> tokenList = new ArrayList<String>(); StringBuilder stringBuilder = new StringBuilder(); int i; for (i = 0; i < expressionString.length(); i++) { char c = expressionString.charAt(i); switch (c) { case '+': case '-': case '*': case '/': case '(': case ')': if (stringBuilder.length() > 0) { tokenList.add(stringBuilder.toString()); stringBuilder.setLength(0); } tokenList.add(Character.toString(c)); break; case ' ': // ignore space break; default: stringBuilder.append(c); } } if (stringBuilder.length() > 0) { tokenList.add(stringBuilder.toString()); } return tokenList; } }