Literal.java
001 /*
002  *  Literal.java
003  *
004  *  Niraj Aswani, 09/March/07
005  *
006  *  $Id: Literal.html,v 1.0 2007/03/09 16:13:01 niraj Exp $
007  */
008 package gate.creole.ontology;
009 
010 import java.util.Locale;
011 
012 /**
013  * The class Literal represents a literal value as defined in section 6.5 of 
014  * http://www.w3.org/TR/rdf-concepts . 
015  * A literal value consists of a lexical form which is represented
016  * as a unicode string and in addition optionally either a language 
017  * tag or a datatype.
018  
019  @author Niraj Aswani, Johann Petrak
020  */
021 
022 // NOTE: (Johann Petrak) This may need to get extended in the future to 
023 // also deal with the rdf:PlainLiteral datatype and the different
024 // way of how literals of that type are represented.
025 // See http://www.w3.org/TR/rdf-plain-literal/
026 
027 public class Literal {
028   /**
029    * The actual value (the lexical form) of the literal, represented 
030    * as a unicode string.
031    */
032   private String value;
033 
034   /**
035    * The language tag for the literal if it is a plain literal. If there is
036    * a language tag, there cannot be a data type.
037    */
038   private Locale language;
039 
040   /**
041    * The data type of the literal if it is a typed literal. If there is 
042    * a data type, there cannot be a language tag. 
043    * Data types are represented as gate.creole.ontology.DataType objects
044    * but the only information that is used internally is the datatype 
045    * URI String (as returned by DataType.getXmlSchemaURIString())
046    */
047   private DataType dataType;
048 
049   /**
050    * Create a plain literal (i.e an untyped literal) without a language tag
051    * (the language is null).
052    * A plain literal cannot have a data type (the datatype will always be null).
053    */
054   public Literal(String value) {
055     this.value = value;
056     // removed by JP: a plain literal does not have a language tag nor
057     // a datatype.
058     //this.language = OConstants.ENGLISH;
059     //this.dataType = DataType.getStringDataType();
060     this.language = null;
061     this.dataType = null;
062   }
063 
064   /**
065    * Create a plain literal (i.e. an untyped literal) with a language
066    * tag that corresponds to the string returned by language.getLanguage().
067    * Any information stored in the Java Locale object other than the
068    * language code is ignored and discarded when stored in the ontology.
069    * A plain literal cannot have a data type (the datatype will alwats be null).
070    
071    @param value 
072    @param language
073    @deprecated Use the constructor Literal(String value, String languagetag) 
074    * instead
075    */
076   @Deprecated
077   public Literal(String value, Locale language) {
078     this.value = value;
079     this.language = language;
080     // removed by JP: a plain literal with a language tag must
081     // not have a datatype
082     // this.dataType = DataType.getStringDataType(); 
083     this.dataType = null;
084   }
085 
086   /**
087    * Create a plain literal associated with a language tag. A language tag
088    * should be an official two-character lowercase language code.
089    
090    @param value
091    @param languagetag 
092    */
093   public Literal(String value, String languagetag) {
094     this.value = value;
095     this.language = new Locale(languagetag);
096     this.dataType = null;
097   }
098   
099   
100   /**
101    * Create a typed literal. A typed literal is associated with a datatype
102    * and cannot have a language tag (the language will always be null).
103    
104    @param value 
105    @param dataType
106    @throws InvalidValueException
107    */
108   public Literal(String value, DataType dataTypethrows InvalidValueException {
109     this.value = value;
110     // removed by JP: a typed literal must not have a language tag
111     // this.language = OConstants.ENGLISH;
112     this.language = null;
113     this.dataType = dataType;
114     // lets check if the provided val is valid for the supplied
115     // dataType
116     if(!dataType.isValidValue(this.value)) {
117       throw new InvalidValueException("The value :\"" this.value
118               "\" is not compatible with the dataType \""
119               + dataType.getXmlSchemaURIString() "\"");
120     }
121   }
122 
123   /**
124    * Gets the datatype of the literal. This will return null for all plain
125    * literals (i.e. literals that are not associated with a data type).
126    */
127   public DataType getDataType() {
128     return dataType;
129   }
130 
131   /**
132    * Returns the value (lexical form) associated with this instance of literal.
133    */
134   public String getValue() {
135     return value;
136   }
137 
138   /**
139    * Returns the language associated with this literal represented as a 
140    * Locale object. Note that the only useful information in the Locale
141    * object is the language code which can be retrieved with the 
142    * getLanguage() method of the Locale object.
143    @deprecated Use the method getLanguageTag() instead.
144    */
145   @Deprecated
146   public Locale getLanguage() {
147     return language;
148   }
149 
150   /**
151    * The language tag of the literal as a two-character lowercase language code
152    * or null if no language tag
153    * is associated. This always returns null for typed literals (literals
154    * associated with a data type).
155    
156    @return the language tag as String
157    */
158   public String getLanguageTag() {
159     if(language == null) {
160       return null;
161     else {
162       return language.getLanguage();
163     }
164   }
165   
166   
167   /**
168    * This method always returns the string representation of the 
169    * literal value in the same way as getValue().
170    * For a representation that also includes the language tag or 
171    * data type, use toTurtle().
172    
173    @return The value of the literal as String, identical to getValue()
174    */
175   @Override
176   public String toString() {
177     return value;
178   }
179 
180 
181   /**
182    * The representation of the literal in Turtle language
183    * (see http://www.w3.org/TeamSubmission/turtle/)
184    * Note that datatype URIs for typed literals 
185    * will always be represented as full URIs
186    * and not use the xsd namespace.
187    
188    @return A String that contains the representation of the literal 
189    * in Turtle language 
190    */
191   public String toTurtle() {
192     String val = this.value;
193     val = val.replace("\"""\\\"");
194     val = "\""+val+"\"";
195     if(dataType == null) {
196       if(language != null) {
197         val = val+"@"+language;
198       
199     else {
200       val = val+"^^<" + dataType.getXmlSchemaURIString() ">";
201     }
202     return val;
203   }
204 
205   @Override
206   public int hashCode() {
207     int hash = 17 (value == null : value.hashCode());
208     hash = 37*hash + (language == null :  language.hashCode());
209     hash = 37*hash + (dataType == null : dataType.hashCode());
210     return hash;
211   }
212 
213   @Override
214   /**
215    * Two literals are considered equal if the strings representing their
216    * values are equal and if they have identical language tags or 
217    * identical data types or both do not have either a language tag or
218    * a data type.
219    */
220   public boolean equals(Object obj) {
221     if (obj == null) {
222       return false;
223     }
224     if (getClass() != obj.getClass()) {
225       return false;
226     }
227     final Literal other = (Literalobj;
228     // if both are Literals, they are only equal if the dataTypes are the same
229     // and if the languages are the same and if the values are the same
230     if ((this.value == null&& (other.value == null)) {
231       return true;
232     }
233     if(!(this.dataType == null ?
234           other.dataType == null this.dataType.equals(other.dataType)) ||
235        !(this.language == null ?
236           other.language == null this.language.equals(other.language)) ||
237        !(this.value == null ?
238           other.value == null this.value.equals(other.value))) {
239       return false;
240     }
241     return true;
242   }
243 
244 }