/[webpac]/trunk2/openisis/org/openisis/Field.java
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Annotation of /trunk2/openisis/org/openisis/Field.java

Parent Directory Parent Directory | Revision Log Revision Log


Revision 237 - (hide annotations)
Mon Mar 8 17:43:12 2004 UTC (20 years, 2 months ago) by dpavlin
Original Path: openisis/current/org/openisis/Field.java
File size: 7789 byte(s)
initial import of openisis 0.9.0 vendor drop

1 dpavlin 237 /*
2     openisis - an open implementation of the CDS/ISIS database
3     Version 0.8.x (patchlevel see file Version)
4     Copyright (C) 2001-2003 by Erik Grziwotz, erik@openisis.org
5    
6     This library is free software; you can redistribute it and/or
7     modify it under the terms of the GNU Lesser General Public
8     License as published by the Free Software Foundation; either
9     version 2.1 of the License, or (at your option) any later version.
10    
11     This library is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14     Lesser General Public License for more details.
15    
16     You should have received a copy of the GNU Lesser General Public
17     License along with this library; if not, write to the Free Software
18     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19    
20     see README for more information
21     EOH */
22    
23    
24     package org.openisis;
25    
26     import java.util.StringTokenizer; // split
27    
28    
29     /**
30     Field implementation of openisis java binding.
31     A Field is an immutable structure, binding a String value to a tag.
32     It provides methods for formatted access to the value.
33     <p>
34     $Id: Field.java,v 1.5 2003/04/08 00:20:53 kripke Exp $
35     @version $Revision: 1.5 $
36     @author $Author: kripke $
37     */
38     public class Field {
39    
40    
41     /**
42     what a single field can contribute to the V operator.
43     @param b a StringBuffer to append to
44     @param mode OR-combination of the field formatting flags
45     defined in Db and an optional subfield character.
46     @param plain a String to format
47     @param len a 16bit length constraint | offset &lt;&lt; 16
48     @return false iff a non-existing subfield was requested, else true
49     */
50     public static boolean v ( StringBuffer b, int mode, String plain, int len ) {
51     if ( 0 != (Db.MXU & mode) ) // won't change any specials
52     plain = plain.toUpperCase();
53     final char[] c = plain.toCharArray();
54     final int cl=c.length;
55     char sub = (char)mode;
56     int o=0, e=cl;
57     if ( 0 != sub ) {
58     if ( '*' == sub ) { // first subfield
59     if ( e > 1 && '^' == c[0] )
60     o = 2;
61     } else {
62     if ( 0 != (Db.MXU & mode) ) // oops - upcased subfield marks ...
63     sub = Character.toUpperCase(sub);
64     for (;;) {
65     if ( cl == o ) return false; // no subfield
66     if ( '^' != c[o++] ) continue;
67     if ( cl == o ) return false; // no subfield
68     if ( sub == c[o++] ) break;
69     }
70     }
71     // got sub starting at o
72     e = o;
73     while ( cl > e && '^' != c[e] )
74     e++;
75     }
76     // now the relevant data is at offset o and ends at e
77     if ( 0 != len ) {
78     int off = len >>> 16;
79     len |= 0xffff;
80     o += off;
81     if ( 0 != len && e > o+len )
82     e = o+len;
83     }
84     if ( e <= o )
85     return true; // existing but empty
86     boolean mh = Db.MHL == (Db.MHL & mode);
87     boolean mi = Db.MI == (Db.MI & mode);
88     boolean ht = Db.HTU == (Db.HTU & mode);
89     boolean ab = false; // inside angel brackets: stop at =
90     if ( ! (mh || ht) ) {
91     b.append( c, o, e-o );
92     return true;
93     }
94     final char htlim = // chars > htlim are escaped
95     ( Db.HTA == (Db.HTA & mode) ) ? 127 :
96     ( Db.HTI == (Db.HTI & mode) ) ? 255 :
97     Character.MAX_VALUE;
98     int i=o;
99     char x = 0;
100     // now we run at least one of mh or ht mode replacements
101     LOOP: for (;;i++) {
102     if ( i < e && htlim >= (x = c[i]) )
103     switch ( x ) {
104     case '"': case '&': if ( ht ) break; continue;
105     case '^': if ( mh ) break; continue;
106     case '=': if ( ab ) break; continue;
107     case '<': case '>': break; // special in any case
108     default: continue;
109     }
110     if ( i > o ) // flush what we had up to current position
111     b.append( c, o, i-o );
112     if ( i == e ) // done
113     break;
114     o = i+1; // new offset after this
115     if ( htlim < x ) { // write decimal value
116     b.append( "&#" ).append( (int)x ).append( ';' );
117     continue;
118     }
119     // now we have one of the special chars
120     switch ( x ) {
121     case '"': b.append( "&quot;" ); continue; // ht
122     case '&': b.append( "&amp;" ); continue; // ht
123     case '^': // mh
124     if ( i+1 < e ) {
125     x = Character.toUpperCase( c[++i] );
126     if ( 1 < o ) // not on beginning of field
127     b.append( ('A' == x) ? ';' : ('A'<x && x<'J') ? ',' : '.' )
128     .append( ' ' );
129     }
130     o = i+1;
131     continue;
132     case '=': // angel brackets -- skip to >
133     while ( '>' != c[i] ) if ( e == ++i ) break LOOP; // ran to end
134     o = i+1;
135     // don't break, go on checking for ><-pair
136     case '>':
137     ab = false;
138     if ( ! mh )
139     b.append( "&gt;" );
140     else if ( i+1<e && '<' == c[i+1] )
141     b.append( "; " );
142     continue;
143     case '<':
144     if ( ! mh ) { b.append( "&lt;" ); continue; } // ht
145     if ( ! mi ) { ab = true; continue; } // non-index mh
146     // index mode -- skip to = or >
147     while ( '>' != c[i] && '=' != c[i] )
148     if ( e == ++i ) break LOOP; // ran to end
149     o = i+1;
150     break;
151     }
152     }
153    
154     if ( Db.MDL == (Db.MDL & mode) ) // data mode
155     switch ( Character.getType( c[e-1] ) ) {
156     case Character.START_PUNCTUATION:
157     case Character.END_PUNCTUATION:
158     case Character.CONNECTOR_PUNCTUATION:
159     case Character.OTHER_PUNCTUATION:
160     b.append( " " );
161     break;
162     default:
163     b.append( ". " );
164     }
165    
166     return true;
167     } // v
168    
169    
170     /** format a String in HTU-mode.
171     @see #v(StringBuffer,int,String,int)
172     */
173     public static String html ( String plain ) {
174     StringBuffer b = new StringBuffer( plain.length() + 3 );
175     v( b, Db.HTU, plain, 0 ); // always true w/o subfield spec
176     return b.toString();
177     } // html
178    
179    
180     //
181     // so far the statics
182     //
183    
184     /** the tag of this field.
185     For primary fields, this is the field number.
186     For subfields, this is actually a char.
187     */
188     public final int tag;
189     public final String val;
190    
191     public Field ( int tag_, String val_ ) {
192     tag = tag_;
193     val = (val_==null)?"":val_;
194     }
195    
196     public boolean equals (Object that) {
197     if (null == that) {
198     return false;
199     }
200     if (getClass () != that.getClass ()) {
201     return false;
202     }
203     String v1 = val; if (null == v1) v1 = "";
204     String v2 = ((Field)that).val; if (null == v2) v2 = "";
205     return tag == ((Field)that).tag && v1.equals (v2);
206     }
207    
208     public String toString () {
209     return tag + ";" + val;
210     }
211    
212     /** split the Field into subfields.
213     */
214     public Field[] split () {
215     if ( null == val || 0 == val.length() )
216     return null;
217     String tval=val;
218     int p;
219     if ((p=tval.indexOf('^'))<0) return null;
220     if (p>0) tval=tval.substring(p+1,tval.length());
221     StringTokenizer st = new StringTokenizer( tval, "^" );
222     Field[] f = new Field[ st.countTokens() ];
223     for ( int i=0; i<f.length; i++ ) {
224     String tok = st.nextToken();
225     if ( null != tok && 0 < tok.length() )
226     f[i] = new Field( (int)tok.charAt(0), tok.substring(1) );
227     }
228     return f;
229     } // split
230    
231    
232     public String getValue() {
233     int p;
234     if ((p=val.indexOf('^'))<0) return val;
235     else return val.substring(0,p);
236     }
237    
238     public Field[] getSubFields() {
239     return split();
240     }
241    
242    
243     /** format field to a StringBuffer.
244     @see #v(StringBuffer,int,String,int)
245     */
246     public boolean v ( StringBuffer b, int mode ) {
247     return v( b, mode, val, 0 );
248     } // v
249    
250    
251     /** format field to a StringBuffer.
252     @see #v(StringBuffer,int,String,int)
253     */
254     public boolean v ( StringBuffer b, int mode, int len ) {
255     if (val==null) {
256     System.err.println("VAL==NULL:"+tag+","+val);
257     }
258     return v( b, mode, val, len );
259     } // v
260    
261    
262     /** format field as new String.
263     @see #v(StringBuffer,int,String,int)
264     */
265     public String v ( int mode, int len ) {
266     StringBuffer b = new StringBuffer( val.length() + 3 );
267     return v( b, mode, val, len ) ? b.toString() : Db.EMPTY;
268     } // v
269    
270    
271     /** format field as new String.
272     @see #v(StringBuffer,int,String,int)
273     */
274     public String v ( int mode ) {
275     return v( mode, 0 );
276     } // v
277    
278    
279     /** format field in HTU-mode as new String.
280     @see #v(StringBuffer,int,String,int)
281     */
282     public String html () {
283     return v( Db.HTU );
284     } // html
285    
286     } // Field

  ViewVC Help
Powered by ViewVC 1.1.26