001: /*
002: * (c) Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 Hewlett-Packard Development Company, LP
003: * All rights reserved.
004: *
005: * Redistribution and use in source and binary forms, with or without
006: * modification, are permitted provided that the following conditions
007: * are met:
008: * 1. Redistributions of source code must retain the above copyright
009: * notice, this list of conditions and the following disclaimer.
010: * 2. Redistributions in binary form must reproduce the above copyright
011: * notice, this list of conditions and the following disclaimer in the
012: * documentation and/or other materials provided with the distribution.
013: * 3. The name of the author may not be used to endorse or promote products
014: * derived from this software without specific prior written permission.
015:
016: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
017: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
018: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
019: * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
020: * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
021: * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
022: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
023: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
024: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
025: * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
026: *
027: * LiteralImpl.java
028: *
029: * Created on 03 August 2000, 14:42
030: */
031:
032: package com.hp.hpl.jena.rdf.model.impl;
033:
034: import com.hp.hpl.jena.rdf.model.*;
035: import com.hp.hpl.jena.graph.*;
036: import com.hp.hpl.jena.shared.*;
037:
038: import com.hp.hpl.jena.datatypes.DatatypeFormatException;
039: import com.hp.hpl.jena.datatypes.RDFDatatype;
040: import com.hp.hpl.jena.datatypes.xsd.XSDDatatype;
041: import com.hp.hpl.jena.enhanced.*;
042:
043: /** An implementation of Literal.
044: *
045: * @author bwm and der
046: * @version Release='$Name: $' Revision='$Revision: 1.27 $' Date='$Date: 2008/01/02 12:05:01 $'
047: */
048: public class LiteralImpl extends EnhNode implements Literal {
049:
050: final static public Implementation factory = new Implementation() {
051: public boolean canWrap(Node n, EnhGraph eg) {
052: return n.isLiteral();
053: }
054:
055: public EnhNode wrap(Node n, EnhGraph eg) {
056: if (!n.isLiteral())
057: throw new LiteralRequiredException(n);
058: return new LiteralImpl(n, eg);
059: }
060: };
061:
062: public LiteralImpl(Node n, ModelCom m) {
063: super (n, m);
064: }
065:
066: public LiteralImpl(Node n, EnhGraph m) {
067: super (n, m);
068: }
069:
070: public Object visitWith(RDFVisitor rv) {
071: return rv.visitLiteral(this );
072: }
073:
074: /**
075: Literals are not in any particular model, and so inModel can return this.
076: @param m a model to move the literal into
077: @return this
078: */
079: public RDFNode inModel(Model m) {
080: return this ;
081: }
082:
083: /**
084: *@deprecated Please use the createLiteral methods on Model.
085: *Model implementors should use Literal instructors which include the Model.
086: */
087: public LiteralImpl(boolean b) {
088: this (String.valueOf(b));
089: }
090:
091: /**
092: *@deprecated Please use the createLiteral methods on Model.
093: *Model implementors should use Literal instructors which include the Model.
094: */
095: public LiteralImpl(long l) {
096: this (String.valueOf(l));
097: }
098:
099: /**
100: *@deprecated Please use the createLiteral methods on Model.
101: *Model implementors should use Literal instructors which include the Model.
102: */
103: public LiteralImpl(char c) {
104: this (String.valueOf(c));
105: }
106:
107: /**
108: *@deprecated Please use the createLiteral methods on Model.
109: *Model implementors should use Literal instructors which include the Model.
110: */
111: public LiteralImpl(float f) {
112: this (String.valueOf(f));
113: }
114:
115: /**
116: *@deprecated Please use the createLiteral methods on Model.
117: *Model implementors should use Literal instructors which include the Model.
118: */
119: public LiteralImpl(double d) {
120: this (String.valueOf(d));
121: }
122:
123: /**
124: *@deprecated Please use the createLiteral methods on Model.
125: *Model implementors should use Literal instructors which include the Model.
126: */
127: public LiteralImpl(String s) {
128: this (s, "");
129: }
130:
131: /**
132: *@deprecated Please use the createLiteral methods on Model.
133: *Model implementors should use Literal instructors which include the Model.
134: */
135: public LiteralImpl(String s, String l) {
136: this (s, l, false);
137: }
138:
139: /**
140: *@deprecated Please use the createLiteral methods on Model.
141: *Model implementors should use Literal instructors which include the Model.
142: */
143: public LiteralImpl(String s, boolean wellFormed) {
144: this (s, "", wellFormed);
145: }
146:
147: /**
148: *@deprecated Please use the createLiteral methods on Model.
149: *Model implementors should use Literal instructors which include the Model.
150: */
151: public LiteralImpl(String s, String l, boolean wellFormed) {
152: this (s, l, wellFormed, null);
153: }
154:
155: /**
156: *@deprecated Please use the createLiteral methods on Model.
157: *Model implementors should use Literal instructors which include the Model.
158: */
159: public LiteralImpl(String s, String l, boolean wellFormed,
160: ModelCom m) {
161: this (Node.createLiteral(s, l, wellFormed), m);
162: }
163:
164: /**
165: *@deprecated Please use the createLiteral methods on Model.
166: *Model implementors should use Literal instructors which include the Model.
167: */
168: public LiteralImpl(Object o) {
169: this (o.toString());
170: }
171:
172: public String toString() {
173: return asNode().toString(PrefixMapping.Standard, false);
174: }
175:
176: /**
177: * Return the value of the literal. In the case of plain literals
178: * this will return the literal string. In the case of typed literals
179: * it will return a java object representing the value. In the case
180: * of typed literals representing a java primitive then the appropriate
181: * java wrapper class (Integer etc) will be returned.
182: */
183: public Object getValue() {
184: return asNode().getLiteralValue();
185: }
186:
187: /**
188: * Return the datatype of the literal. This will be null in the
189: * case of plain literals.
190: */
191: public RDFDatatype getDatatype() {
192: return asNode().getLiteralDatatype();
193: }
194:
195: /**
196: * Return the uri of the datatype of the literal. This will be null in the
197: * case of plain literals.
198: */
199: public String getDatatypeURI() {
200: return asNode().getLiteralDatatypeURI();
201: }
202:
203: /**
204: * Return true if this is a "plain" (i.e. old style, not typed) literal.
205: */
206: public boolean isPlainLiteral() {
207: return asNode().getLiteralDatatype() == null;
208: }
209:
210: /**
211: * Return the lexical form of the literal.
212: */
213: public String getLexicalForm() {
214: return asNode().getLiteralLexicalForm();
215: }
216:
217: public boolean getBoolean() {
218: Object value = asNode().getLiteralValue();
219: if (isPlainLiteral()) {
220: // old style plain literal - try parsing the string
221: if (value.equals("true")) {
222: return true;
223: } else if (value.equals("false")) {
224: return false;
225: } else {
226: throw new BadBooleanException(value.toString());
227: }
228: } else {
229: // typed literal
230: if (value instanceof Boolean) {
231: return ((Boolean) value).booleanValue();
232: } else {
233: throw new DatatypeFormatException(this .toString()
234: + " is not a Boolean");
235: }
236: }
237: }
238:
239: public byte getByte() {
240: if (isPlainLiteral()) {
241: return Byte.parseByte(getLexicalForm());
242: } else {
243: return byteValue(asNumber(getValue()));
244: }
245: }
246:
247: public short getShort() {
248: if (isPlainLiteral()) {
249: return Short.parseShort(getLexicalForm());
250: } else {
251: return shortValue(asNumber(getValue()));
252: }
253: }
254:
255: public int getInt() {
256: if (isPlainLiteral()) {
257: return Integer.parseInt(getLexicalForm());
258: } else {
259: return intValue(asNumber(getValue()));
260: }
261: }
262:
263: public long getLong() {
264: if (isPlainLiteral()) {
265: return Long.parseLong(getLexicalForm());
266: } else {
267: return asNumber(getValue()).longValue();
268: }
269: }
270:
271: public char getChar() {
272: if (isPlainLiteral()) {
273: if (getString().length() == 1) {
274: return (getString().charAt(0));
275: } else {
276: throw new BadCharLiteralException(getString());
277: }
278: } else {
279: Object value = getValue();
280: if (value instanceof Character) {
281: return ((Character) value).charValue();
282: } else {
283: throw new DatatypeFormatException(value.toString()
284: + " is not a Character");
285: }
286: }
287: }
288:
289: public float getFloat() {
290: if (isPlainLiteral()) {
291: return Float.parseFloat(getLexicalForm());
292: } else {
293: return asNumber(getValue()).floatValue();
294: }
295: }
296:
297: public double getDouble() {
298: if (isPlainLiteral()) {
299: return Double.parseDouble(getLexicalForm());
300: } else {
301: return asNumber(getValue()).doubleValue();
302: }
303: }
304:
305: public String getString() {
306: return asNode().getLiteralLexicalForm();
307: }
308:
309: public Object getObject(ObjectF f) {
310: if (isPlainLiteral()) {
311: try {
312: return f.createObject(getString());
313: } catch (Exception e) {
314: throw new JenaException(e);
315: }
316: } else {
317: return getValue();
318: }
319: }
320:
321: public String getLanguage() {
322: return asNode().getLiteralLanguage();
323: }
324:
325: public boolean getWellFormed() {
326: return isWellFormedXML();
327: }
328:
329: public boolean isWellFormedXML() {
330: return asNode().getLiteralIsXML();
331: }
332:
333: /**
334: * Test that two literals are semantically equivalent.
335: * In some cases this may be the sames as equals, in others
336: * equals is stricter. For example, two xsd:int literals with
337: * the same value but different language tag are semantically
338: * equivalent but distinguished by the java equality function
339: * in order to support round tripping.
340: */
341: public boolean sameValueAs(Literal other) {
342: return asNode().sameValueAs(other.asNode());
343: }
344:
345: // Internal helper method to convert a value to number
346: private Number asNumber(Object value) {
347: if (value instanceof Number) {
348: return ((Number) value);
349: } else {
350: String message = "Error converting typed value to a number. \n";
351: message += "Datatype is: " + getDatatypeURI();
352: if (getDatatypeURI() == null
353: || !getDatatypeURI().startsWith(XSDDatatype.XSD)) {
354: message += " which is not an xsd type.";
355: }
356: message += " \n";
357: String type = message += "Java representation type is "
358: + (value == null ? "null" : value.getClass()
359: .toString());
360: throw new DatatypeFormatException(message);
361: }
362: }
363:
364: private byte byteValue(Number n) {
365: return (byte) getIntegralValueInRange(Byte.MIN_VALUE, n,
366: Byte.MAX_VALUE);
367: }
368:
369: private short shortValue(Number n) {
370: return (short) getIntegralValueInRange(Short.MIN_VALUE, n,
371: Short.MAX_VALUE);
372: }
373:
374: private int intValue(Number n) {
375: return (int) getIntegralValueInRange(Integer.MIN_VALUE, n,
376: Integer.MAX_VALUE);
377: }
378:
379: private long getIntegralValueInRange(long min, Number n, long max) {
380: long result = n.longValue();
381: if (min <= result && result <= max)
382: return result;
383: throw new IllegalArgumentException("byte value required: "
384: + result);
385: }
386:
387: }
|