001: /* Copyright (c) 2001 - 2007 TOPP - www.openplans.org. All rights reserved.
002: * This code is licensed under the GPL 2.0 license, availible at the root
003: * application directory.
004: */
005: package org.geoserver.ows.util;
006:
007: /**
008: * Xerces' <code>getEncodingName()</code> method of
009: * <code>org.apache.xerces.impl.XMLEntityManager</code>)
010: * returns an array with name of encoding scheme and endianness.
011: * I decided to create a separate class incapsulating encoding metadata.
012: * The may idea behind this is the fact that we will most probably need to
013: * save this info somewhere and use it later when writing the response.
014: * Beside that, using class makes related code more clear.
015: */
016: public class EncodingInfo {
017: /**
018: * This is a name of autodetected <em>encoding scheme</em> (not necessarily
019: * <em>charset</em>) which should be used to read XML declaration in order
020: * to determine actual data <em>charset</em>.
021: */
022: private String fEncoding = null;
023:
024: /**
025: * Contains info about detected byte order (or endian-ness) of the
026: * incoming data. <code>true</code> if order is big-endian,
027: * <code>false</code> for little-endian, and <code>null</code>
028: * if byte order is not relevant for this encoding scheme.
029: * This is a "three-state" switch (third is <code>null</code>),
030: * so it can't be just plain <code>boolean</code> type.
031: */
032: private Boolean fIsBigEndian = null;
033:
034: /**
035: * This is technically not a part of encoding metadata, but more
036: * like characteristic of the input XML document. Tells whether
037: * Byte Order Mark (BOM) was found while detecting encoding scheme.
038: */
039: private boolean fHasBOM;
040:
041: /**
042: * Non-arg constructor to use in a few cases when you need a blank
043: * instance of <code>EncodingInfo</code>. It cant' be used right
044: * after creation and should be populated first via either setters
045: * or specific charset detection methods.
046: *
047: * @param encoding Name of the autodetected encoding scheme.
048: *
049: * @param isBigEndian
050: *
051: * Detected byte order of the data. <code>true</code> if
052: * order is big-endian, <code>false</code> if little-endian,
053: * and <code>null</code> if byte order is not relevant for
054: * this encoding scheme.
055: */
056: public EncodingInfo() {
057: }
058:
059: /**
060: * Constructor that takes name of the encoding scheme and endianness
061: * - results of autodetection in <code>getEncodingName</code>.
062: * BOM is considered missing if object is constructed this way.
063: *
064: * @param encoding Name of the autodetected encoding scheme.
065: *
066: * @param isBigEndian
067: *
068: * Detected byte order of the data. <code>true</code> if
069: * order is big-endian, <code>false</code> if little-endian,
070: * and <code>null</code> if byte order is not relevant for
071: * this encoding scheme.
072: */
073: public EncodingInfo(String encoding, Boolean isBigEndian) {
074: fEncoding = encoding;
075: fIsBigEndian = isBigEndian;
076: fHasBOM = false;
077: }
078:
079: /**
080: * Constructor that takes name of the encoding scheme and endianness
081: * - results of autodetection in <code>getEncodingName()</code>.
082: * Also presence of Byte Order Mark should be specified explicitly.
083: *
084: * @param encoding Name of the autodetected encoding scheme.
085: *
086: * @param isBigEndian
087: *
088: * Detected byte order of the data. <code>true</code> if
089: * order is big-endian, <code>false</code> if little-endian,
090: * and <code>null</code> if byte order is not relevant for
091: * this encoding scheme.
092: *
093: * @param hasBOM <code>true</code> if BOM is present,
094: * <code>false</code> otherwise.
095: */
096: public EncodingInfo(String encoding, Boolean isBigEndian,
097: boolean hasBOM) {
098: fEncoding = encoding;
099: fIsBigEndian = isBigEndian;
100: fHasBOM = hasBOM;
101: }
102:
103: /**
104: * Returns current encoding scheme (or charset).
105: */
106: public String getEncoding() {
107: return fEncoding;
108: }
109:
110: /**
111: * Sets new value of stored encoding (charset?) name.
112: */
113: public void setEncoding(String encoding) {
114: fEncoding = encoding;
115: }
116:
117: /**
118: * Accessor for <code>fIsBigEndian</code>. Should we define a mutator too?
119: */
120: public Boolean isBigEndian() {
121: return fIsBigEndian;
122: }
123:
124: /**
125: * Accessor for <code>fHasBOM</code>. Imho mutator is not required.
126: */
127: public boolean hasBOM() {
128: return fHasBOM;
129: }
130:
131: /**
132: * Copies property values from another <code>EncodingInfo</code> instance.
133: * Strange enough, but sometimes such behavior is preferred to simple
134: * assignment or cloning. More specifically, this method is currently used
135: * (at least it was :) in <code>XmlCharsetDetector.getCharsetAwareReader</code>
136: * (other two ways simply don't work).
137: *
138: * @param encInfo source object which properties should be mirrored in this
139: * instance
140: */
141: public void copyFrom(EncodingInfo encInfo) {
142: fEncoding = encInfo.getEncoding();
143: fIsBigEndian = encInfo.isBigEndian();
144: fHasBOM = encInfo.hasBOM();
145: }
146:
147: /**
148: * Returns current state of this instance in human-readable form.
149: */
150: public String toString() {
151: StringBuffer sb = new StringBuffer();
152: sb.append((null == fEncoding) ? "[NULL]" : fEncoding);
153:
154: if (null != fIsBigEndian) {
155: sb.append((fIsBigEndian.booleanValue()) ? " BIG ENDIAN"
156: : " LITTLE ENDIAN");
157: }
158:
159: if (fHasBOM) {
160: sb.append(" with BOM");
161: }
162:
163: return sb.toString();
164: }
165: } // END class EncodingInfo
|