/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you 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. */ #if !defined(XALAN_ELEMNUMBER_HEADER_GUARD) #define XALAN_ELEMNUMBER_HEADER_GUARD // Base include file. Must be first. #include #include // Base class header file. #include #include #include #include #include namespace XALAN_CPP_NAMESPACE { class AVT; class MutableNodeRefList; class XalanNumberFormat; class XPath; class XPathExecutionContext; class ElemNumber: public ElemTemplateElement { public: typedef CountersTable::CountType CountType; enum eLevel { eSingle, eMultiple, eAny }; typedef XalanVector CountTypeArrayType; /** * Perform static initialization. See class XSLTInit. */ static void initialize(MemoryManager& theManager); /** * Perform static shut down. See class XSLTInit. */ static void terminate(); /** * Construct an object corresponding to an "xsl:number" element * * @param constructionContext context for construction of object * @param stylesheetTree stylesheet containing element * @param atts list of attributes for element * @param lineNumber line number in document * @param columnNumber column number in document * @param id The unique ID within the stylesheet for this xsl:number element */ ElemNumber( StylesheetConstructionContext& constructionContext, Stylesheet& stylesheetTree, const AttributeListType& atts, XalanFileLoc lineNumber, XalanFileLoc columnNumber, unsigned long id); static ElemNumber* create( MemoryManager& theManager, StylesheetConstructionContext& constructionContext, Stylesheet& stylesheetTree, const AttributeListType& atts, XalanFileLoc lineNumber, XalanFileLoc columnNumber, unsigned long id); virtual ~ElemNumber(); // These methods are inherited from ElemTemplateElement ... virtual const XalanDOMString& getElementName() const; #if !defined(XALAN_RECURSIVE_STYLESHEET_EXECUTION) virtual const ElemTemplateElement* startElement(StylesheetExecutionContext& executionContext) const; #else virtual void execute(StylesheetExecutionContext& executionContext) const; #endif unsigned long getID() const { return m_id; } /** * Get the previous node to be counted. */ XalanNode* getPreviousNode( StylesheetExecutionContext& executionContext, XalanNode* pos) const; /** * Get the target node that will be counted.. */ XalanNode* getTargetNode( StylesheetExecutionContext& executionContext, XalanNode* sourceNode) const; virtual const XPath* getXPath(XalanSize_t index) const; protected: /** * Given a 'from' pattern (ala xsl:number), a match pattern * and a context, find the first ancestor that matches the * pattern (including the context handed in). * * @param executionContext The current execution context * @param matchPatternString The match pattern. * @param matchPatternString The count match pattern. * @param node The context node * @return A pointer to the matched node. */ XalanNode* findAncestor( StylesheetExecutionContext& executionContext, const XPath* fromMatchPattern, const XPath* countMatchPattern, XalanNode* context) const; /** * Given a 'from' pattern (ala xsl:number), a match pattern * and a context, find the first ancestor that matches the * pattern (including the context handed in). * * @param executionContext The current execution context * @param matchPatternString The match pattern. * @param matchPatternString The count match pattern. * @param node The context node * @return A pointer to the matched node. */ XalanNode* findPrecedingOrAncestorOrSelf( StylesheetExecutionContext& executionContext, const XPath* fromMatchPattern, const XPath* countMatchPattern, XalanNode* context) const; /** * Get the count match pattern, or a default value. */ const XPath* getCountMatchPattern( StylesheetExecutionContext& executionContext, XalanNode* contextNode) const; /** * Given an XML source node, get the count according to the * parameters set up by the xsl:number attributes. */ void getCountString( StylesheetExecutionContext& executionContext, XalanDOMString& theResult) const; void getCountString( StylesheetExecutionContext& executionContext, const MutableNodeRefList& ancestors, CountersTable& ctable, CountType numberList[], NodeRefListBase::size_type numberListLength, XalanDOMString& theResult) const; /** * Get the ancestors, up to the root, that match the * pattern. * @param patterns if non-0, count only nodes * that match this pattern, if 0 count all ancestors. * @param executionContext The current execution context. * @param node Count this node and it's ancestors. * @param stopAtFirstFound If true, only get the first matching ancestor * @param ancestors The ancestors that match the pattern. */ void getMatchingAncestors( StylesheetExecutionContext& executionContext, XalanNode* node, bool stopAtFirstFound, MutableNodeRefList& ancestors) const; /** * Get a formatter. * @param executionContext The current execution context. * @return A new XalanNumberFormat instance. The caller owns the memory. */ XalanNumberFormat* getNumberFormatter(StylesheetExecutionContext& executionContext) const; /** * Format an array of integrals into a formatted string. * * @param executionContext The current execution context. * @param theList Array of one or more integer numbers. * @param theListLength The length of the array. * @param formattedNumber The formatted number result. */ void formatNumberList( StylesheetExecutionContext& executionContext, const CountType theList[], NodeRefListBase::size_type theListLength, XalanDOMString& formattedNumber) const; /** * Convert an intergral into alphabetic counting, in other words * count using the sequence A B C ... Z. * @param val Value to convert -- must be greater than zero. * @param table a table containing one character for each digit in the radix * @param theResult A string representing alpha count of number. * @see XSLTEngineImpl#DecimalToRoman * * Note that the radix of the conversion is inferred from the size * of the table. */ static void int2singlealphaCount( CountType val, const XalanDOMString& table, XalanDOMString& theResult); /** * Convert an integral into alphabetic counting, in other words * count using the sequence A B C ... Z AA AB AC.... etc. * @param val Value to convert -- must be greater than zero. * @param table a table containing one character for each digit in the radix * @param length the table length * @param result returns the stringrepresenting alpha count of number. * @see XSLTEngineImpl#DecimalToRoman * * Note that the radix of the conversion is inferred from the size * of the table. */ static void int2alphaCount( CountType val, const XalanDOMChar table[], XalanDOMString::size_type length, XalanDOMString& theResult); /** * Convert an integral into roman numerals. * @param val Value to convert. * @param prefixesAreOK true to enable prefix notation (e.g. 4 = "IV"), false to disable prefix notation (e.g. 4 = "IIII"). * @param theResult The formatted Roman numeral string. * @see DecimalToRoman * @see m_romanConvertTable */ static void toRoman( CountType val, bool prefixesAreOK, XalanDOMString& theResult); private: void evaluateLetterValueAVT( StylesheetExecutionContext& executionContext, XalanDOMString& value) const; void traditionalAlphaCount( CountType theValue, const XalanNumberingResourceBundle& theResourceBundle, XalanDOMString& theResult) const; /* * Get Formatted number */ void getFormattedNumber( StylesheetExecutionContext& executionContext, XalanDOMChar numberType, XalanDOMString::size_type numberWidth, CountType listElement, XalanDOMString& theResult) const; const XPath* m_countMatchPattern; const XPath* m_fromMatchPattern; const XPath* m_valueExpr; CountType m_level; // = Constants.NUMBERLEVEL_SINGLE; const AVT* m_format_avt; const AVT* m_lang_avt; const AVT* m_lettervalue_avt; const AVT* m_groupingSeparator_avt; const AVT* m_groupingSize_avt; const unsigned long m_id; /** * The string "@". */ static const XalanDOMChar s_atString[]; /** * The string "text()". */ static const XalanDOMString& s_textString; /** * The string "comment()". */ static const XalanDOMString& s_commentString; /** * The string "/". */ static const XalanDOMString& s_slashString; /** * The string "processing-instruction(". */ static const XalanDOMChar s_piString[]; /** * The string "level". */ static const XalanDOMChar s_levelString[]; /** * The string "multiple". */ static const XalanDOMChar s_multipleString[]; /** * The string "any". */ static const XalanDOMChar s_anyString[]; /** * The string "single". */ static const XalanDOMChar s_singleString[]; /** * The string "alphabetic". */ static const XalanDOMChar s_alphabeticString[]; /** * The string "traditional". */ static const XalanDOMChar s_traditionalString[]; /** * The string "#error". */ static const XalanDOMChar s_errorString[]; /** * Chars for converting integers into alpha counts. */ static const XalanDOMChar s_alphaCountTable[]; static const XalanDOMString::size_type s_alphaCountTableSize; static const XalanDOMChar s_elalphaCountTable[]; static const XalanDOMString::size_type s_elalphaCountTableSize; /** * Table to help in converting decimals to roman numerals. * @see XSLTEngineImpl#DecimalToRoman * @see XSLTEngineImpl#long2roman */ static const DecimalToRoman s_romanConvertTable[]; static const size_t s_romanConvertTableSize; /** * numbering resource bundle for Greek numbering. */ static const XalanNumberingResourceBundle& s_elalphaResourceBundle; public: /** * This class returns tokens using non-alphanumberic characters as * delimiters. */ class NumberFormatStringTokenizer { public: typedef XalanDOMString::size_type size_type; /** * Construct a NumberFormatStringTokenizer. * * @param theString string to tokenize */ NumberFormatStringTokenizer(const XalanDOMString& theString); /** * Sets the string to tokenize. * * @param theString new string to tokenize */ void setString(const XalanDOMString& theString); /** * Reset tokenizer so that nextToken() starts from the beginning. */ void reset() { m_currentPosition = 0; } /** * Retrieve the next token to be parsed. * * @param theToken The next token string */ void nextToken(XalanDOMString& theToken); /** * Determine if there are tokens remaining * * @return true if there are more tokens */ bool hasMoreTokens() const { return m_currentPosition >= m_maxPosition ? false : true; } /** * Count the number of tokens yet to be parsed * * @return number of remaining tokens */ size_type countTokens() const; private: size_type m_currentPosition; size_type m_maxPosition; const XalanDOMString* m_string; }; private: }; } #endif // XALAN_ELEMNUMBER_HEADER_GUARD