Buffer.java
上传用户:xfwatch
上传日期:2020-12-14
资源大小:872k
文件大小:18k
源码类别:

中间件编程

开发平台:

Java

  1. /*
  2.  * JBoss, Home of Professional Open Source
  3.  * Copyright 2008, Red Hat, Inc., and others contributors as indicated
  4.  * by the @authors tag. All rights reserved.
  5.  * See the copyright.txt in the distribution for a
  6.  * full listing of individual contributors.
  7.  * This copyrighted material is made available to anyone wishing to use,
  8.  * modify, copy, or redistribute it subject to the terms and conditions
  9.  * of the GNU Lesser General public  License, v. 2.1.
  10.  * This program is distributed in the hope that it will be useful, but WITHOUT A
  11.  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
  12.  * PARTICULAR PURPOSE.  See the GNU Lesser General public  License for more details.
  13.  * You should have received a copy of the GNU Lesser General public  License,
  14.  * v.2.1 along with this distribution; if not, write to the Free Software
  15.  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
  16.  * MA  02110-1301, USA.
  17.  */
  18. package org.jboss.blacktie.jatmibroker.xatmi;
  19. import java.io.ByteArrayInputStream;
  20. import java.io.ByteArrayOutputStream;
  21. import java.io.DataInputStream;
  22. import java.io.DataOutputStream;
  23. import java.io.IOException;
  24. import java.io.Serializable;
  25. import java.nio.ByteBuffer;
  26. import java.nio.ByteOrder;
  27. import java.util.HashMap;
  28. import java.util.Iterator;
  29. import java.util.List;
  30. import java.util.Map;
  31. import java.util.Properties;
  32. import org.apache.log4j.LogManager;
  33. import org.apache.log4j.Logger;
  34. import org.jboss.blacktie.jatmibroker.core.conf.AttributeStructure;
  35. import org.jboss.blacktie.jatmibroker.core.conf.BufferStructure;
  36. import org.jboss.blacktie.jatmibroker.jab.JABException;
  37. import org.jboss.blacktie.jatmibroker.jab.JABTransaction;
  38. /**
  39.  * This class encapsulates the response from the remote service and the return
  40.  * code
  41.  */
  42. public abstract class Buffer implements Serializable {
  43. private static final Logger log = LogManager.getLogger(Buffer.class);
  44. /**
  45.  * The agreed size of a byte.
  46.  */
  47. public static final int BYTE_SIZE = 1;
  48. /**
  49.  * The agreed size of a long.
  50.  */
  51. public static final int LONG_SIZE = 8;
  52. /**
  53.  * The agreed size of a int.
  54.  */
  55. public static final int INT_SIZE = 4;
  56. /**
  57.  * The agreed size of a short.
  58.  */
  59. public static final int SHORT_SIZE = 2;
  60. /**
  61.  * The agreed size of a float.
  62.  */
  63. public static final int FLOAT_SIZE = INT_SIZE;
  64. /**
  65.  * The agreed size of a double.
  66.  */
  67. public static final int DOUBLE_SIZE = LONG_SIZE;
  68. /**
  69.  * 
  70.  */
  71. private static final long serialVersionUID = 1L;
  72. private Map<String, Object> structure = new HashMap<String, Object>();
  73. private String[] keys;
  74. private Class[] types;
  75. private int[] lengths;
  76. private boolean deserialized;
  77. private boolean formatted;
  78. int currentPos = 0;
  79. private List<Class> supportedTypes;
  80. private boolean requiresSerialization;
  81. private String type;
  82. private String subtype;
  83. private byte[] data;
  84. private int[] counts;
  85. private Map<String, Class> format = new HashMap<String, Class>();
  86. /**
  87.  * Create a new buffer
  88.  * 
  89.  * @param properties
  90.  * @param b
  91.  * 
  92.  * @param types
  93.  * @throws ConnectionException
  94.  */
  95. Buffer(String type, String subtype, boolean requiresSerialization,
  96. List<Class> supportedTypes, Properties properties)
  97. throws ConnectionException {
  98. this.type = type;
  99. this.subtype = subtype;
  100. this.requiresSerialization = requiresSerialization;
  101. this.supportedTypes = supportedTypes;
  102. if (requiresSerialization) {
  103. Map<String, BufferStructure> buffers = (Map<String, BufferStructure>) properties
  104. .get("blacktie.domain.buffers");
  105. BufferStructure buffer = buffers.get(subtype);
  106. if (buffer == null) {
  107. throw new ConnectionException(Connection.TPEITYPE,
  108. "Subtype was not registered: " + subtype);
  109. }
  110. String[] ids = new String[buffer.attributes.size()];
  111. Class[] types = new Class[buffer.attributes.size()];
  112. int[] length = new int[buffer.attributes.size()];
  113. int[] count = new int[buffer.attributes.size()];
  114. Iterator<AttributeStructure> iterator = buffer.attributes
  115. .iterator();
  116. int i = 0;
  117. while (iterator.hasNext()) {
  118. AttributeStructure attribute = iterator.next();
  119. ids[i] = attribute.id;
  120. types[i] = attribute.type;
  121. if (!supportedTypes.contains(types[i])) {
  122. throw new ConnectionException(Connection.TPEITYPE,
  123. "Cannot use type configured in buffer " + types[i]);
  124. }
  125. length[i] = attribute.length;
  126. count[i] = attribute.count;
  127. i++;
  128. }
  129. format(ids, types, length, count);
  130. } else {
  131. format.put("X_OCTET", byte[].class);
  132. }
  133. }
  134. public Map<String, Class> getFormat() {
  135. return format;
  136. }
  137. private void format(String[] keys, Class[] types, int[] lengths,
  138. int[] counts) throws ConnectionException {
  139. structure.clear();
  140. if (keys.length != types.length || types.length != lengths.length) {
  141. throw new ConnectionException(-1,
  142. "Invalid format, each array description should be same length");
  143. }
  144. this.keys = keys;
  145. this.types = types;
  146. this.lengths = lengths;
  147. this.counts = counts;
  148. for (int i = 0; i < keys.length; i++) {
  149. format.put(keys[i], types[i]);
  150. }
  151. formatted = true;
  152. }
  153. void deserialize(byte[] data) throws ConnectionException {
  154. currentPos = 0;
  155. if (requiresSerialization) {
  156. if (!deserialized && data != null) {
  157. if (keys == null) {
  158. throw new ConnectionException(Connection.TPEITYPE,
  159. "Message format not provided");
  160. }
  161. ByteArrayInputStream bais = new ByteArrayInputStream(data);
  162. DataInputStream dis = new DataInputStream(bais);
  163. for (int i = 0; i < types.length; i++) {
  164. if (!supportedTypes.contains(types[i])) {
  165. throw new ConnectionException(Connection.TPEITYPE,
  166. "Cannot read type from buffer " + types[i]);
  167. }
  168. try {
  169. if (types[i] == int.class) {
  170. structure.put(keys[i], readInt(dis));
  171. } else if (types[i] == short.class) {
  172. structure.put(keys[i], readShort(dis));
  173. } else if (types[i] == long.class) {
  174. structure.put(keys[i], readLong(dis));
  175. } else if (types[i] == byte.class) {
  176. structure.put(keys[i], readByte(dis));
  177. } else if (types[i] == float.class) {
  178. structure.put(keys[i], readFloat(dis));
  179. } else if (types[i] == double.class) {
  180. structure.put(keys[i], readDouble(dis));
  181. } else if (types[i] == int[].class) {
  182. int[] toRead = new int[lengths[i]];
  183. for (int j = 0; j < lengths[i]; j++) {
  184. toRead[j] = readInt(dis);
  185. }
  186. structure.put(keys[i], toRead);
  187. } else if (types[i] == short[].class) {
  188. short[] toRead = new short[lengths[i]];
  189. for (int j = 0; j < lengths[i]; j++) {
  190. toRead[j] = readShort(dis);
  191. }
  192. structure.put(keys[i], toRead);
  193. } else if (types[i] == long[].class) {
  194. long[] toRead = new long[lengths[i]];
  195. for (int j = 0; j < lengths[i]; j++) {
  196. toRead[j] = readLong(dis);
  197. }
  198. structure.put(keys[i], toRead);
  199. } else if (types[i] == byte[].class) {
  200. byte[] toRead = new byte[lengths[i]];
  201. for (int j = 0; j < lengths[i]; j++) {
  202. toRead[j] = readByte(dis);
  203. }
  204. structure.put(keys[i], toRead);
  205. } else if (types[i] == float[].class) {
  206. float[] toRead = new float[lengths[i]];
  207. for (int j = 0; j < lengths[i]; j++) {
  208. toRead[j] = readFloat(dis);
  209. }
  210. structure.put(keys[i], toRead);
  211. } else if (types[i] == double[].class) {
  212. double[] toRead = new double[lengths[i]];
  213. for (int j = 0; j < lengths[i]; j++) {
  214. toRead[j] = readDouble(dis);
  215. }
  216. structure.put(keys[i], toRead);
  217. } else if (types[i] == byte[][].class) {
  218. byte[][] toRead = new byte[counts[i]][lengths[i]];
  219. for (int k = 0; k < counts[i]; k++) {
  220. for (int j = 0; j < lengths[i]; j++) {
  221. toRead[k][j] = readByte(dis);
  222. }
  223. }
  224. structure.put(keys[i], toRead);
  225. } else {
  226. throw new ConnectionException(Connection.TPEITYPE,
  227. "Could not deserialize: " + types[i]);
  228. }
  229. } catch (IOException e) {
  230. throw new ConnectionException(
  231. Connection.TPEITYPE,
  232. "Could not parse the value as: "
  233. + keys[i]
  234. + " was not a "
  235. + types[i]
  236. + " and even if it was an array of that type its length was not: "
  237. + lengths[i]);
  238. }
  239. }
  240. }
  241. } else {
  242. this.data = data;
  243. }
  244. deserialized = true;
  245. }
  246. byte[] serialize() throws ConnectionException {
  247. currentPos = 0;
  248. byte[] toReturn = null;
  249. if (requiresSerialization) {
  250. ByteArrayOutputStream baos = new ByteArrayOutputStream();
  251. DataOutputStream dos = new DataOutputStream(baos);
  252. for (int i = 0; i < types.length; i++) {
  253. try {
  254. if (types[i] == int.class) {
  255. Integer toWrite = (Integer) structure.get(keys[i]);
  256. if (toWrite != null) {
  257. writeInt(dos, toWrite);
  258. } else {
  259. writeInt(dos, 0);
  260. }
  261. } else if (types[i] == short.class) {
  262. Short toWrite = (Short) structure.get(keys[i]);
  263. if (toWrite != null) {
  264. writeShort(dos, toWrite);
  265. } else {
  266. writeShort(dos, (short) 0);
  267. }
  268. } else if (types[i] == long.class) {
  269. Long toWrite = (Long) structure.get(keys[i]);
  270. if (toWrite != null) {
  271. writeLong(dos, toWrite);
  272. } else {
  273. writeLong(dos, 0);
  274. }
  275. } else if (types[i] == byte.class) {
  276. Byte toWrite = (Byte) structure.get(keys[i]);
  277. if (toWrite != null) {
  278. writeByte(dos, toWrite);
  279. } else {
  280. // writeByte(dos, '');
  281. writeByte(dos, (byte) 0);
  282. }
  283. } else if (types[i] == float.class) {
  284. Float toWrite = (Float) structure.get(keys[i]);
  285. if (toWrite != null) {
  286. writeFloat(dos, toWrite);
  287. } else {
  288. writeFloat(dos, 0);
  289. }
  290. } else if (types[i] == double.class) {
  291. Double toWrite = (Double) structure.get(keys[i]);
  292. if (toWrite != null) {
  293. writeDouble(dos, toWrite);
  294. } else {
  295. writeDouble(dos, 0);
  296. }
  297. } else if (types[i] == int[].class) {
  298. int[] toWrite = (int[]) structure.get(keys[i]);
  299. int max = 0;
  300. if (toWrite != null) {
  301. max = Math.min(lengths[i], toWrite.length);
  302. for (int j = 0; j < lengths[i]; j++) {
  303. writeInt(dos, toWrite[j]);
  304. }
  305. }
  306. for (int j = max; j < lengths[i]; j++) {
  307. writeInt(dos, 0);
  308. }
  309. } else if (types[i] == short[].class) {
  310. short[] toWrite = (short[]) structure.get(keys[i]);
  311. int max = 0;
  312. if (toWrite != null) {
  313. max = Math.min(lengths[i], toWrite.length);
  314. for (int j = 0; j < lengths[i]; j++) {
  315. writeShort(dos, toWrite[j]);
  316. }
  317. }
  318. for (int j = max; j < lengths[i]; j++) {
  319. writeShort(dos, (short) 0);
  320. }
  321. } else if (types[i] == long[].class) {
  322. long[] toWrite = (long[]) structure.get(keys[i]);
  323. int max = 0;
  324. if (toWrite != null) {
  325. max = Math.min(lengths[i], toWrite.length);
  326. for (int j = 0; j < lengths[i]; j++) {
  327. writeLong(dos, toWrite[j]);
  328. }
  329. }
  330. for (int j = max; j < lengths[i]; j++) {
  331. writeLong(dos, 0);
  332. }
  333. } else if (types[i] == byte[].class) {
  334. byte[] toWrite = (byte[]) structure.get(keys[i]);
  335. int max = 0;
  336. if (toWrite != null) {
  337. max = Math.min(lengths[i], toWrite.length);
  338. for (int j = 0; j < max; j++) {
  339. writeByte(dos, toWrite[j]);
  340. }
  341. }
  342. for (int j = max; j < lengths[i]; j++) {
  343. // writeByte(dos, '');
  344. writeByte(dos, (byte) 0);
  345. }
  346. } else if (types[i] == float[].class) {
  347. float[] toWrite = (float[]) structure.get(keys[i]);
  348. int max = 0;
  349. if (toWrite != null) {
  350. max = Math.min(lengths[i], toWrite.length);
  351. for (int j = 0; j < lengths[i]; j++) {
  352. writeFloat(dos, toWrite[j]);
  353. }
  354. }
  355. for (int j = max; j < lengths[i]; j++) {
  356. writeFloat(dos, 0);
  357. }
  358. } else if (types[i] == double[].class) {
  359. double[] toWrite = (double[]) structure.get(keys[i]);
  360. int max = 0;
  361. if (toWrite != null) {
  362. max = Math.min(lengths[i], toWrite.length);
  363. for (int j = 0; j < lengths[i]; j++) {
  364. writeDouble(dos, toWrite[j]);
  365. }
  366. }
  367. for (int j = max; j < lengths[i]; j++) {
  368. writeDouble(dos, 0);
  369. }
  370. } else if (types[i] == byte[][].class) {
  371. byte[][] toWrite = (byte[][]) structure.get(keys[i]);
  372. if (toWrite != null) {
  373. for (int k = 0; k < counts[i]; k++) {
  374. for (int j = 0; j < lengths[i]; j++) {
  375. writeByte(dos, toWrite[k][j]);
  376. }
  377. }
  378. } else {
  379. for (int j = 0; j < counts[i] * lengths[i]; j++) {
  380. writeByte(dos, (byte) 0);
  381. }
  382. }
  383. } else {
  384. if (JABTransaction.current() != null) {
  385. try {
  386. JABTransaction.current().rollback_only();
  387. } catch (JABException e) {
  388. throw new ConnectionException(
  389. Connection.TPESYSTEM,
  390. "Could not mark transaction for rollback only");
  391. }
  392. }
  393. throw new ConnectionException(Connection.TPEOTYPE,
  394. "Could not serialize: " + types[i]);
  395. }
  396. } catch (IOException e) {
  397. throw new ConnectionException(
  398. Connection.TPEOTYPE,
  399. "Could not parse the value as: "
  400. + keys[i]
  401. + " was not a "
  402. + types[i]
  403. + " and even if it was an array of that type its length was not: "
  404. + lengths[i]);
  405. }
  406. }
  407. toReturn = baos.toByteArray();
  408. } else {
  409. toReturn = getRawData();
  410. }
  411. if (toReturn == null) {
  412. toReturn = new byte[1];
  413. }
  414. return toReturn;
  415. }
  416. private void writeByte(DataOutputStream dos, byte b) throws IOException {
  417. dos.writeByte(b);
  418. currentPos += 1;
  419. }
  420. private byte readByte(DataInputStream dis) throws IOException {
  421. currentPos += 1;
  422. byte x = dis.readByte();
  423. ByteBuffer bbuf = ByteBuffer.allocate(BYTE_SIZE);
  424. bbuf.order(ByteOrder.LITTLE_ENDIAN);
  425. bbuf.put(x);
  426. bbuf.order(ByteOrder.BIG_ENDIAN);
  427. return bbuf.get(0);
  428. }
  429. private void writeLong(DataOutputStream dos, long x) throws IOException {
  430. ByteBuffer bbuf = ByteBuffer.allocate(LONG_SIZE);
  431. bbuf.order(ByteOrder.BIG_ENDIAN);
  432. bbuf.putLong(x);
  433. bbuf.order(ByteOrder.LITTLE_ENDIAN);
  434. long toWrite = bbuf.getLong(0);
  435. dos.writeLong(toWrite);
  436. currentPos += LONG_SIZE;
  437. }
  438. private long readLong(DataInputStream dis) throws IOException {
  439. currentPos += LONG_SIZE;
  440. long x = dis.readLong();
  441. ByteBuffer bbuf = ByteBuffer.allocate(LONG_SIZE);
  442. bbuf.order(ByteOrder.LITTLE_ENDIAN);
  443. bbuf.putLong(x);
  444. bbuf.order(ByteOrder.BIG_ENDIAN);
  445. return bbuf.getLong(0);
  446. }
  447. private void writeInt(DataOutputStream dos, int x) throws IOException {
  448. ByteBuffer bbuf = ByteBuffer.allocate(INT_SIZE);
  449. bbuf.order(ByteOrder.BIG_ENDIAN);
  450. bbuf.putInt(x);
  451. bbuf.order(ByteOrder.LITTLE_ENDIAN);
  452. int toWrite = bbuf.getInt(0);
  453. dos.writeInt(toWrite);
  454. currentPos += INT_SIZE;
  455. }
  456. private int readInt(DataInputStream dis) throws IOException {
  457. currentPos += INT_SIZE;
  458. int x = dis.readInt();
  459. ByteBuffer bbuf = ByteBuffer.allocate(INT_SIZE);
  460. bbuf.order(ByteOrder.LITTLE_ENDIAN);
  461. bbuf.putInt(x);
  462. bbuf.order(ByteOrder.BIG_ENDIAN);
  463. return bbuf.getInt(0);
  464. }
  465. private void writeShort(DataOutputStream dos, short x) throws IOException {
  466. ByteBuffer bbuf = ByteBuffer.allocate(SHORT_SIZE);
  467. bbuf.order(ByteOrder.BIG_ENDIAN);
  468. bbuf.putShort(x);
  469. bbuf.order(ByteOrder.LITTLE_ENDIAN);
  470. short toWrite = bbuf.getShort(0);
  471. dos.writeShort(toWrite);
  472. currentPos += SHORT_SIZE;
  473. }
  474. private short readShort(DataInputStream dis) throws IOException {
  475. currentPos += SHORT_SIZE;
  476. short x = dis.readShort();
  477. ByteBuffer bbuf = ByteBuffer.allocate(SHORT_SIZE);
  478. bbuf.order(ByteOrder.LITTLE_ENDIAN);
  479. bbuf.putShort(x);
  480. bbuf.order(ByteOrder.BIG_ENDIAN);
  481. return bbuf.getShort(0);
  482. }
  483. private void writeFloat(DataOutputStream dos, float x) throws IOException {
  484. ByteBuffer bbuf = ByteBuffer.allocate(FLOAT_SIZE);
  485. bbuf.order(ByteOrder.BIG_ENDIAN);
  486. bbuf.putFloat(x);
  487. bbuf.order(ByteOrder.LITTLE_ENDIAN);
  488. float toWrite = bbuf.getFloat(0);
  489. dos.writeFloat(toWrite);
  490. currentPos += FLOAT_SIZE;
  491. }
  492. private float readFloat(DataInputStream dis) throws IOException {
  493. currentPos += FLOAT_SIZE;
  494. float x = dis.readFloat();
  495. ByteBuffer bbuf = ByteBuffer.allocate(FLOAT_SIZE);
  496. bbuf.order(ByteOrder.LITTLE_ENDIAN);
  497. bbuf.putFloat(x);
  498. bbuf.order(ByteOrder.BIG_ENDIAN);
  499. return bbuf.getFloat(0);
  500. }
  501. private void writeDouble(DataOutputStream dos, double x) throws IOException {
  502. ByteBuffer bbuf = ByteBuffer.allocate(DOUBLE_SIZE);
  503. bbuf.order(ByteOrder.BIG_ENDIAN);
  504. bbuf.putDouble(x);
  505. bbuf.order(ByteOrder.LITTLE_ENDIAN);
  506. double toWrite = bbuf.getDouble(0);
  507. dos.writeDouble(toWrite);
  508. currentPos += DOUBLE_SIZE;
  509. }
  510. private double readDouble(DataInputStream dis) throws IOException {
  511. currentPos += DOUBLE_SIZE;
  512. double x = dis.readDouble();
  513. ByteBuffer bbuf = ByteBuffer.allocate(DOUBLE_SIZE);
  514. bbuf.order(ByteOrder.LITTLE_ENDIAN);
  515. bbuf.putDouble(x);
  516. bbuf.order(ByteOrder.BIG_ENDIAN);
  517. return bbuf.getDouble(0);
  518. }
  519. /**
  520.  * Get the type
  521.  * 
  522.  * @return The type
  523.  */
  524. public String getType() {
  525. return type;
  526. }
  527. /**
  528.  * Get the subtype
  529.  * 
  530.  * @return The subtype
  531.  */
  532. public String getSubtype() {
  533. return subtype;
  534. }
  535. /**
  536.  * Clear the content of the buffer
  537.  */
  538. public void clear() {
  539. structure.clear();
  540. data = null;
  541. }
  542. protected Object getAttributeValue(String key, Class type)
  543. throws ConnectionException {
  544. if (!formatted) {
  545. throw new ConnectionException(Connection.TPEPROTO,
  546. "Message not formatted");
  547. }
  548. int position = -1;
  549. for (int i = 0; i < keys.length; i++) {
  550. if (keys[i].equals(key)) {
  551. position = i;
  552. }
  553. }
  554. if (position == -1) {
  555. throw new ConnectionException(Connection.TPEITYPE,
  556. "Key is not part of the structure: " + key);
  557. } else if (types[position] != type) {
  558. throw new ConnectionException(Connection.TPEITYPE,
  559. "Key is not request type, it is a: " + types[position]);
  560. }
  561. return structure.get(key);
  562. }
  563. protected void setAttributeValue(String key, Class type, Object value)
  564. throws ConnectionException {
  565. if (!formatted) {
  566. throw new ConnectionException(Connection.TPEPROTO,
  567. "Message not formatted");
  568. }
  569. int position = -1;
  570. for (int i = 0; i < keys.length; i++) {
  571. if (keys[i].equals(key)) {
  572. position = i;
  573. }
  574. }
  575. if (position == -1) {
  576. throw new ConnectionException(Connection.TPEITYPE,
  577. "Key is not part of the structure: " + key);
  578. } else if (types[position] != type) {
  579. throw new ConnectionException(Connection.TPEITYPE,
  580. "Key is not request type, it is a: " + types[position]);
  581. }
  582. structure.put(key, value);
  583. }
  584. protected void setRawData(byte[] bytes) {
  585. this.data = bytes;
  586. }
  587. protected byte[] getRawData() {
  588. return data;
  589. }
  590. }