| /* |
| * 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. |
| */ |
| |
| #include <xalanc/Include/PlatformDefinitions.hpp> |
| |
| |
| |
| #include <cmath> |
| #include <cstring> |
| #include <ctime> |
| #include <iostream> |
| |
| |
| |
| #include <xercesc/util/PlatformUtils.hpp> |
| |
| |
| |
| #include <xalanc/XalanTransformer/XalanTransformer.hpp> |
| |
| |
| |
| #include <xalanc/XPath/Function.hpp> |
| #include <xalanc/XPath/XObjectFactory.hpp> |
| |
| |
| |
| using xalanc::Function; |
| using xalanc::Locator; |
| using xalanc::XPathExecutionContext; |
| using xalanc::XalanDOMString; |
| using xalanc::XalanNode; |
| using xalanc::XObjectPtr; |
| using xalanc::MemoryManager; |
| using xalanc::XalanCopyConstruct; |
| |
| // This class defines a function that will return the square root |
| // of its argument. |
| class FunctionSquareRoot : public Function |
| { |
| public: |
| |
| /** |
| * Execute an XPath function object. The function must return a valid |
| * object. Extension functions should override this version of execute(), |
| * rather than one of the other calls designed for a specific number of |
| * arguments. |
| * |
| * @param executionContext executing context |
| * @param context current context node |
| * @param args vector of pointers to XObject arguments |
| * @param locator Locator for the XPath expression that contains the function call |
| * @return pointer to the result XObject |
| */ |
| virtual XObjectPtr |
| execute( |
| XPathExecutionContext& executionContext, |
| XalanNode* context, |
| const XObjectArgVectorType& args, |
| const Locator* locator) const |
| { |
| if (args.size() != 1) |
| { |
| XPathExecutionContext::GetAndReleaseCachedString theGuard(executionContext); |
| |
| generalError(executionContext, context, locator); |
| } |
| |
| assert(args[0].null() == false); |
| |
| using std::sqrt; |
| #endif |
| |
| return executionContext.getXObjectFactory().createNumber(sqrt(args[0]->num(executionContext))); |
| } |
| |
| using Function::execute; |
| |
| /** |
| * Create a copy of the function object. |
| * |
| * @return pointer to the new object |
| */ |
| #if defined(XALAN_NO_COVARIANT_RETURN_TYPE) |
| virtual Function* |
| #else |
| virtual FunctionSquareRoot* |
| #endif |
| clone(MemoryManager& theManager) const |
| { |
| return XalanCopyConstruct(theManager, *this); |
| } |
| |
| protected: |
| |
| /** |
| * Get the error message to report when |
| * the function is called with the wrong |
| * number of arguments. |
| * |
| * @return function error message |
| */ |
| const XalanDOMString& |
| getError(XalanDOMString& theResult) const |
| { |
| theResult.assign("The square-root() function accepts one argument!"); |
| |
| return theResult; |
| } |
| |
| private: |
| |
| // Not implemented... |
| FunctionSquareRoot& |
| operator=(const FunctionSquareRoot&); |
| |
| bool |
| operator==(const FunctionSquareRoot&) const; |
| }; |
| |
| |
| |
| // This class defines a function that will return the cube |
| // of its argument. |
| class FunctionCube : public Function |
| { |
| public: |
| |
| /** |
| * Execute an XPath function object. The function must return a valid |
| * object. Extension functions should override this version of execute(), |
| * rather than one of the other calls designed for a specific number of |
| * arguments. |
| * |
| * @param executionContext executing context |
| * @param context current context node |
| * @param args vector of pointers to XObject arguments |
| * @param locator Locator for the XPath expression that contains the function call |
| * @return pointer to the result XObject |
| */ |
| virtual XObjectPtr |
| execute( |
| XPathExecutionContext& executionContext, |
| XalanNode* context, |
| const XObjectArgVectorType& args, |
| const Locator* locator) const |
| { |
| if (args.size() != 1) |
| { |
| XPathExecutionContext::GetAndReleaseCachedString theGuard(executionContext); |
| |
| generalError(executionContext, context, locator); |
| } |
| |
| assert(args[0].null() == false); |
| |
| using std::pow; |
| |
| return executionContext.getXObjectFactory().createNumber(pow(args[0]->num(executionContext), 3)); |
| } |
| |
| using Function::execute; |
| |
| /** |
| * Create a copy of the function object. |
| * |
| * @return pointer to the new object |
| */ |
| #if defined(XALAN_NO_COVARIANT_RETURN_TYPE) |
| virtual Function* |
| #else |
| virtual FunctionCube* |
| #endif |
| clone(MemoryManager& theManager) const |
| { |
| return XalanCopyConstruct(theManager, *this); |
| } |
| |
| protected: |
| |
| /** |
| * Get the error message to report when |
| * the function is called with the wrong |
| * number of arguments. |
| * |
| * @return function error message |
| */ |
| const XalanDOMString& |
| getError(XalanDOMString& theResult) const |
| { |
| theResult.assign("The cube() function accepts one argument!"); |
| |
| return theResult; |
| } |
| |
| private: |
| |
| // Not implemented... |
| FunctionCube& |
| operator=(const FunctionCube&); |
| |
| bool |
| operator==(const FunctionCube&) const; |
| }; |
| |
| |
| |
| // This class defines a function that runs the C function |
| // asctime() using the current system time. |
| class FunctionAsctime : public Function |
| { |
| public: |
| |
| /** |
| * Execute an XPath function object. The function must return a valid |
| * object. Extension functions should override this version of execute(), |
| * rather than one of the other calls designed for a specific number of |
| * arguments. |
| * |
| * @param executionContext executing context |
| * @param context current context node |
| * @param args vector of pointers to XObject arguments |
| * @param locator Locator for the XPath expression that contains the function call |
| * @return pointer to the result XObject |
| */ |
| virtual XObjectPtr |
| execute( |
| XPathExecutionContext& executionContext, |
| XalanNode* context, |
| const XObjectArgVectorType& args, |
| const Locator* locator) const |
| { |
| if (args.empty() == false) |
| { |
| generalError(executionContext, context, locator); |
| } |
| |
| using std::time; |
| using std::time_t; |
| using std::localtime; |
| using std::asctime; |
| using std::strlen; |
| |
| time_t theTime; |
| |
| time(&theTime); |
| |
| char* const theTimeString = asctime(localtime(&theTime)); |
| assert(theTimeString != 0); |
| |
| // The resulting string has a newline character at the end, |
| // so get rid of it. |
| theTimeString[strlen(theTimeString) - 1] = '\0'; |
| |
| return executionContext.getXObjectFactory().createString(XalanDOMString(theTimeString)); |
| } |
| |
| using Function::execute; |
| |
| /** |
| * Create a copy of the function object. |
| * |
| * @return pointer to the new object |
| */ |
| #if defined(XALAN_NO_COVARIANT_RETURN_TYPE) |
| virtual Function* |
| #else |
| virtual FunctionAsctime* |
| #endif |
| clone(MemoryManager& theManager) const |
| { |
| return XalanCopyConstruct(theManager, *this); |
| } |
| |
| protected: |
| |
| /** |
| * Get the error message to report when |
| * the function is called with the wrong |
| * number of arguments. |
| * |
| * @return function error message |
| */ |
| const XalanDOMString& |
| getError(XalanDOMString& theResult) const |
| { |
| theResult.assign("The asctime() function accepts one argument!"); |
| |
| return theResult; |
| } |
| |
| private: |
| |
| // Not implemented... |
| FunctionAsctime& |
| operator=(const FunctionAsctime&); |
| |
| bool |
| operator==(const FunctionAsctime&) const; |
| }; |
| |
| |
| |
| int |
| main( |
| int argc, |
| char* /* argv */[]) |
| { |
| using std::cerr; |
| using std::endl; |
| |
| int theResult = 0; |
| |
| if (argc != 1) |
| { |
| cerr << "Usage: ExternalFunction" |
| << endl |
| << endl; |
| } |
| else |
| { |
| using xercesc::XMLPlatformUtils; |
| using xercesc::XMLException; |
| |
| using xalanc::XalanTransformer; |
| |
| // Call the static initializer for Xerces. |
| try |
| { |
| XMLPlatformUtils::Initialize(); |
| } |
| catch (const XMLException& toCatch) |
| { |
| cerr << "Error during Xerces initialization. Error code was " |
| << toCatch.getCode() |
| << "." |
| << endl; |
| |
| theResult = -1; |
| } |
| |
| if (theResult == 0) |
| { |
| // Initialize Xalan. |
| XalanTransformer::initialize(); |
| |
| { |
| // Create a XalanTransformer. |
| XalanTransformer theXalanTransformer; |
| |
| // The namespace for our functions... |
| const XalanDOMString theNamespace("http://ExternalFunction.xalan-c++.xml.apache.org"); |
| |
| // Install the functions in the local space. They will only |
| // be installed in this instance, so no other instances |
| // will know about them... |
| theXalanTransformer.installExternalFunction( |
| theNamespace, |
| XalanDOMString("asctime"), |
| FunctionAsctime()); |
| |
| theXalanTransformer.installExternalFunction( |
| theNamespace, |
| XalanDOMString("square-root"), |
| FunctionSquareRoot()); |
| |
| theXalanTransformer.installExternalFunction( |
| theNamespace, |
| XalanDOMString("cube"), |
| FunctionCube()); |
| |
| // Do the transform. |
| theResult = theXalanTransformer.transform("foo.xml", "foo.xsl", "foo.out"); |
| |
| if(theResult != 0) |
| { |
| cerr << "ExternalFunction Error: \n" << theXalanTransformer.getLastError() |
| << endl |
| << endl; |
| } |
| } |
| |
| // Terminate Xalan... |
| XalanTransformer::terminate(); |
| } |
| |
| // Terminate Xerces... |
| XMLPlatformUtils::Terminate(); |
| |
| // Clean up the ICU, if it's integrated... |
| XalanTransformer::ICUCleanUp(); |
| } |
| |
| return theResult; |
| } |