View Javadoc

1   /*******************************************************************************
2    * Copyright (c) 2015 LegSem.
3    * All rights reserved. This program and the accompanying materials
4    * are made available under the terms of the GNU Lesser Public License v2.1
5    * which accompanies this distribution, and is available at
6    * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
7    * 
8    * Contributors:
9    *     LegSem - initial API and implementation
10   ******************************************************************************/
11  package com.legstar.coxb.common;
12  
13  import com.legstar.coxb.CobolElement;
14  import com.legstar.coxb.ICobolArrayBinding;
15  import com.legstar.coxb.ICobolComplexBinding;
16  import com.legstar.coxb.ICobolNumericBinding;
17  import com.legstar.coxb.host.HostException;
18  
19  /**
20   * This generic class implements behavior common to all array bindings.
21   * 
22   */
23  public abstract class CArrayBinding extends CBinding implements
24          ICobolArrayBinding {
25  
26      /** A reference to a counter for variable size arrays. */
27      private ICobolNumericBinding mCounter;
28  
29      /** Array individual item length in bytes (unknown by default). */
30      private int mItemByteLength = 0;
31  
32      /**
33       * Constructor for a cobol element to java binding.
34       * 
35       * @param bindingName the identifier for this binding
36       * @param jaxbName the name of the bound java property
37       * @param jaxbType the type of the bound java property
38       * @param cobolAnnotations the cobol annotations for this element
39       * @param parentBinding a reference to the parent binding if any
40       */
41      public CArrayBinding(final String bindingName, final String jaxbName,
42              final Class < ? > jaxbType, final CobolElement cobolAnnotations,
43              final ICobolComplexBinding parentBinding) {
44          super(bindingName, jaxbName, jaxbType, cobolAnnotations, parentBinding);
45      }
46  
47      /**
48       * {@inheritDoc}
49       */
50      public int getCurrentOccurs() throws HostException {
51          /*
52           * If this is a variable size array, ask ancestors for the current value
53           * of the counter we depend on.
54           */
55          if (isVariableSize()) {
56              return getCounter().getBigIntegerValue().intValue();
57          }
58          return this.getMaxOccurs();
59      }
60  
61      /**
62       * {@inheritDoc}
63       * <p/>
64       * If length exceed Integer.MAX_VALUE, returns Integer.MAX_VALUE.
65       */
66      public int calcByteLength() {
67          long byteLength = getMaxOccurs() * (long) getItemByteLength();
68          return byteLength > Integer.MAX_VALUE ? Integer.MAX_VALUE
69                  : (int) byteLength;
70      }
71  
72      /**
73       * This test cannot be done at construction time because the depending on
74       * property can be added later.
75       * 
76       * @return true if this is a variable size array
77       */
78      public boolean isVariableSize() {
79          return (getMinOccurs() < getMaxOccurs() && getDependingOn() != null && getDependingOn()
80                  .length() > 0) ? true : false;
81      }
82  
83      /**
84       * The first time around, this will seek the counter from the parent
85       * binding. This is an expensive operation so we cache the result to speed
86       * up next referrals.
87       * 
88       * @return the counter
89       * @throws HostException if something goes wrong
90       */
91      private ICobolNumericBinding getCounter() throws HostException {
92          if (mCounter == null) {
93              mCounter = getParentBinding().getCounter(getDependingOn());
94          }
95          return mCounter;
96      }
97  
98      /**
99       * Pre version 1.2.4 generated simple arrays did not support the
100      * ItemByteLength attribute. Their ByteLength attribute was actually the
101      * ItemByteLength instead of being the size of the entire array. We need to
102      * continue supporting this old model. Hence the size adjustment here.
103      * 
104      * @return the Cobol element length in bytes
105      */
106     public int getByteLength() {
107         if (isGeneratedBinding() && !(this instanceof CArrayComplexBinding)
108                 && mItemByteLength == 0) {
109             /* Binding was generated before 1.2.4. Adjust lengths. */
110             int itemByteLength = super.getByteLength();
111             setItemByteLength(itemByteLength);
112             setByteLength(itemByteLength * getMaxOccurs());
113         }
114         return super.getByteLength();
115     }
116 
117     /**
118      * {@inheritDoc}
119      */
120     public int getItemByteLength() {
121         if (mItemByteLength == 0) {
122             if (isGeneratedBinding() && !(this instanceof CArrayComplexBinding)) {
123                 /* Binding was generated before 1.2.4. Adjust lengths. */
124                 mItemByteLength = super.getByteLength();
125                 setByteLength(mItemByteLength * getMaxOccurs());
126             } else {
127                 mItemByteLength = calcItemByteLength();
128             }
129         }
130         return mItemByteLength;
131     }
132 
133     /**
134      * {@inheritDoc}
135      */
136     public void setItemByteLength(final int itemByteLength) {
137         mItemByteLength = itemByteLength;
138     }
139 
140 }