PageRenderTime 48ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/tags/1.0rc2/enterprise/src/main/java/com/orientechnologies/orient/enterprise/channel/binary/OChannelBinary.java

http://orient.googlecode.com/
Java | 385 lines | 287 code | 78 blank | 20 comment | 73 complexity | 3b22bfa760ee4044f0f58e2afd59457a MD5 | raw file
Possible License(s): Apache-2.0, AGPL-3.0
  1. /*
  2. * Copyright 1999-2010 Luca Garulli (l.garulli--at--orientechnologies.com)
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. package com.orientechnologies.orient.enterprise.channel.binary;
  17. import java.io.DataInputStream;
  18. import java.io.DataOutputStream;
  19. import java.io.IOException;
  20. import java.lang.reflect.Constructor;
  21. import java.lang.reflect.InvocationTargetException;
  22. import java.net.Socket;
  23. import java.util.ArrayList;
  24. import java.util.Collection;
  25. import java.util.HashSet;
  26. import java.util.List;
  27. import java.util.Set;
  28. import com.orientechnologies.common.log.OLogManager;
  29. import com.orientechnologies.common.util.OPair;
  30. import com.orientechnologies.orient.core.config.OContextConfiguration;
  31. import com.orientechnologies.orient.core.config.OGlobalConfiguration;
  32. import com.orientechnologies.orient.core.exception.ODatabaseException;
  33. import com.orientechnologies.orient.core.exception.OStorageException;
  34. import com.orientechnologies.orient.core.id.ORID;
  35. import com.orientechnologies.orient.core.id.ORecordId;
  36. import com.orientechnologies.orient.enterprise.channel.OChannel;
  37. public abstract class OChannelBinary extends OChannel {
  38. public DataInputStream in;
  39. public DataOutputStream out;
  40. private final int maxChunkSize;
  41. private boolean debug;
  42. private final byte[] buffer;
  43. public OChannelBinary(final Socket iSocket, final OContextConfiguration iConfig) throws IOException {
  44. super(iSocket, iConfig);
  45. maxChunkSize = iConfig.getValueAsInteger(OGlobalConfiguration.NETWORK_BINARY_MAX_CONTENT_LENGTH);
  46. debug = iConfig.getValueAsBoolean(OGlobalConfiguration.NETWORK_BINARY_DEBUG);
  47. buffer = new byte[maxChunkSize];
  48. }
  49. public byte readByte() throws IOException {
  50. if (debug) {
  51. OLogManager.instance().debug(this, "Reading byte (1 byte)...");
  52. final byte value = in.readByte();
  53. OLogManager.instance().debug(this, "Read byte: " + (int) value);
  54. return value;
  55. }
  56. return in.readByte();
  57. }
  58. public int readInt() throws IOException {
  59. if (debug) {
  60. OLogManager.instance().debug(this, "Reading int (4 bytes)...");
  61. final int value = in.readInt();
  62. OLogManager.instance().debug(this, "Read int: " + value);
  63. return value;
  64. }
  65. return in.readInt();
  66. }
  67. public long readLong() throws IOException {
  68. if (debug) {
  69. OLogManager.instance().debug(this, "Reading long (8 bytes)...");
  70. final long value = in.readLong();
  71. OLogManager.instance().debug(this, "Read long: " + value);
  72. return value;
  73. }
  74. return in.readLong();
  75. }
  76. public short readShort() throws IOException {
  77. if (debug) {
  78. OLogManager.instance().debug(this, "Reading short (2 bytes)...");
  79. final short value = in.readShort();
  80. OLogManager.instance().debug(this, "Read short: " + value);
  81. return value;
  82. }
  83. return in.readShort();
  84. }
  85. public String readString() throws IOException {
  86. if (debug) {
  87. OLogManager.instance().debug(this, "Reading string (4+N bytes)...");
  88. byte[] buffer = readBytes();
  89. if (buffer == null)
  90. return null;
  91. String value = new String(buffer);
  92. OLogManager.instance().debug(this, "Read string: " + value);
  93. return value;
  94. }
  95. final byte[] buffer = readBytes();
  96. if (buffer == null)
  97. return null;
  98. return new String(buffer);
  99. }
  100. public byte[] readBytes() throws IOException {
  101. if (debug)
  102. OLogManager.instance().debug(this, "Reading chunk of bytes. Reading chunk length as int (4 bytes)...");
  103. final int len = in.readInt();
  104. if (debug)
  105. OLogManager.instance().debug(this, "Read chunk lenght: " + len);
  106. if (len < 0)
  107. return null;
  108. if (debug)
  109. OLogManager.instance().debug(this, "Reading " + len + " bytes...");
  110. final byte[] tmp = new byte[len];
  111. in.readFully(tmp);
  112. if (debug)
  113. OLogManager.instance().debug(this, "Read " + len + " bytes: " + new String(tmp));
  114. return tmp;
  115. }
  116. public List<String> readStringList() throws IOException {
  117. if (debug)
  118. OLogManager.instance().debug(this, "Reading string list. Reading string list items as int (4 bytes)...");
  119. final int items = in.readInt();
  120. if (debug)
  121. OLogManager.instance().debug(this, "Read string list items: " + items);
  122. if (items < 0)
  123. return null;
  124. List<String> result = new ArrayList<String>();
  125. for (int i = 0; i < items; ++i)
  126. result.add(readString());
  127. if (debug)
  128. OLogManager.instance().debug(this, "Read string list with %d items: ", items);
  129. return result;
  130. }
  131. public Set<String> readStringSet() throws IOException {
  132. if (debug)
  133. OLogManager.instance().debug(this, "Reading string set. Reading string set items as int (4 bytes)...");
  134. int items = in.readInt();
  135. if (debug)
  136. OLogManager.instance().debug(this, "Read string set items: " + items);
  137. if (items < 0)
  138. return null;
  139. Set<String> result = new HashSet<String>();
  140. for (int i = 0; i < items; ++i)
  141. result.add(readString());
  142. if (debug)
  143. OLogManager.instance().debug(this, "Read string set with %d items: ", items);
  144. return result;
  145. }
  146. public ORecordId readRID() throws IOException {
  147. return new ORecordId(readShort(), readLong());
  148. }
  149. public void writeByte(final byte iContent) throws IOException {
  150. if (debug)
  151. OLogManager.instance().debug(this, "Writing byte (1 byte): %d", iContent);
  152. out.write(iContent);
  153. }
  154. public void writeInt(final int iContent) throws IOException {
  155. if (debug)
  156. OLogManager.instance().debug(this, "Writing int (4 bytes): %d", iContent);
  157. out.writeInt(iContent);
  158. }
  159. public void writeLong(final long iContent) throws IOException {
  160. if (debug)
  161. OLogManager.instance().debug(this, "Writing long (8 bytes): %d", iContent);
  162. out.writeLong(iContent);
  163. }
  164. public void writeShort(final short iContent) throws IOException {
  165. if (debug)
  166. OLogManager.instance().debug(this, "Writing long (2 bytes): %d", iContent);
  167. out.writeShort(iContent);
  168. }
  169. public OChannelBinary writeString(final String iContent) throws IOException {
  170. if (debug)
  171. OLogManager.instance().debug(this, "Writing string (4+%d=%d bytes): %s", iContent != null ? iContent.length() : 0,
  172. iContent != null ? iContent.length() + 4 : 4, iContent);
  173. if (iContent == null)
  174. out.writeInt(-1);
  175. else
  176. writeBytes(iContent.getBytes());
  177. return this;
  178. }
  179. public OChannelBinary writeBytes(final byte[] iContent) throws IOException {
  180. return writeBytes(iContent, iContent != null ? iContent.length : 0);
  181. }
  182. public OChannelBinary writeBytes(final byte[] iContent, final int iLength) throws IOException {
  183. if (debug)
  184. OLogManager.instance().debug(this, "Writing bytes (4+%d=%d bytes): %s", iLength, iLength + 4, iContent);
  185. if (iContent == null) {
  186. out.writeInt(-1);
  187. } else {
  188. out.writeInt(iLength);
  189. out.write(iContent, 0, iLength);
  190. }
  191. return this;
  192. }
  193. public OChannelBinary writeCollectionString(final Collection<String> iCollection) throws IOException {
  194. if (debug)
  195. OLogManager.instance().debug(this, "Writing strings (4+%d=%d items): %s", iCollection != null ? iCollection.size() : 0,
  196. iCollection != null ? iCollection.size() + 4 : 4, iCollection.toString());
  197. if (iCollection == null)
  198. writeInt(-1);
  199. else {
  200. writeInt(iCollection.size());
  201. int i = 0;
  202. for (String s : iCollection) {
  203. writeString(s);
  204. i++;
  205. }
  206. }
  207. return this;
  208. }
  209. public void writeRID(final ORID iRID) throws IOException {
  210. writeShort((short) iRID.getClusterId());
  211. writeLong(iRID.getClusterPosition());
  212. }
  213. public void clearInput() throws IOException {
  214. if (in != null)
  215. while (in.available() > 0)
  216. in.read();
  217. }
  218. @Override
  219. public void flush() throws IOException {
  220. super.flush();
  221. out.flush();
  222. }
  223. @Override
  224. public void close() {
  225. try {
  226. if (in != null)
  227. in.close();
  228. } catch (IOException e) {
  229. }
  230. try {
  231. if (out != null)
  232. out.close();
  233. } catch (IOException e) {
  234. }
  235. super.close();
  236. }
  237. public int readStatus() throws IOException {
  238. // READ THE RESPONSE
  239. return handleStatus(readByte(), readInt());
  240. }
  241. protected int handleStatus(final byte iResult, final int iClientTxId) throws IOException {
  242. if (iResult == OChannelBinaryProtocol.RESPONSE_STATUS_OK || iResult == OChannelBinaryProtocol.PUSH_DATA) {
  243. } else if (iResult == OChannelBinaryProtocol.RESPONSE_STATUS_ERROR) {
  244. StringBuilder buffer = new StringBuilder();
  245. final List<OPair<String, String>> exceptions = new ArrayList<OPair<String, String>>();
  246. // EXCEPTION
  247. while (readByte() == 1) {
  248. final String excClassName = readString();
  249. final String excMessage = readString();
  250. exceptions.add(new OPair<String, String>(excClassName, excMessage));
  251. }
  252. Exception previous = null;
  253. for (int i = exceptions.size() - 1; i > -1; --i) {
  254. previous = createException(exceptions.get(i).getKey(), exceptions.get(i).getValue(), previous);
  255. }
  256. if (previous != null) {
  257. if (previous instanceof RuntimeException)
  258. throw (RuntimeException) previous;
  259. else
  260. throw new ODatabaseException("Generic error, see the underlying cause", previous);
  261. } else
  262. throw new ONetworkProtocolException("Network response error: " + buffer.toString());
  263. } else {
  264. // PROTOCOL ERROR
  265. // close();
  266. throw new ONetworkProtocolException("Error on reading response from the server");
  267. }
  268. return iClientTxId;
  269. }
  270. @SuppressWarnings("unchecked")
  271. private static RuntimeException createException(final String iClassName, final String iMessage, final Exception iPrevious) {
  272. RuntimeException rootException = null;
  273. Constructor<?> c = null;
  274. try {
  275. final Class<RuntimeException> excClass = (Class<RuntimeException>) Class.forName(iClassName);
  276. if (iPrevious != null) {
  277. try {
  278. c = excClass.getConstructor(String.class, Throwable.class);
  279. } catch (NoSuchMethodException e) {
  280. c = excClass.getConstructor(String.class, Exception.class);
  281. }
  282. }
  283. if (c == null)
  284. c = excClass.getConstructor(String.class);
  285. } catch (Exception e) {
  286. // UNABLE TO REPRODUCE THE SAME SERVER-SIZE EXCEPTION: THROW A STORAGE EXCEPTION
  287. rootException = new OStorageException(iMessage, iPrevious);
  288. }
  289. if (c != null)
  290. try {
  291. if (c.getParameterTypes().length > 1)
  292. rootException = (RuntimeException) c.newInstance(iMessage, iPrevious);
  293. else
  294. rootException = (RuntimeException) c.newInstance(iMessage);
  295. } catch (InstantiationException e) {
  296. } catch (IllegalAccessException e) {
  297. } catch (InvocationTargetException e) {
  298. }
  299. return rootException;
  300. }
  301. public byte[] getBuffer() {
  302. return buffer;
  303. }
  304. public int getMaxChunkSize() {
  305. return maxChunkSize;
  306. }
  307. }