1*b1cdbd2cSJim Jagielski /************************************************************** 2*b1cdbd2cSJim Jagielski * 3*b1cdbd2cSJim Jagielski * Licensed to the Apache Software Foundation (ASF) under one 4*b1cdbd2cSJim Jagielski * or more contributor license agreements. See the NOTICE file 5*b1cdbd2cSJim Jagielski * distributed with this work for additional information 6*b1cdbd2cSJim Jagielski * regarding copyright ownership. The ASF licenses this file 7*b1cdbd2cSJim Jagielski * to you under the Apache License, Version 2.0 (the 8*b1cdbd2cSJim Jagielski * "License"); you may not use this file except in compliance 9*b1cdbd2cSJim Jagielski * with the License. You may obtain a copy of the License at 10*b1cdbd2cSJim Jagielski * 11*b1cdbd2cSJim Jagielski * http://www.apache.org/licenses/LICENSE-2.0 12*b1cdbd2cSJim Jagielski * 13*b1cdbd2cSJim Jagielski * Unless required by applicable law or agreed to in writing, 14*b1cdbd2cSJim Jagielski * software distributed under the License is distributed on an 15*b1cdbd2cSJim Jagielski * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16*b1cdbd2cSJim Jagielski * KIND, either express or implied. See the License for the 17*b1cdbd2cSJim Jagielski * specific language governing permissions and limitations 18*b1cdbd2cSJim Jagielski * under the License. 19*b1cdbd2cSJim Jagielski * 20*b1cdbd2cSJim Jagielski *************************************************************/ 21*b1cdbd2cSJim Jagielski 22*b1cdbd2cSJim Jagielski 23*b1cdbd2cSJim Jagielski package com.sun.star.report.pentaho; 24*b1cdbd2cSJim Jagielski 25*b1cdbd2cSJim Jagielski 26*b1cdbd2cSJim Jagielski import com.sun.star.lang.XServiceInfo; 27*b1cdbd2cSJim Jagielski import com.sun.star.lib.uno.helper.ComponentBase; 28*b1cdbd2cSJim Jagielski import com.sun.star.lib.uno.helper.PropertySetMixin; 29*b1cdbd2cSJim Jagielski import com.sun.star.sheet.FormulaLanguage; 30*b1cdbd2cSJim Jagielski import com.sun.star.sheet.FormulaMapGroup; 31*b1cdbd2cSJim Jagielski import com.sun.star.sheet.FormulaMapGroupSpecialOffset; 32*b1cdbd2cSJim Jagielski import com.sun.star.sheet.FormulaOpCodeMapEntry; 33*b1cdbd2cSJim Jagielski import com.sun.star.sheet.FormulaToken; 34*b1cdbd2cSJim Jagielski import com.sun.star.sheet.XFormulaOpCodeMapper; 35*b1cdbd2cSJim Jagielski import com.sun.star.uno.Any; 36*b1cdbd2cSJim Jagielski import com.sun.star.uno.Exception; 37*b1cdbd2cSJim Jagielski import com.sun.star.uno.Type; 38*b1cdbd2cSJim Jagielski import com.sun.star.uno.UnoRuntime; 39*b1cdbd2cSJim Jagielski import com.sun.star.uno.XComponentContext; 40*b1cdbd2cSJim Jagielski 41*b1cdbd2cSJim Jagielski import java.io.StringReader; 42*b1cdbd2cSJim Jagielski 43*b1cdbd2cSJim Jagielski import java.util.ArrayList; 44*b1cdbd2cSJim Jagielski import java.util.HashMap; 45*b1cdbd2cSJim Jagielski import java.util.Iterator; 46*b1cdbd2cSJim Jagielski import java.util.List; 47*b1cdbd2cSJim Jagielski import java.util.Map; 48*b1cdbd2cSJim Jagielski 49*b1cdbd2cSJim Jagielski import org.pentaho.reporting.libraries.base.config.Configuration; 50*b1cdbd2cSJim Jagielski import org.pentaho.reporting.libraries.formula.DefaultFormulaContext; 51*b1cdbd2cSJim Jagielski import org.pentaho.reporting.libraries.formula.function.FunctionRegistry; 52*b1cdbd2cSJim Jagielski import org.pentaho.reporting.libraries.formula.parser.FormulaParser; 53*b1cdbd2cSJim Jagielski import org.pentaho.reporting.libraries.formula.parser.GeneratedFormulaParserConstants; 54*b1cdbd2cSJim Jagielski import org.pentaho.reporting.libraries.formula.parser.GeneratedFormulaParserTokenManager; 55*b1cdbd2cSJim Jagielski import org.pentaho.reporting.libraries.formula.parser.JavaCharStream; 56*b1cdbd2cSJim Jagielski import org.pentaho.reporting.libraries.formula.parser.ParseException; 57*b1cdbd2cSJim Jagielski import org.pentaho.reporting.libraries.formula.parser.Token; 58*b1cdbd2cSJim Jagielski import org.pentaho.reporting.libraries.formula.parser.TokenMgrError; 59*b1cdbd2cSJim Jagielski 60*b1cdbd2cSJim Jagielski 61*b1cdbd2cSJim Jagielski public final class SOFormulaParser extends ComponentBase 62*b1cdbd2cSJim Jagielski implements com.sun.star.report.meta.XFormulaParser, XServiceInfo 63*b1cdbd2cSJim Jagielski { 64*b1cdbd2cSJim Jagielski 65*b1cdbd2cSJim Jagielski public static final int SEPARATORS = 0; 66*b1cdbd2cSJim Jagielski public static final int ARRAY_SEPARATORS = 1; 67*b1cdbd2cSJim Jagielski public static final int UNARY_OPERATORS = 2; 68*b1cdbd2cSJim Jagielski public static final int BINARY_OPERATORS = 3; 69*b1cdbd2cSJim Jagielski public static final int FUNCTIONS = 4; 70*b1cdbd2cSJim Jagielski private final XComponentContext m_xContext; 71*b1cdbd2cSJim Jagielski private final PropertySetMixin m_prophlp; 72*b1cdbd2cSJim Jagielski private static final String __serviceName = "com.sun.star.report.meta.FormulaParser"; 73*b1cdbd2cSJim Jagielski private static final String OPERATORS = "org.pentaho.reporting.libraries.formula.operators."; 74*b1cdbd2cSJim Jagielski // attributes 75*b1cdbd2cSJim Jagielski final private List m_OpCodeMap = new ArrayList(); 76*b1cdbd2cSJim Jagielski private XFormulaOpCodeMapper formulaOpCodeMapper = null; 77*b1cdbd2cSJim Jagielski private final Map parserAllOpCodes = new HashMap(); 78*b1cdbd2cSJim Jagielski private final Map parserNames = new HashMap(); 79*b1cdbd2cSJim Jagielski private final Map[] groupOpCodes = new HashMap[5]; 80*b1cdbd2cSJim Jagielski private final List specialOpCodes = new ArrayList(); 81*b1cdbd2cSJim Jagielski getSpecialOpCodes()82*b1cdbd2cSJim Jagielski public List getSpecialOpCodes() 83*b1cdbd2cSJim Jagielski { 84*b1cdbd2cSJim Jagielski return specialOpCodes; 85*b1cdbd2cSJim Jagielski } 86*b1cdbd2cSJim Jagielski private int ownTokenCounter = 1000; 87*b1cdbd2cSJim Jagielski private final FormulaOpCodeMapEntry opCodePush; 88*b1cdbd2cSJim Jagielski private final FormulaParser parser; 89*b1cdbd2cSJim Jagielski SOFormulaParser(final XComponentContext context)90*b1cdbd2cSJim Jagielski public SOFormulaParser(final XComponentContext context) 91*b1cdbd2cSJim Jagielski { 92*b1cdbd2cSJim Jagielski 93*b1cdbd2cSJim Jagielski m_xContext = context; 94*b1cdbd2cSJim Jagielski final ClassLoader cl = java.lang.Thread.currentThread().getContextClassLoader(); 95*b1cdbd2cSJim Jagielski Thread.currentThread().setContextClassLoader(this.getClass().getClassLoader()); 96*b1cdbd2cSJim Jagielski 97*b1cdbd2cSJim Jagielski parser = new FormulaParser(); 98*b1cdbd2cSJim Jagielski try 99*b1cdbd2cSJim Jagielski { 100*b1cdbd2cSJim Jagielski final XFormulaOpCodeMapper mapper = (XFormulaOpCodeMapper) UnoRuntime.queryInterface(XFormulaOpCodeMapper.class, m_xContext.getServiceManager().createInstanceWithContext("simple.formula.FormulaOpCodeMapperObj", m_xContext)); 101*b1cdbd2cSJim Jagielski FormulaOpCodeMapEntry[] opCodes = mapper.getAvailableMappings(FormulaLanguage.ODFF, FormulaMapGroup.FUNCTIONS); 102*b1cdbd2cSJim Jagielski final DefaultFormulaContext defaultContext = new DefaultFormulaContext(); 103*b1cdbd2cSJim Jagielski final FunctionRegistry functionRegistry = defaultContext.getFunctionRegistry(); 104*b1cdbd2cSJim Jagielski 105*b1cdbd2cSJim Jagielski String[] names = functionRegistry.getFunctionNames(); 106*b1cdbd2cSJim Jagielski addOpCodes(names, opCodes, FUNCTIONS); 107*b1cdbd2cSJim Jagielski names = getOperators(defaultContext, OPERATORS); 108*b1cdbd2cSJim Jagielski opCodes = mapper.getAvailableMappings(FormulaLanguage.ODFF, FormulaMapGroup.UNARY_OPERATORS); 109*b1cdbd2cSJim Jagielski addOpCodes(names, opCodes, UNARY_OPERATORS); 110*b1cdbd2cSJim Jagielski opCodes = mapper.getAvailableMappings(FormulaLanguage.ODFF, FormulaMapGroup.BINARY_OPERATORS); 111*b1cdbd2cSJim Jagielski addOpCodes(names, opCodes, BINARY_OPERATORS); 112*b1cdbd2cSJim Jagielski 113*b1cdbd2cSJim Jagielski names = GeneratedFormulaParserConstants.tokenImage.clone(); 114*b1cdbd2cSJim Jagielski for (int i = 0; i < names.length; i++) 115*b1cdbd2cSJim Jagielski { 116*b1cdbd2cSJim Jagielski final String token = names[i]; 117*b1cdbd2cSJim Jagielski if (token != null && token.length() > 0 && token.charAt(0) == '"') 118*b1cdbd2cSJim Jagielski { 119*b1cdbd2cSJim Jagielski names[i] = token.substring(1, token.length() - 1); 120*b1cdbd2cSJim Jagielski } 121*b1cdbd2cSJim Jagielski } 122*b1cdbd2cSJim Jagielski opCodes = mapper.getAvailableMappings(FormulaLanguage.ODFF, FormulaMapGroup.SEPARATORS); 123*b1cdbd2cSJim Jagielski addOpCodes(names, opCodes, SEPARATORS, false); 124*b1cdbd2cSJim Jagielski 125*b1cdbd2cSJim Jagielski opCodes = mapper.getAvailableMappings(FormulaLanguage.ODFF, FormulaMapGroup.ARRAY_SEPARATORS); 126*b1cdbd2cSJim Jagielski addOpCodes(names, opCodes, ARRAY_SEPARATORS, false); 127*b1cdbd2cSJim Jagielski 128*b1cdbd2cSJim Jagielski opCodes = mapper.getAvailableMappings(FormulaLanguage.ODFF, FormulaMapGroup.SPECIAL); 129*b1cdbd2cSJim Jagielski 130*b1cdbd2cSJim Jagielski for (int i = 0; i < opCodes.length; i++) 131*b1cdbd2cSJim Jagielski { 132*b1cdbd2cSJim Jagielski final FormulaOpCodeMapEntry opCode = opCodes[i]; 133*b1cdbd2cSJim Jagielski parserAllOpCodes.put(opCode.Token.OpCode, opCode); 134*b1cdbd2cSJim Jagielski specialOpCodes.add(opCode); 135*b1cdbd2cSJim Jagielski } 136*b1cdbd2cSJim Jagielski // addOpCodes(names, opCodes,SPECIAL,false); 137*b1cdbd2cSJim Jagielski } 138*b1cdbd2cSJim Jagielski catch (Exception ex) 139*b1cdbd2cSJim Jagielski { 140*b1cdbd2cSJim Jagielski ex.printStackTrace(); 141*b1cdbd2cSJim Jagielski } 142*b1cdbd2cSJim Jagielski opCodePush = (FormulaOpCodeMapEntry) specialOpCodes.get(FormulaMapGroupSpecialOffset.PUSH); 143*b1cdbd2cSJim Jagielski Thread.currentThread().setContextClassLoader(cl); 144*b1cdbd2cSJim Jagielski // use the last parameter of the PropertySetMixin constructor 145*b1cdbd2cSJim Jagielski // for your optional attributes if necessary. See the documentation 146*b1cdbd2cSJim Jagielski // of the PropertySetMixin helper for further information. 147*b1cdbd2cSJim Jagielski // Ensure that your attributes are initialized correctly! 148*b1cdbd2cSJim Jagielski m_prophlp = new PropertySetMixin(m_xContext, this, 149*b1cdbd2cSJim Jagielski new Type(com.sun.star.report.meta.XFormulaParser.class), null); 150*b1cdbd2cSJim Jagielski } 151*b1cdbd2cSJim Jagielski 152*b1cdbd2cSJim Jagielski // com.sun.star.sheet.XFormulaParser: parseFormula(String aFormula, com.sun.star.table.CellAddress aReferencePos)153*b1cdbd2cSJim Jagielski public com.sun.star.sheet.FormulaToken[] parseFormula(String aFormula, com.sun.star.table.CellAddress aReferencePos) 154*b1cdbd2cSJim Jagielski { 155*b1cdbd2cSJim Jagielski final ArrayList tokens = new ArrayList(); 156*b1cdbd2cSJim Jagielski if (!"=".equals(aFormula)) 157*b1cdbd2cSJim Jagielski { 158*b1cdbd2cSJim Jagielski String formula; 159*b1cdbd2cSJim Jagielski if (aFormula.charAt(0) == '=') 160*b1cdbd2cSJim Jagielski { 161*b1cdbd2cSJim Jagielski formula = aFormula.substring(1); 162*b1cdbd2cSJim Jagielski } 163*b1cdbd2cSJim Jagielski else 164*b1cdbd2cSJim Jagielski { 165*b1cdbd2cSJim Jagielski formula = aFormula; 166*b1cdbd2cSJim Jagielski } 167*b1cdbd2cSJim Jagielski final ArrayList images = new ArrayList(); 168*b1cdbd2cSJim Jagielski try 169*b1cdbd2cSJim Jagielski { 170*b1cdbd2cSJim Jagielski int brackets = 0; 171*b1cdbd2cSJim Jagielski final GeneratedFormulaParserTokenManager tokenParser = new GeneratedFormulaParserTokenManager(new JavaCharStream(new StringReader(formula), 1, 1)); 172*b1cdbd2cSJim Jagielski Token token = tokenParser.getNextToken(); 173*b1cdbd2cSJim Jagielski while (token.kind != GeneratedFormulaParserConstants.EOF) 174*b1cdbd2cSJim Jagielski { 175*b1cdbd2cSJim Jagielski final FormulaToken formulaToken; 176*b1cdbd2cSJim Jagielski images.add(token.image); 177*b1cdbd2cSJim Jagielski final String upper = token.image.toUpperCase(); 178*b1cdbd2cSJim Jagielski if (parserNames.containsKey(upper)) 179*b1cdbd2cSJim Jagielski { 180*b1cdbd2cSJim Jagielski if ("(".equals(token.image)) 181*b1cdbd2cSJim Jagielski { 182*b1cdbd2cSJim Jagielski brackets++; 183*b1cdbd2cSJim Jagielski } 184*b1cdbd2cSJim Jagielski else if (")".equals(token.image)) 185*b1cdbd2cSJim Jagielski { 186*b1cdbd2cSJim Jagielski --brackets; 187*b1cdbd2cSJim Jagielski } 188*b1cdbd2cSJim Jagielski final FormulaOpCodeMapEntry opCode = (FormulaOpCodeMapEntry) parserNames.get(upper); 189*b1cdbd2cSJim Jagielski formulaToken = opCode.Token; 190*b1cdbd2cSJim Jagielski } 191*b1cdbd2cSJim Jagielski else if (token.kind == GeneratedFormulaParserConstants.WHITESPACE) 192*b1cdbd2cSJim Jagielski { 193*b1cdbd2cSJim Jagielski final FormulaOpCodeMapEntry opCode = (FormulaOpCodeMapEntry) specialOpCodes.get(FormulaMapGroupSpecialOffset.SPACES); 194*b1cdbd2cSJim Jagielski formulaToken = opCode.Token; 195*b1cdbd2cSJim Jagielski } 196*b1cdbd2cSJim Jagielski else 197*b1cdbd2cSJim Jagielski { 198*b1cdbd2cSJim Jagielski formulaToken = new FormulaToken(); 199*b1cdbd2cSJim Jagielski formulaToken.OpCode = opCodePush.Token.OpCode; 200*b1cdbd2cSJim Jagielski formulaToken.Data = new Any(Type.STRING, token.image); 201*b1cdbd2cSJim Jagielski } 202*b1cdbd2cSJim Jagielski 203*b1cdbd2cSJim Jagielski tokens.add(formulaToken); 204*b1cdbd2cSJim Jagielski token = tokenParser.getNextToken(); 205*b1cdbd2cSJim Jagielski } 206*b1cdbd2cSJim Jagielski if (brackets > 0) 207*b1cdbd2cSJim Jagielski { 208*b1cdbd2cSJim Jagielski final FormulaOpCodeMapEntry opCode = (FormulaOpCodeMapEntry) parserNames.get(")"); 209*b1cdbd2cSJim Jagielski while (brackets-- != 0) 210*b1cdbd2cSJim Jagielski { 211*b1cdbd2cSJim Jagielski formula = formula.concat(")"); 212*b1cdbd2cSJim Jagielski images.add(")"); 213*b1cdbd2cSJim Jagielski tokens.add(opCode.Token); 214*b1cdbd2cSJim Jagielski } 215*b1cdbd2cSJim Jagielski 216*b1cdbd2cSJim Jagielski } 217*b1cdbd2cSJim Jagielski 218*b1cdbd2cSJim Jagielski parser.parse(formula); 219*b1cdbd2cSJim Jagielski } 220*b1cdbd2cSJim Jagielski catch (ParseException ex) 221*b1cdbd2cSJim Jagielski { 222*b1cdbd2cSJim Jagielski boolean found = false; 223*b1cdbd2cSJim Jagielski // error occured so all token must be bad 224*b1cdbd2cSJim Jagielski for (int i = 0; i < tokens.size(); i++) 225*b1cdbd2cSJim Jagielski { 226*b1cdbd2cSJim Jagielski if (!found && ex.currentToken != null && images.get(i).equals(ex.currentToken.image)) 227*b1cdbd2cSJim Jagielski { 228*b1cdbd2cSJim Jagielski found = true; 229*b1cdbd2cSJim Jagielski } 230*b1cdbd2cSJim Jagielski if (found) 231*b1cdbd2cSJim Jagielski { 232*b1cdbd2cSJim Jagielski final FormulaToken dest = new FormulaToken(); 233*b1cdbd2cSJim Jagielski dest.OpCode = ((FormulaOpCodeMapEntry) specialOpCodes.get(FormulaMapGroupSpecialOffset.BAD)).Token.OpCode; 234*b1cdbd2cSJim Jagielski dest.Data = new Any(Type.STRING, images.get(i)); 235*b1cdbd2cSJim Jagielski tokens.remove(i); 236*b1cdbd2cSJim Jagielski tokens.add(i, dest); 237*b1cdbd2cSJim Jagielski } 238*b1cdbd2cSJim Jagielski } 239*b1cdbd2cSJim Jagielski } 240*b1cdbd2cSJim Jagielski catch (java.lang.Exception e) 241*b1cdbd2cSJim Jagielski { 242*b1cdbd2cSJim Jagielski } 243*b1cdbd2cSJim Jagielski catch (TokenMgrError e) 244*b1cdbd2cSJim Jagielski { 245*b1cdbd2cSJim Jagielski } 246*b1cdbd2cSJim Jagielski } 247*b1cdbd2cSJim Jagielski return (FormulaToken[]) tokens.toArray(new FormulaToken[tokens.size()]); 248*b1cdbd2cSJim Jagielski } 249*b1cdbd2cSJim Jagielski printFormula(com.sun.star.sheet.FormulaToken[] aTokens, com.sun.star.table.CellAddress aReferencePos)250*b1cdbd2cSJim Jagielski public String printFormula(com.sun.star.sheet.FormulaToken[] aTokens, com.sun.star.table.CellAddress aReferencePos) 251*b1cdbd2cSJim Jagielski { 252*b1cdbd2cSJim Jagielski final StringBuffer ret = new StringBuffer(); 253*b1cdbd2cSJim Jagielski for (int i = 0; i < aTokens.length; i++) 254*b1cdbd2cSJim Jagielski { 255*b1cdbd2cSJim Jagielski final FormulaToken formulaToken = aTokens[i]; 256*b1cdbd2cSJim Jagielski if (formulaToken.OpCode == opCodePush.Token.OpCode && !formulaToken.Data.equals(Any.VOID)) 257*b1cdbd2cSJim Jagielski { 258*b1cdbd2cSJim Jagielski ret.append(formulaToken.Data); 259*b1cdbd2cSJim Jagielski } 260*b1cdbd2cSJim Jagielski else if (parserAllOpCodes.containsKey(formulaToken.OpCode)) 261*b1cdbd2cSJim Jagielski { 262*b1cdbd2cSJim Jagielski final FormulaOpCodeMapEntry opCode = (FormulaOpCodeMapEntry) parserAllOpCodes.get(formulaToken.OpCode); 263*b1cdbd2cSJim Jagielski if (opCode.Name.length() > 0) 264*b1cdbd2cSJim Jagielski { 265*b1cdbd2cSJim Jagielski ret.append(opCode.Name); 266*b1cdbd2cSJim Jagielski } 267*b1cdbd2cSJim Jagielski else if (!formulaToken.Data.equals(Any.VOID)) 268*b1cdbd2cSJim Jagielski { 269*b1cdbd2cSJim Jagielski ret.append(formulaToken.Data); 270*b1cdbd2cSJim Jagielski } 271*b1cdbd2cSJim Jagielski } 272*b1cdbd2cSJim Jagielski } 273*b1cdbd2cSJim Jagielski return ret.toString(); 274*b1cdbd2cSJim Jagielski } 275*b1cdbd2cSJim Jagielski 276*b1cdbd2cSJim Jagielski // com.sun.star.beans.XPropertySet: getPropertySetInfo()277*b1cdbd2cSJim Jagielski public com.sun.star.beans.XPropertySetInfo getPropertySetInfo() 278*b1cdbd2cSJim Jagielski { 279*b1cdbd2cSJim Jagielski return m_prophlp.getPropertySetInfo(); 280*b1cdbd2cSJim Jagielski } 281*b1cdbd2cSJim Jagielski setPropertyValue(String aPropertyName, Object aValue)282*b1cdbd2cSJim Jagielski public void setPropertyValue(String aPropertyName, Object aValue) throws com.sun.star.beans.UnknownPropertyException, com.sun.star.beans.PropertyVetoException, com.sun.star.lang.IllegalArgumentException, com.sun.star.lang.WrappedTargetException 283*b1cdbd2cSJim Jagielski { 284*b1cdbd2cSJim Jagielski m_prophlp.setPropertyValue(aPropertyName, aValue); 285*b1cdbd2cSJim Jagielski } 286*b1cdbd2cSJim Jagielski getPropertyValue(String aPropertyName)287*b1cdbd2cSJim Jagielski public Object getPropertyValue(String aPropertyName) throws com.sun.star.beans.UnknownPropertyException, com.sun.star.lang.WrappedTargetException 288*b1cdbd2cSJim Jagielski { 289*b1cdbd2cSJim Jagielski return m_prophlp.getPropertyValue(aPropertyName); 290*b1cdbd2cSJim Jagielski } 291*b1cdbd2cSJim Jagielski addPropertyChangeListener(String aPropertyName, com.sun.star.beans.XPropertyChangeListener xListener)292*b1cdbd2cSJim Jagielski public void addPropertyChangeListener(String aPropertyName, com.sun.star.beans.XPropertyChangeListener xListener) throws com.sun.star.beans.UnknownPropertyException, com.sun.star.lang.WrappedTargetException 293*b1cdbd2cSJim Jagielski { 294*b1cdbd2cSJim Jagielski m_prophlp.addPropertyChangeListener(aPropertyName, xListener); 295*b1cdbd2cSJim Jagielski } 296*b1cdbd2cSJim Jagielski removePropertyChangeListener(String aPropertyName, com.sun.star.beans.XPropertyChangeListener xListener)297*b1cdbd2cSJim Jagielski public void removePropertyChangeListener(String aPropertyName, com.sun.star.beans.XPropertyChangeListener xListener) throws com.sun.star.beans.UnknownPropertyException, com.sun.star.lang.WrappedTargetException 298*b1cdbd2cSJim Jagielski { 299*b1cdbd2cSJim Jagielski m_prophlp.removePropertyChangeListener(aPropertyName, xListener); 300*b1cdbd2cSJim Jagielski } 301*b1cdbd2cSJim Jagielski addVetoableChangeListener(String aPropertyName, com.sun.star.beans.XVetoableChangeListener xListener)302*b1cdbd2cSJim Jagielski public void addVetoableChangeListener(String aPropertyName, com.sun.star.beans.XVetoableChangeListener xListener) throws com.sun.star.beans.UnknownPropertyException, com.sun.star.lang.WrappedTargetException 303*b1cdbd2cSJim Jagielski { 304*b1cdbd2cSJim Jagielski m_prophlp.addVetoableChangeListener(aPropertyName, xListener); 305*b1cdbd2cSJim Jagielski } 306*b1cdbd2cSJim Jagielski removeVetoableChangeListener(String aPropertyName, com.sun.star.beans.XVetoableChangeListener xListener)307*b1cdbd2cSJim Jagielski public void removeVetoableChangeListener(String aPropertyName, com.sun.star.beans.XVetoableChangeListener xListener) throws com.sun.star.beans.UnknownPropertyException, com.sun.star.lang.WrappedTargetException 308*b1cdbd2cSJim Jagielski { 309*b1cdbd2cSJim Jagielski m_prophlp.removeVetoableChangeListener(aPropertyName, xListener); 310*b1cdbd2cSJim Jagielski } 311*b1cdbd2cSJim Jagielski 312*b1cdbd2cSJim Jagielski // com.sun.star.report.meta.XFormulaParser: getOpCodeMap()313*b1cdbd2cSJim Jagielski public com.sun.star.sheet.FormulaOpCodeMapEntry[] getOpCodeMap() 314*b1cdbd2cSJim Jagielski { 315*b1cdbd2cSJim Jagielski return (com.sun.star.sheet.FormulaOpCodeMapEntry[]) m_OpCodeMap.toArray(new FormulaOpCodeMapEntry[m_OpCodeMap.size()]); 316*b1cdbd2cSJim Jagielski } 317*b1cdbd2cSJim Jagielski setOpCodeMap(com.sun.star.sheet.FormulaOpCodeMapEntry[] the_value)318*b1cdbd2cSJim Jagielski public void setOpCodeMap(com.sun.star.sheet.FormulaOpCodeMapEntry[] the_value) 319*b1cdbd2cSJim Jagielski { 320*b1cdbd2cSJim Jagielski // m_prophlp.prepareSet("OpCodeMap", null); 321*b1cdbd2cSJim Jagielski // synchronized (this) 322*b1cdbd2cSJim Jagielski // { 323*b1cdbd2cSJim Jagielski // m_OpCodeMap.clear(); 324*b1cdbd2cSJim Jagielski // } 325*b1cdbd2cSJim Jagielski } 326*b1cdbd2cSJim Jagielski getImplementationName()327*b1cdbd2cSJim Jagielski public String getImplementationName() 328*b1cdbd2cSJim Jagielski { 329*b1cdbd2cSJim Jagielski return SOFormulaParser.class.getName(); 330*b1cdbd2cSJim Jagielski } 331*b1cdbd2cSJim Jagielski supportsService(String sServiceName)332*b1cdbd2cSJim Jagielski public boolean supportsService(String sServiceName) 333*b1cdbd2cSJim Jagielski { 334*b1cdbd2cSJim Jagielski return sServiceName.equals(__serviceName); 335*b1cdbd2cSJim Jagielski } 336*b1cdbd2cSJim Jagielski getSupportedServiceNames()337*b1cdbd2cSJim Jagielski public String[] getSupportedServiceNames() 338*b1cdbd2cSJim Jagielski { 339*b1cdbd2cSJim Jagielski return getServiceNames(); 340*b1cdbd2cSJim Jagielski } 341*b1cdbd2cSJim Jagielski 342*b1cdbd2cSJim Jagielski /** 343*b1cdbd2cSJim Jagielski * This method is a simple helper function to used in the static component initialisation functions as well as 344*b1cdbd2cSJim Jagielski * in getSupportedServiceNames. 345*b1cdbd2cSJim Jagielski * @return 346*b1cdbd2cSJim Jagielski */ getServiceNames()347*b1cdbd2cSJim Jagielski public static String[] getServiceNames() 348*b1cdbd2cSJim Jagielski { 349*b1cdbd2cSJim Jagielski return new String[] 350*b1cdbd2cSJim Jagielski { 351*b1cdbd2cSJim Jagielski __serviceName 352*b1cdbd2cSJim Jagielski }; 353*b1cdbd2cSJim Jagielski } 354*b1cdbd2cSJim Jagielski getFormulaOpCodeMapper()355*b1cdbd2cSJim Jagielski public XFormulaOpCodeMapper getFormulaOpCodeMapper() 356*b1cdbd2cSJim Jagielski { 357*b1cdbd2cSJim Jagielski if (formulaOpCodeMapper == null) 358*b1cdbd2cSJim Jagielski { 359*b1cdbd2cSJim Jagielski formulaOpCodeMapper = new SOFormulaOpCodeMapper(this); 360*b1cdbd2cSJim Jagielski } 361*b1cdbd2cSJim Jagielski 362*b1cdbd2cSJim Jagielski return formulaOpCodeMapper; 363*b1cdbd2cSJim Jagielski } 364*b1cdbd2cSJim Jagielski addOpCodes(String[] names, FormulaOpCodeMapEntry[] opCodes, int group)365*b1cdbd2cSJim Jagielski private void addOpCodes(String[] names, FormulaOpCodeMapEntry[] opCodes, int group) 366*b1cdbd2cSJim Jagielski { 367*b1cdbd2cSJim Jagielski addOpCodes(names, opCodes, group, true); 368*b1cdbd2cSJim Jagielski } 369*b1cdbd2cSJim Jagielski addOpCodes(String[] names, FormulaOpCodeMapEntry[] opCodes, int group, boolean add)370*b1cdbd2cSJim Jagielski private void addOpCodes(String[] names, FormulaOpCodeMapEntry[] opCodes, int group, boolean add) 371*b1cdbd2cSJim Jagielski { 372*b1cdbd2cSJim Jagielski groupOpCodes[group] = new HashMap(); 373*b1cdbd2cSJim Jagielski for (int j = 0; j < names.length; j++) 374*b1cdbd2cSJim Jagielski { 375*b1cdbd2cSJim Jagielski FormulaOpCodeMapEntry opCode = null; 376*b1cdbd2cSJim Jagielski int i = 0; 377*b1cdbd2cSJim Jagielski for (; i < opCodes.length; i++) 378*b1cdbd2cSJim Jagielski { 379*b1cdbd2cSJim Jagielski opCode = opCodes[i]; 380*b1cdbd2cSJim Jagielski if (names[j].equals(opCode.Name)) 381*b1cdbd2cSJim Jagielski { 382*b1cdbd2cSJim Jagielski break; 383*b1cdbd2cSJim Jagielski } 384*b1cdbd2cSJim Jagielski } 385*b1cdbd2cSJim Jagielski if (i >= opCodes.length) 386*b1cdbd2cSJim Jagielski { 387*b1cdbd2cSJim Jagielski if (!add) 388*b1cdbd2cSJim Jagielski { 389*b1cdbd2cSJim Jagielski continue; 390*b1cdbd2cSJim Jagielski } 391*b1cdbd2cSJim Jagielski final FormulaToken token = new FormulaToken(ownTokenCounter++, Any.VOID); 392*b1cdbd2cSJim Jagielski opCode = new FormulaOpCodeMapEntry(names[j], token); 393*b1cdbd2cSJim Jagielski } 394*b1cdbd2cSJim Jagielski parserNames.put(names[j], opCode); 395*b1cdbd2cSJim Jagielski parserAllOpCodes.put(opCode.Token.OpCode, opCode); 396*b1cdbd2cSJim Jagielski groupOpCodes[group].put(opCode.Token.OpCode, opCode); 397*b1cdbd2cSJim Jagielski } 398*b1cdbd2cSJim Jagielski } 399*b1cdbd2cSJim Jagielski getNames()400*b1cdbd2cSJim Jagielski public Map getNames() 401*b1cdbd2cSJim Jagielski { 402*b1cdbd2cSJim Jagielski return parserNames; 403*b1cdbd2cSJim Jagielski } 404*b1cdbd2cSJim Jagielski getGroup(int group)405*b1cdbd2cSJim Jagielski public Map getGroup(int group) 406*b1cdbd2cSJim Jagielski { 407*b1cdbd2cSJim Jagielski return groupOpCodes[group]; 408*b1cdbd2cSJim Jagielski } 409*b1cdbd2cSJim Jagielski getOperators(DefaultFormulaContext defaultContext, final String _kind)410*b1cdbd2cSJim Jagielski private String[] getOperators(DefaultFormulaContext defaultContext, final String _kind) 411*b1cdbd2cSJim Jagielski { 412*b1cdbd2cSJim Jagielski final ArrayList ops = new ArrayList(); 413*b1cdbd2cSJim Jagielski final Configuration configuration = defaultContext.getConfiguration(); 414*b1cdbd2cSJim Jagielski final Iterator iter = configuration.findPropertyKeys(_kind); 415*b1cdbd2cSJim Jagielski while (iter.hasNext()) 416*b1cdbd2cSJim Jagielski { 417*b1cdbd2cSJim Jagielski final String configKey = (String) iter.next(); 418*b1cdbd2cSJim Jagielski if (!configKey.endsWith(".class")) 419*b1cdbd2cSJim Jagielski { 420*b1cdbd2cSJim Jagielski continue; 421*b1cdbd2cSJim Jagielski } 422*b1cdbd2cSJim Jagielski final String operatorClass = configuration.getConfigProperty(configKey); 423*b1cdbd2cSJim Jagielski if (operatorClass == null) 424*b1cdbd2cSJim Jagielski { 425*b1cdbd2cSJim Jagielski continue; 426*b1cdbd2cSJim Jagielski } 427*b1cdbd2cSJim Jagielski if (operatorClass.length() == 0) 428*b1cdbd2cSJim Jagielski { 429*b1cdbd2cSJim Jagielski continue; 430*b1cdbd2cSJim Jagielski } 431*b1cdbd2cSJim Jagielski final String tokenKey = configKey.substring(0, configKey.length() - ".class".length()) + ".token"; 432*b1cdbd2cSJim Jagielski final String token = configuration.getConfigProperty(tokenKey); 433*b1cdbd2cSJim Jagielski if (token == null) 434*b1cdbd2cSJim Jagielski { 435*b1cdbd2cSJim Jagielski continue; 436*b1cdbd2cSJim Jagielski } 437*b1cdbd2cSJim Jagielski ops.add(token.trim()); 438*b1cdbd2cSJim Jagielski } 439*b1cdbd2cSJim Jagielski return (String[]) ops.toArray(new String[ops.size()]); 440*b1cdbd2cSJim Jagielski } 441*b1cdbd2cSJim Jagielski } 442*b1cdbd2cSJim Jagielski 443