comparison software/eXist/mpdl-modules/src/org/exist/xquery/modules/mpdltext/InsertAtCharPos.java @ 6:2396a569e446

new functions: externalObjects, normalizer, Unicode2Betacode
author Josef Willenborg <jwillenborg@mpiwg-berlin.mpg.de>
date Tue, 08 Feb 2011 14:54:09 +0100
parents
children
comparison
equal deleted inserted replaced
5:94305c504178 6:2396a569e446
1 /*
2 * eXist Open Source Native XML Database: Extension module
3 * Copyright (C) 2008 Josef Willenborg
4 * jwillenborg@mpiwg-berlin.mpg.de
5 * http://www.mpiwg-berlin.mpg.de
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 *
21 * $Id: TextModule.java $
22 */
23 package org.exist.xquery.modules.mpdltext;
24
25 import org.exist.dom.QName;
26 import org.exist.xquery.BasicFunction;
27 import org.exist.xquery.Cardinality;
28 import org.exist.xquery.FunctionSignature;
29 import org.exist.xquery.XPathException;
30 import org.exist.xquery.XQueryContext;
31 import org.exist.xquery.value.Sequence;
32 import org.exist.xquery.value.SequenceType;
33 import org.exist.xquery.value.StringValue;
34 import org.exist.xquery.value.Type;
35 import org.exist.xquery.value.ValueSequence;
36
37 public class InsertAtCharPos extends BasicFunction {
38
39 public final static FunctionSignature signature =
40 new FunctionSignature(
41 new QName("insertAtCharPos", MPDLTextModule.NAMESPACE_URI, MPDLTextModule.PREFIX),
42 "A function which inserts in the xml element node string (first parameter) the given xml element " +
43 "node string (second parameter) at the given char position (third parameter).",
44 new SequenceType[] { new SequenceType(Type.STRING, Cardinality.EXACTLY_ONE),
45 new SequenceType(Type.STRING, Cardinality.EXACTLY_ONE),
46 new SequenceType(Type.INT, Cardinality.EXACTLY_ONE)
47 },
48 new SequenceType(Type.STRING, Cardinality.EXACTLY_ONE));
49
50 public InsertAtCharPos(XQueryContext context) {
51 super(context, signature);
52 }
53
54 public Sequence eval(Sequence[] args, Sequence contextSequence) throws XPathException {
55 Sequence elementInputStr = args[0];
56 Sequence insertElementStr = args[1];
57 Sequence charPosStr = args[2];
58 String elementInputStrStr = elementInputStr.getStringValue();
59 String insertElementStrStr = insertElementStr.getStringValue();
60 String charPosStrStr = charPosStr.getStringValue();
61 Integer charPos = new Integer(charPosStrStr);
62 int strCharIndex = getIndex(elementInputStrStr, charPos);
63 if (charPos == 0)
64 strCharIndex = getIndex(elementInputStrStr, charPos + 1) - 1;
65 String resultStr = elementInputStrStr.substring(0, strCharIndex) + insertElementStrStr + elementInputStrStr.substring(strCharIndex);
66 ValueSequence result = new ValueSequence();
67 result.add(new StringValue(resultStr));
68 return result;
69 }
70
71 private int getIndex(String xmlString, int charPos) {
72 int size = xmlString.length();
73 int counter = 0;
74 int charCounter = 0;
75 int counterLastChar = -1;
76 boolean isEntity = false;
77 boolean isElement = false;
78 while (counter < size) {
79 char c = xmlString.charAt(counter);
80 switch (c) {
81 case '<': isElement = true; break;
82 case '>': isElement = false; break;
83 case '&': isEntity = true; break;
84 case ';': isEntity = false; break;
85 }
86 // count all chars which are not inside elements and entities
87 // if element closing char ">" is found it should not be counted as a char
88 // if an entity closing char ";" is found it should be counted cause the entity itself is one char long
89 if (! isEntity && ! isElement && !(c == '>')) {
90 charCounter++;
91 counterLastChar = counter;
92 }
93 if (charCounter == charPos) {
94 break;
95 }
96 counter++;
97 }
98 // input charPos was bigger than available chars: return the last available charPos
99 if (counter == size)
100 return counterLastChar + 1;
101 return counter + 1;
102 }
103 }