View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.flatfile;
18  
19  import java.io.ByteArrayInputStream;
20  import java.io.InputStream;
21  
22  import org.apache.commons.flatfile.util.ConcatenatedInputStream;
23  import org.apache.commons.flatfile.util.RepeatingInputStream;
24  
25  /**
26   * Support for fields with pad/justify.
27   * @version $Revision: 1301242 $ $Date: 2012-03-15 17:14:40 -0500 (Thu, 15 Mar 2012) $
28   */
29  public abstract class PadJustifyFieldSupport extends FieldSupport {
30      /** Serialization version */
31      private static final long serialVersionUID = -4953059253157670418L;
32  
33      /**
34       * Default pad.
35       */
36      public static final byte DEFAULT_PAD = 0x20;
37  
38      /**
39       * Justify enumerated type.
40       */
41      public enum Justify implements FieldOption {
42          /** Left-justify */
43          LEFT {
44              /**
45               * {@inheritDoc}
46               */
47              protected InputStream getInputStream(byte[] src, PadJustifyFieldSupport dest) {
48                  final InputStream is = new ByteArrayInputStream(src);
49                  final int dlen = dest.getPadJustifyLength();
50                  return dlen <= src.length ? is : new ConcatenatedInputStream(
51                      is, RepeatingInputStream.withLimit(dlen - src.length,
52                          dest.getPad()));
53              }
54          },
55  
56          /** Right-justify */
57          RIGHT {
58              /**
59               * {@inheritDoc}
60               */
61              protected InputStream getInputStream(byte[] src, PadJustifyFieldSupport dest) {
62                  final int dlen = dest.getPadJustifyLength();
63                  if (dlen < src.length) {
64                      return new ByteArrayInputStream(src, src.length - dlen,
65                          dlen);
66                  }
67                  final InputStream is = new ByteArrayInputStream(src);
68                  return dlen == src.length ? is : new ConcatenatedInputStream(
69                      RepeatingInputStream.withLimit(dlen - src.length,
70                          dest.getPad()), is);
71              }
72          },
73  
74          /** Center */
75          CENTER {
76              /**
77               * {@inheritDoc}
78               */
79              protected InputStream getInputStream(byte[] src, PadJustifyFieldSupport dest) {
80                  final int dlen = dest.getPadJustifyLength();
81                  // it would be odd and therefore hopefully rare to center a
82                  // field that allowed overflow, but we'll provide for it:
83                  if (dlen < src.length) {
84                      return new ByteArrayInputStream(src,
85                          (src.length - dlen) / 2, dlen);
86                  }
87                  final InputStream is = new ByteArrayInputStream(src);
88                  if (dlen == src.length) {
89                      return is;
90                  }
91                  final byte pad = dest.getPad();
92                  return new ConcatenatedInputStream(
93                      RepeatingInputStream
94                          .withLimit((dlen - src.length) / 2, pad),
95                      is, RepeatingInputStream.of(pad));
96              }
97          };
98  
99          /**
100          * Get an InputStream for the specified parameters.
101          * @param src byte[] value
102          * @param dest PadJustifyFieldSupport
103          * @return InputStream
104          */
105         protected abstract InputStream getInputStream(byte[] src, PadJustifyFieldSupport dest);
106     }
107 
108     private byte pad = DEFAULT_PAD;
109     private Justify justify;
110 
111     /**
112      * Get the justify.
113      * @return Justify
114      */
115     public Justify getJustify() {
116         return justify == null ? Justify.LEFT : justify;
117     }
118 
119     /**
120      * Set the justify.
121      * @param justify Justify
122      */
123     public void setJustify(Justify justify) {
124         this.justify = justify;
125     }
126 
127     /**
128      * Get the pad.
129      * @return byte
130      */
131     public byte getPad() {
132         return pad;
133     }
134 
135     /**
136      * Set the pad.
137      * @param pad byte
138      */
139     public void setPad(byte pad) {
140         this.pad = pad;
141     }
142 
143     /**
144      * Implement pad/justify.
145      * @param b value set
146      */
147     public void setValue(byte[] b) {
148         dieOnExceptionRead(getJustify().getInputStream(b, this));
149     }
150 
151     /**
152      * Provide the desired target length for padding/justification actions.
153      * @return int
154      */
155     protected abstract int getPadJustifyLength();
156 }