github.com/keysonZZZ/kmg@v0.0.0-20151121023212-05317bfd7d39/kmgRpc/kmgRpcJava/tplGenerateCode.go (about)

     1  package kmgRpcJava
     2  
     3  import (
     4  	"bytes"
     5  )
     6  
     7  func tplGenerateCode(config *tplConfig) string {
     8  	var _buf bytes.Buffer
     9  	_buf.WriteString(`
    10  package `)
    11  	_buf.WriteString(config.OutPackageName)
    12  	_buf.WriteString(`;
    13  
    14  import com.google.gson.Gson;
    15  import com.google.gson.GsonBuilder;
    16  import com.google.gson.JsonDeserializationContext;
    17  import com.google.gson.JsonDeserializer;
    18  import com.google.gson.JsonElement;
    19  import com.google.gson.JsonParseException;
    20  import com.google.gson.JsonPrimitive;
    21  import com.google.gson.JsonSerializationContext;
    22  import com.google.gson.JsonSerializer;
    23  import com.google.gson.JsonSyntaxException;
    24  
    25  import javax.crypto.Cipher;
    26  import javax.crypto.spec.IvParameterSpec;
    27  import javax.crypto.spec.SecretKeySpec;
    28  import java.io.ByteArrayOutputStream;
    29  import java.io.IOException;
    30  import java.io.InputStream;
    31  import java.io.OutputStream;
    32  import java.lang.reflect.Type;
    33  import java.net.HttpURLConnection;
    34  import java.net.URL;
    35  import java.nio.charset.Charset;
    36  import java.security.MessageDigest;
    37  import java.security.SecureRandom;
    38  import java.util.Arrays;
    39  import java.util.Calendar;
    40  import java.util.Date;
    41  import java.util.List;
    42  import java.util.SimpleTimeZone;
    43  import java.util.TimeZone;
    44  import java.util.zip.Deflater;
    45  import java.util.zip.Inflater;
    46  
    47  /*
    48      example:
    49          RpcDemo.ConfigDefaultClient("http://127.0.0.1:34567","abc psk") // added in some init function.
    50          String result = RpcDemo.GetDefaultClient().PostScoreInt("abc",1) // use the rpc everywhere.
    51   */
    52  
    53  public class `)
    54  	_buf.WriteString(config.ClassName)
    55  	_buf.WriteString(` {
    56      //类型列表
    57      `)
    58  	for _, innerClass := range config.InnerClassList {
    59  		_buf.WriteString(`
    60          `)
    61  		_buf.WriteString(innerClass.tplInnerClass())
    62  		_buf.WriteString(`
    63      `)
    64  	}
    65  	_buf.WriteString(`
    66  
    67      public static class Client{
    68          // 所有Api列表
    69          `)
    70  	for _, api := range config.ApiList {
    71  		_buf.WriteString(`
    72              `)
    73  		_buf.WriteString(api.tplApiClient())
    74  		_buf.WriteString(`
    75          `)
    76  	}
    77  	_buf.WriteString(`
    78  
    79  
    80          //引入的不会变的库代码.还需要com.google.gson 这个package的依赖
    81          public String RemoteUrl;
    82          public byte[] Psk;
    83          private <T> T sendRequest(String apiName,Object reqData,Class<T> tClass) throws Exception{
    84              String inDataString = kmgJson.MarshalToString(reqData); // UTF8? 啥编码?
    85              if (apiName.length()>255){
    86                  throw new Exception("len(apiName)>255");
    87              }
    88              ByteArrayOutputStream baos = new ByteArrayOutputStream();
    89              baos.write(apiName.length());
    90              baos.write(KmgString.StringToArrayByte(apiName));
    91              baos.write(KmgString.StringToArrayByte(inDataString));
    92              byte[] inByte = baos.toByteArray();
    93              if (this.Psk!=null){
    94                  inByte = kmgCrypto.CompressAndEncryptBytesEncodeV2(this.Psk, inByte);
    95              }
    96              byte[] outBytes =  kmgHttp.SimplePost(this.RemoteUrl, inByte);
    97              outBytes = kmgCrypto.CompressAndEncryptBytesDecodeV2(this.Psk, outBytes);
    98              if (outBytes.length==0){
    99                  throw new Exception("outBytes.length==0");
   100              }
   101              String AfterString = KmgString.ArrayByteToString(Arrays.copyOfRange(outBytes,1,outBytes.length));
   102              if (outBytes[0]==1){ //error
   103                  throw new Exception(AfterString);
   104              }else if (outBytes[0]==2) { //success
   105                  return kmgJson.UnmarshalFromString(AfterString, tClass);
   106              }
   107              throw new Exception("httpjsonApi protocol error 1 "+outBytes[0]);
   108          }
   109      }
   110      public static void ConfigDefaultClient(String RemoteUrl,String pskStr){
   111          defaultClient = new Client();
   112          defaultClient.RemoteUrl = RemoteUrl;
   113          defaultClient.Psk = kmgCrypto.Get32PskFromString(pskStr);
   114      }
   115      private static Client defaultClient;
   116      public static Client GetDefaultClient(){
   117          return defaultClient;
   118      }
   119      public static class KmgString{
   120          public static final Charset UTF_8 = Charset.forName("UTF-8");
   121          public static byte[] StringToArrayByte(String str){
   122              return str.getBytes(UTF_8);
   123          }
   124          public static String ArrayByteToString(byte[] bytes){
   125              return new String(bytes, UTF_8);
   126          }
   127      }
   128      public static class kmgBytes {
   129          public static byte[] Slice(byte[] in,int start,int end){
   130              return Arrays.copyOfRange(in,start,end);
   131          }
   132      }
   133      public static class kmgIo {
   134          private static final int EOF = -1;
   135          public static byte[] InputStreamReadAll(final InputStream input) throws IOException {
   136              final ByteArrayOutputStream output = new ByteArrayOutputStream();
   137              copy(input, output);
   138              return output.toByteArray();
   139          }
   140          public static int copy(final InputStream input, final OutputStream output) throws IOException {
   141              final long count = copyLarge(input, output,new byte[8192]);
   142              if (count > Integer.MAX_VALUE) {
   143                  return -1;
   144              }
   145              return (int) count;
   146          }
   147          public static long copyLarge(final InputStream input, final OutputStream output, final byte[] buffer)
   148                  throws IOException {
   149              long count = 0;
   150              int n = 0;
   151              while (EOF != (n = input.read(buffer))) {
   152                  output.write(buffer, 0, n);
   153                  count += n;
   154              }
   155              return count;
   156          }
   157      }
   158      public static class kmgHttp {
   159          public static byte[] SimplePost(String urls,byte[] inByte) throws Exception{
   160              System.setProperty("http.keepAlive", "false");
   161              URL url = new URL(urls);
   162              HttpURLConnection conn = (HttpURLConnection)url.openConnection();
   163              conn.setRequestMethod("POST");
   164              conn.setRequestProperty("Content-Type", "image/jpeg");
   165              conn.setUseCaches(false);
   166              conn.setDoInput(true);
   167              conn.setDoOutput(true);
   168              conn.setReadTimeout(10000);
   169              conn.setConnectTimeout(5000);
   170              OutputStream os = conn.getOutputStream();
   171              os.write(inByte);
   172              os.flush();
   173              os.close();
   174              InputStream is;
   175              if (conn.getResponseCode()==200){
   176                  is = conn.getInputStream();
   177              }else{
   178                  is = conn.getErrorStream();
   179              }
   180              byte[] outByte = kmgIo.InputStreamReadAll(is);
   181              is.close();
   182              return outByte;
   183          }
   184      }
   185      public static class kmgCrypto {
   186          private static byte[] magicCode4 = new byte[]{(byte)0xa7,(byte)0x97,0x6d,0x15};
   187          // key lenth 32
   188          public static byte[] CompressAndEncryptBytesEncodeV2(byte[] key,byte[] data) throws Exception{
   189              data = compressV2(data);
   190              byte[] cbcIv = KmgRand.MustCryptoRandBytes(16);
   191              ByteArrayOutputStream buf = new ByteArrayOutputStream();
   192              buf.write(data);
   193              buf.write(magicCode4);
   194              Cipher cipher = Cipher.getInstance("AES/CTR/NoPadding");
   195              cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(key, "AES"), new IvParameterSpec(cbcIv));
   196              byte[] encrypted = cipher.doFinal(buf.toByteArray());
   197              buf = new ByteArrayOutputStream();
   198              buf.write(cbcIv);
   199              buf.write(encrypted);
   200              return buf.toByteArray();
   201          }
   202          // key lenth 32
   203          public static byte[] CompressAndEncryptBytesDecodeV2(byte[] key,byte[] data) throws Exception {
   204              if (data.length < 21) {
   205                  throw new Exception("[kmgCrypto.CompressAndEncryptBytesDecode] input data too small");
   206              }
   207              byte[] cbcIv = kmgBytes.Slice(data, 0, 16);
   208              byte[] encrypted = kmgBytes.Slice(data, 16, data.length);
   209              Cipher cipher = Cipher.getInstance("AES/CTR/NoPadding");
   210              cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(key, "AES"), new IvParameterSpec(cbcIv));
   211              byte[] decrypted = cipher.doFinal(encrypted);
   212              byte[] compressed = kmgBytes.Slice(decrypted, 0, decrypted.length - 4);
   213              if (!Arrays.equals(magicCode4, kmgBytes.Slice(decrypted, decrypted.length - 4, decrypted.length))){
   214                  throw new Exception("[kmgCrypto.CompressAndEncryptBytesDecode] magicCode not match");
   215              }
   216              return uncompressV2(compressed);
   217          }
   218          private static byte[] compressV2(byte[] data) throws Exception{
   219              byte[] outData = kmgCompress.ZlibMustCompress(data);
   220              if (outData.length>=data.length){
   221                  ByteArrayOutputStream buf = new ByteArrayOutputStream();
   222                  buf.write(0);
   223                  buf.write(data);
   224                  return buf.toByteArray();
   225              }else{
   226                  ByteArrayOutputStream buf = new ByteArrayOutputStream();
   227                  buf.write(1);
   228                  buf.write(outData);
   229                  return buf.toByteArray();
   230              }
   231          }
   232          private static byte[] uncompressV2(byte[] data) throws Exception{
   233              if (data.length==0){
   234                  throw new Exception("[uncopressV2] len(inData)==0");
   235              }
   236              if (data[0]==0){
   237                  return kmgBytes.Slice(data, 1, data.length);
   238              }
   239              return kmgCompress.ZlibUnCompress(kmgBytes.Slice(data, 1, data.length));
   240          }
   241          public static byte[] Sha512Sum(byte[] data) {
   242              try {
   243                  MessageDigest sh = MessageDigest.getInstance("SHA-512");
   244                  sh.update(data);
   245                  return sh.digest();
   246              }catch(Exception e){
   247                  System.out.println(e.getMessage());
   248                  e.printStackTrace();
   249              }
   250              return null;
   251          }
   252          public static byte[] Get32PskFromString(String s){
   253              return kmgBytes.Slice(kmgCrypto.Sha512Sum(KmgString.StringToArrayByte(s)), 0, 32);
   254          }
   255      }
   256      public static class kmgCompress {
   257          public static byte[] ZlibMustCompress(byte[] inB){
   258              Deflater deflater = new Deflater();
   259              deflater.setInput(inB);
   260              deflater.finish();
   261              ByteArrayOutputStream baos = new ByteArrayOutputStream();
   262              byte[] buf = new byte[8192];
   263              while (!deflater.finished()) {
   264                  int byteCount = deflater.deflate(buf);
   265                  baos.write(buf, 0, byteCount);
   266              }
   267              deflater.end();
   268              byte[] out = baos.toByteArray();
   269              return out;
   270          }
   271          public static byte[] ZlibUnCompress(byte[] inB) throws Exception{
   272              Inflater deflater = new Inflater();
   273              deflater.setInput(inB);
   274              ByteArrayOutputStream baos = new ByteArrayOutputStream();
   275              byte[] buf = new byte[8192];
   276              while (!deflater.finished()) {
   277                  int byteCount = deflater.inflate(buf);
   278                  if (byteCount==0){
   279                      break;
   280                  }
   281                  baos.write(buf, 0, byteCount);
   282              }
   283              deflater.end();
   284              return baos.toByteArray();
   285          }
   286      }
   287      public static class kmgSync {
   288          public static class Once{
   289              private Object locker = new Object();
   290              private boolean isInit = false;
   291              public void Do(Runnable f){
   292                  synchronized (locker){
   293                      if (isInit){
   294                          return;
   295                      }
   296                      f.run();
   297                      isInit = true;
   298                  }
   299              }
   300          }
   301      }
   302      public static class kmgJson {
   303          public static String MarshalToString(Object data){
   304              return getGson().toJson(data);
   305          }
   306          public static<T> T UnmarshalFromString(String s,Class<T> t) throws JsonSyntaxException {
   307              if (t==void.class){
   308                  return null;
   309              }
   310              return getGson().fromJson(s,t);
   311          }
   312          private static Gson gson;
   313          private static kmgSync.Once gsonOnce = new kmgSync.Once();
   314          private static Gson getGson(){
   315              gsonOnce.Do(new Runnable() {
   316                  @Override
   317                  public void run() {
   318                      JsonSerializer<Date> ser = new JsonSerializer<Date>() {
   319                          @Override
   320                          public JsonElement serialize(Date src, Type typeOfSrc, JsonSerializationContext
   321                                  context) {
   322                              if (src == null) {
   323                                  return null;
   324                              } else {
   325                                  return new JsonPrimitive(KmgTime.FormatGolangDate(src));
   326                              }
   327                          }
   328                      };
   329                      JsonDeserializer<Date> deser = new JsonDeserializer<Date>() {
   330                          @Override
   331                          public Date deserialize(JsonElement json, Type typeOfT,
   332                                                  JsonDeserializationContext context) throws JsonParseException {
   333                              if (json == null) {
   334                                  return null;
   335                              } else {
   336                                  try {
   337                                      return KmgTime.ParseGolangDate(json.getAsString());
   338                                  } catch (Exception e) {
   339                                      throw new JsonParseException(e.getMessage());
   340                                  }
   341                              }
   342                          }
   343                      };
   344                      gson = new GsonBuilder()
   345                              .registerTypeAdapter(Date.class, ser)
   346                              .registerTypeAdapter(Date.class, deser).create();
   347                  }
   348              });
   349              return gson;
   350          }
   351      }
   352      public static class KmgRand{
   353          public static byte[] MustCryptoRandBytes(int length) {
   354              SecureRandom sr = new SecureRandom();
   355              byte[] output = new byte[length];
   356              sr.nextBytes(output);
   357              return output;
   358          }
   359      }
   360      public static class KmgTime{
   361          public static Date ParseGolangDate(String st) throws Exception{
   362              Calendar cal = Calendar.getInstance();
   363              int year = Integer.parseInt(st.substring(0, 4));
   364              int month = Integer.parseInt(st.substring(5,7));
   365              int day = Integer.parseInt(st.substring(8,10));
   366              int hour = Integer.parseInt(st.substring(11, 13));
   367              int minute = Integer.parseInt(st.substring(14,16));
   368              int second = Integer.parseInt(st.substring(17,19));
   369              float nonaSecond = 0;
   370              int tzStartPos = 19;
   371              if (st.charAt(19)=='.'){
   372                  // 从19开始找到第一个不是数字的字符串.
   373                  for (;;){
   374                      tzStartPos++;
   375                      if (st.length()<=tzStartPos){
   376                          throw new Exception("can not parse "+st);
   377                      }
   378                      char thisChar = st.charAt(tzStartPos);
   379                      if (thisChar>='0' && thisChar<='9'){
   380                      }else{
   381                          break;
   382                      }
   383                  }
   384                  nonaSecond = Float.parseFloat("0." + st.substring(20, tzStartPos));
   385              }
   386              cal.set(Calendar.MILLISECOND,(int)(nonaSecond*1e3));
   387              char tzStart = st.charAt(tzStartPos);
   388              if (tzStart=='Z'){
   389                  cal.setTimeZone(TimeZone.getTimeZone("UTC"));
   390              }else {
   391                  int tzHour = Integer.parseInt(st.substring(tzStartPos+1,tzStartPos+3));
   392                  int tzMin = Integer.parseInt(st.substring(tzStartPos+4,tzStartPos+6));
   393                  int tzOffset = tzHour*3600*1000 + tzMin * 60*1000;
   394                  if (tzStart=='-'){
   395                      tzOffset = - tzOffset;
   396                  }
   397                  TimeZone tz = new SimpleTimeZone(tzOffset,"");
   398                  cal.setTimeZone(tz);
   399              }
   400              cal.set(year,month-1,day,hour,minute,second);
   401              return cal.getTime();
   402          }
   403          public static String FormatGolangDate(Date date){
   404              Calendar cal = Calendar.getInstance();
   405              cal.setTime(date);
   406              StringBuilder buf = new StringBuilder();
   407              formatYear(cal,buf);
   408              buf.append('-');
   409              formatMonth(cal, buf);
   410              buf.append('-');
   411              formatDays(cal, buf);
   412              buf.append('T');
   413              formatHours(cal, buf);
   414              buf.append(':');
   415              formatMinutes(cal, buf);
   416              buf.append(':');
   417              formatSeconds(cal,buf);
   418              formatTimeZone(cal,buf);
   419              return buf.toString();
   420          }
   421          private static void formatYear(Calendar cal, StringBuilder buf) {
   422              int year = cal.get(Calendar.YEAR);
   423              String s;
   424              if (year <= 0) // negative value
   425              {
   426                  s = Integer.toString(1 - year);
   427              } else // positive value
   428              {
   429                  s = Integer.toString(year);
   430              }
   431              while (s.length() < 4) {
   432                  s = '0' + s;
   433              }
   434              if (year <= 0) {
   435                  s = '-' + s;
   436              }
   437              buf.append(s);
   438          }
   439          private static void formatMonth(Calendar cal, StringBuilder buf) {
   440              formatTwoDigits(cal.get(Calendar.MONTH) + 1, buf);
   441          }
   442          private static void formatDays(Calendar cal, StringBuilder buf) {
   443              formatTwoDigits(cal.get(Calendar.DAY_OF_MONTH), buf);
   444          }
   445          private static void formatHours(Calendar cal, StringBuilder buf) {
   446              formatTwoDigits(cal.get(Calendar.HOUR_OF_DAY), buf);
   447          }
   448          private static void formatMinutes(Calendar cal, StringBuilder buf) {
   449              formatTwoDigits(cal.get(Calendar.MINUTE), buf);
   450          }
   451          private static void formatSeconds(Calendar cal, StringBuilder buf) {
   452              formatTwoDigits(cal.get(Calendar.SECOND), buf);
   453              if (cal.isSet(Calendar.MILLISECOND)) { // milliseconds
   454                  int n = cal.get(Calendar.MILLISECOND);
   455                  if (n != 0) {
   456                      String ms = Integer.toString(n);
   457                      while (ms.length() < 3) {
   458                          ms = '0' + ms; // left 0 paddings.
   459                      }
   460                      buf.append('.');
   461                      buf.append(ms);
   462                  }
   463              }
   464          }
   465          /** formats time zone specifier. */
   466          private static void formatTimeZone(Calendar cal, StringBuilder buf) {
   467              TimeZone tz = cal.getTimeZone();
   468              if (tz == null) {
   469                  return;
   470              }
   471              // otherwise print out normally.
   472              int offset = tz.getOffset(cal.getTime().getTime());
   473              if (offset == 0) {
   474                  buf.append('Z');
   475                  return;
   476              }
   477              if (offset >= 0) {
   478                  buf.append('+');
   479              } else {
   480                  buf.append('-');
   481                  offset *= -1;
   482              }
   483              offset /= 60 * 1000; // offset is in milli-seconds
   484              formatTwoDigits(offset / 60, buf);
   485              buf.append(':');
   486              formatTwoDigits(offset % 60, buf);
   487          }
   488          /** formats Integer into two-character-wide string. */
   489          private static void formatTwoDigits(int n, StringBuilder buf) {
   490              // n is always non-negative.
   491              if (n < 10) {
   492                  buf.append('0');
   493              }
   494              buf.append(n);
   495          }
   496      }
   497  }
   498  
   499  
   500  `)
   501  	return _buf.String()
   502  }