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 }