Package org.jboss.mx.loading

Source Code of org.jboss.mx.loading.RepositoryClassLoader

/*     */ package org.jboss.mx.loading;
/*     */
/*     */ import EDU.oswego.cs.dl.util.concurrent.ConcurrentReaderHashMap;
/*     */ import EDU.oswego.cs.dl.util.concurrent.ReentrantLock;
/*     */ import java.io.ByteArrayOutputStream;
/*     */ import java.io.IOException;
/*     */ import java.io.InputStream;
/*     */ import java.net.MalformedURLException;
/*     */ import java.net.URL;
/*     */ import java.net.URLClassLoader;
/*     */ import java.security.CodeSource;
/*     */ import java.security.PermissionCollection;
/*     */ import java.security.Policy;
/*     */ import java.security.ProtectionDomain;
/*     */ import java.security.cert.Certificate;
/*     */ import java.util.Collections;
/*     */ import java.util.Enumeration;
/*     */ import java.util.HashSet;
/*     */ import java.util.Set;
/*     */ import java.util.Vector;
/*     */ import javax.management.ObjectName;
/*     */ import org.jboss.classloading.spi.RealClassLoader;
/*     */ import org.jboss.logging.Logger;
/*     */ import org.jboss.util.collection.SoftSet;
/*     */ import org.jboss.util.loading.Translator;
/*     */
/*     */ public abstract class RepositoryClassLoader extends URLClassLoader
/*     */   implements RealClassLoader
/*     */ {
/*  63 */   private static final Logger log = Logger.getLogger(RepositoryClassLoader.class);
/*     */
/*  66 */   private static final URL[] EMPTY_URL_ARRAY = new URL[0];
/*     */
/*  71 */   protected LoaderRepository repository = null;
/*     */   protected Exception unregisterTrace;
/*     */   private int addedOrder;
/*  79 */   protected ClassLoader parent = null;
/*     */
/*  82 */   private Set classBlackList = Collections.synchronizedSet(new SoftSet());
/*     */
/*  84 */   private Set resourceBlackList = Collections.synchronizedSet(new HashSet());
/*     */
/*  86 */   private ConcurrentReaderHashMap resourceCache = new ConcurrentReaderHashMap();
/*     */
/*  89 */   protected ReentrantLock loadLock = new ReentrantLock();
/*     */   protected int loadClassDepth;
/*     */
/*     */   protected RepositoryClassLoader(URL[] urls, ClassLoader parent)
/*     */   {
/* 106 */     super(urls, parent);
/* 107 */     this.parent = parent;
/*     */
/* 109 */     String mode = ClassToStringAction.getProperty("org.jboss.mx.loading.blacklistMode", null);
/* 110 */     if ((mode == null) || (mode.equalsIgnoreCase("HashSet")))
/*     */     {
/* 112 */       this.classBlackList = Collections.synchronizedSet(new HashSet());
/* 113 */       this.resourceBlackList = Collections.synchronizedSet(new HashSet());
/*     */     }
/* 115 */     else if (mode.equalsIgnoreCase("SoftSet"))
/*     */     {
/* 117 */       this.classBlackList = Collections.synchronizedSet(new SoftSet());
/* 118 */       this.resourceBlackList = Collections.synchronizedSet(new SoftSet());
/*     */     }
/*     */   }
/*     */
/*     */   public abstract ObjectName getObjectName();
/*     */
/*     */   public boolean isValid()
/*     */   {
/* 133 */     return getLoaderRepository() != null;
/*     */   }
/*     */
/*     */   public LoaderRepository getLoaderRepository()
/*     */   {
/* 141 */     return this.repository;
/*     */   }
/*     */
/*     */   public void setRepository(LoaderRepository repository)
/*     */   {
/* 151 */     log.debug("setRepository, repository=" + repository + ", cl=" + this);
/* 152 */     this.repository = repository;
/*     */   }
/*     */
/*     */   public Class<?> getCachedClass(String name)
/*     */   {
/* 157 */     LoaderRepository repository = this.repository;
/* 158 */     if (repository == null)
/* 159 */       return null;
/* 160 */     return repository.getCachedClass(name);
/*     */   }
/*     */
/*     */   public URL getCachedResource(String name)
/*     */   {
/* 166 */     return null;
/*     */   }
/*     */
/*     */   public void clearBlackList(String name)
/*     */   {
/*     */   }
/*     */
/*     */   public int getAddedOrder()
/*     */   {
/* 181 */     return this.addedOrder;
/*     */   }
/*     */
/*     */   public void setAddedOrder(int addedOrder)
/*     */   {
/* 191 */     this.addedOrder = addedOrder;
/*     */   }
/*     */
/*     */   public Class loadClassLocally(String name, boolean resolve)
/*     */     throws ClassNotFoundException
/*     */   {
/* 200 */     boolean trace = log.isTraceEnabled();
/* 201 */     if (trace)
/* 202 */       log.trace("loadClassLocally, " + this + " name=" + name);
/* 203 */     if ((name == null) || (name.length() == 0)) {
/* 204 */       throw new ClassNotFoundException("Null or empty class name");
/*     */     }
/* 206 */     Class result = null;
/*     */     try
/*     */     {
/* 209 */       if (isClassBlackListed(name))
/*     */       {
/* 211 */         if (trace)
/* 212 */           log.trace("Class in blacklist, name=" + name);
/* 213 */         throw new ClassNotFoundException("Class Not Found(blacklist): " + name);
/*     */       }
/*     */       ClassLoader systemClassLoader;
/*     */       Class localClass1;
/* 217 */       if (name.startsWith("java."))
/*     */       {
/* 219 */         systemClassLoader = ClassLoader.getSystemClassLoader();
/* 220 */         localClass1 = systemClassLoader.loadClass(name);
/*     */         return localClass1;
/*     */       }
/*     */       try
/*     */       {
/* 225 */         result = super.loadClass(name, resolve);
/* 226 */         systemClassLoader = result;
/*     */
/* 245 */         if (trace)
/*     */         {
/* 247 */           if (result != null)
/* 248 */             log.trace("loadClassLocally, " + this + " name=" + name + " class=" + result + " cl=" + result.getClassLoader());
/*     */           else
/* 250 */             log.trace("loadClassLocally, " + this + " name=" + name + " not found");
/* 250 */         }return systemClassLoader;
/*     */       }
/*     */       catch (ClassNotFoundException cnfe)
/*     */       {
/* 230 */         addToClassBlackList(name);
/*     */
/* 232 */         if (name.charAt(0) == '[')
/*     */         {
/* 234 */           result = Class.forName(name, true, this);
/* 235 */           removeFromClassBlackList(name);
/* 236 */           localClass1 = result;
/*     */
/* 245 */           if (trace)
/*     */           {
/* 247 */             if (result != null)
/* 248 */               log.trace("loadClassLocally, " + this + " name=" + name + " class=" + result + " cl=" + result.getClassLoader());
/*     */             else
/* 250 */               log.trace("loadClassLocally, " + this + " name=" + name + " not found");
/* 250 */           }return localClass1;
/*     */         }
/* 238 */         if (trace)
/* 239 */           log.trace("CFNE: Adding to blacklist: " + name);
/* 240 */         throw cnfe;
/*     */       }
/*     */     }
/*     */     finally
/*     */     {
/* 245 */       if (trace)
/*     */       {
/* 247 */         if (result != null)
/* 248 */           log.trace("loadClassLocally, " + this + " name=" + name + " class=" + result + " cl=" + result.getClassLoader());
/*     */         else
/* 250 */           log.trace("loadClassLocally, " + this + " name=" + name + " not found");
/*     */       }
/* 250 */     }throw localObject;
/*     */   }
/*     */
/*     */   public URL getResourceLocally(String name)
/*     */   {
/* 260 */     URL resURL = (URL)this.resourceCache.get(name);
/* 261 */     if (resURL != null)
/* 262 */       return resURL;
/* 263 */     if (isResourceBlackListed(name))
/* 264 */       return null;
/* 265 */     resURL = super.getResource(name);
/* 266 */     if (log.isTraceEnabled() == true)
/* 267 */       log.trace("getResourceLocally(" + this + "), name=" + name + ", resURL:" + resURL);
/* 268 */     if (resURL == null)
/* 269 */       addToResourceBlackList(name);
/*     */     else
/* 271 */       this.resourceCache.put(name, resURL);
/* 272 */     return resURL;
/*     */   }
/*     */
/*     */   public URL getURL()
/*     */   {
/* 282 */     URL[] urls = super.getURLs();
/* 283 */     if (urls.length > 0) {
/* 284 */       return urls[0];
/*     */     }
/* 286 */     return null;
/*     */   }
/*     */
/*     */   public void unregister()
/*     */   {
/* 291 */     log.debug("Unregistering cl=" + this);
/* 292 */     if (this.repository != null)
/* 293 */       this.repository.removeClassLoader(this);
/* 294 */     clearBlacklists();
/* 295 */     this.resourceCache.clear();
/* 296 */     this.repository = null;
/* 297 */     this.unregisterTrace = new Exception();
/*     */   }
/*     */
/*     */   public URL[] getClasspath()
/*     */   {
/* 308 */     return super.getURLs();
/*     */   }
/*     */
/*     */   public URL[] getAllURLs()
/*     */   {
/* 318 */     return this.repository.getURLs();
/*     */   }
/*     */
/*     */   public void addToClassBlackList(String name)
/*     */   {
/* 328 */     this.classBlackList.add(name);
/*     */   }
/*     */
/*     */   public void removeFromClassBlackList(String name)
/*     */   {
/* 338 */     this.classBlackList.remove(name);
/*     */   }
/*     */
/*     */   public boolean isClassBlackListed(String name)
/*     */   {
/* 349 */     return this.classBlackList.contains(name);
/*     */   }
/*     */
/*     */   public void clearClassBlackList()
/*     */   {
/* 357 */     this.classBlackList.clear();
/*     */   }
/*     */
/*     */   public void addToResourceBlackList(String name)
/*     */   {
/* 367 */     this.resourceBlackList.add(name);
/*     */   }
/*     */
/*     */   public void removeFromResourceBlackList(String name)
/*     */   {
/* 377 */     this.resourceBlackList.remove(name);
/*     */   }
/*     */
/*     */   public boolean isResourceBlackListed(String name)
/*     */   {
/* 388 */     return this.resourceBlackList.contains(name);
/*     */   }
/*     */
/*     */   public void clearResourceBlackList()
/*     */   {
/* 396 */     this.resourceBlackList.clear();
/*     */   }
/*     */
/*     */   public void clearBlacklists()
/*     */   {
/* 404 */     clearClassBlackList();
/* 405 */     clearResourceBlackList();
/*     */   }
/*     */
/*     */   public Class loadClass(String name, boolean resolve)
/*     */     throws ClassNotFoundException
/*     */   {
/* 421 */     boolean trace = log.isTraceEnabled();
/* 422 */     if (trace)
/* 423 */       log.trace("loadClass " + this + " name=" + name + ", loadClassDepth=" + this.loadClassDepth);
/* 424 */     Class clazz = null;
/*     */     try
/*     */     {
/* 427 */       if (this.repository != null)
/*     */       {
/* 429 */         clazz = this.repository.getCachedClass(name);
/* 430 */         if (clazz != null)
/*     */         {
/* 432 */           if (log.isTraceEnabled())
/*     */           {
/* 434 */             buffer = new StringBuffer("Loaded class from cache, ");
/* 435 */             ClassToStringAction.toString(clazz, buffer);
/* 436 */             log.trace(buffer.toString());
/*     */           }
/* 438 */           buffer = clazz;
/*     */           return buffer;
/*     */         }
/*     */       }
/* 441 */       clazz = loadClassImpl(name, resolve, 2147483647);
/* 442 */       StringBuffer buffer = clazz;
/*     */       return buffer;
/*     */     }
/*     */     finally
/*     */     {
/* 446 */       if (trace)
/*     */       {
/* 448 */         if (clazz != null)
/* 449 */           log.trace("loadClass " + this + " name=" + name + " class=" + clazz + " cl=" + clazz.getClassLoader());
/*     */         else
/* 451 */           log.trace("loadClass " + this + " name=" + name + " not found");
/*     */       }
/* 451 */     }throw localObject;
/*     */   }
/*     */
/*     */   public Class loadClassBefore(String name)
/*     */     throws ClassNotFoundException
/*     */   {
/* 466 */     boolean trace = log.isTraceEnabled();
/* 467 */     if (trace)
/* 468 */       log.trace("loadClassBefore " + this + " name=" + name);
/* 469 */     Class clazz = null;
/*     */     try
/*     */     {
/* 472 */       clazz = loadClassImpl(name, false, this.addedOrder);
/* 473 */       Class localClass1 = clazz;
/*     */       return localClass1;
/*     */     }
/*     */     finally
/*     */     {
/* 477 */       if (trace)
/*     */       {
/* 479 */         if (clazz != null)
/* 480 */           log.trace("loadClassBefore " + this + " name=" + name + " class=" + clazz + " cl=" + clazz.getClassLoader());
/*     */         else
/* 482 */           log.trace("loadClassBefore " + this + " name=" + name + " not found");
/*     */       }
/* 482 */     }throw localObject;
/*     */   }
/*     */
/*     */   public abstract Class loadClassImpl(String paramString, boolean paramBoolean, int paramInt)
/*     */     throws ClassNotFoundException;
/*     */
/*     */   public URL getResource(String name)
/*     */   {
/* 496 */     if (this.repository != null)
/* 497 */       return this.repository.getResource(name, this);
/* 498 */     return null;
/*     */   }
/*     */
/*     */   public Enumeration findResources(String name)
/*     */     throws IOException
/*     */   {
/* 510 */     Vector resURLs = new Vector();
/* 511 */     if (this.repository == null)
/*     */     {
/* 513 */       String msg = "Invalid use of destroyed classloader, UCL destroyed at:";
/* 514 */       IOException e = new IOException(msg);
/* 515 */       e.initCause(this.unregisterTrace);
/* 516 */       throw e;
/*     */     }
/* 518 */     this.repository.getResources(name, this, resURLs);
/* 519 */     return resURLs.elements();
/*     */   }
/*     */
/*     */   public Enumeration findResourcesLocally(String name)
/*     */     throws IOException
/*     */   {
/* 527 */     return super.findResources(name);
/*     */   }
/*     */
/*     */   protected Class findClass(String name)
/*     */     throws ClassNotFoundException
/*     */   {
/* 539 */     boolean trace = log.isTraceEnabled();
/* 540 */     if (trace)
/* 541 */       log.trace("findClass, name=" + name);
/* 542 */     if (isClassBlackListed(name))
/*     */     {
/* 544 */       if (trace)
/* 545 */         log.trace("Class in blacklist, name=" + name);
/* 546 */       throw new ClassNotFoundException("Class Not Found(blacklist): " + name);
/*     */     }
/*     */
/* 549 */     if (this.repository == null)
/*     */     {
/* 551 */       String msg = "Invalid use of destroyed classloader, UCL destroyed at:";
/* 552 */       ClassNotFoundException e = new ClassNotFoundException(msg);
/* 553 */       e.initCause(this.unregisterTrace);
/* 554 */       throw e;
/*     */     }
/* 556 */     Translator translator = this.repository.getTranslator();
/* 557 */     if (translator != null)
/*     */     {
/*     */       try
/*     */       {
/* 563 */         URL classUrl = getClassURL(name);
/* 564 */         byte[] rawcode = loadByteCode(classUrl);
/* 565 */         URL codeSourceUrl = getCodeSourceURL(name, classUrl);
/* 566 */         ProtectionDomain pd = getProtectionDomain(codeSourceUrl);
/* 567 */         byte[] bytecode = translator.transform(this, name, null, pd, rawcode);
/*     */
/* 569 */         if (bytecode == null) {
/* 570 */           bytecode = rawcode;
/*     */         }
/* 572 */         definePackage(name);
/* 573 */         return defineClass(name, bytecode, 0, bytecode.length, pd);
/*     */       }
/*     */       catch (ClassNotFoundException e)
/*     */       {
/* 577 */         throw e;
/*     */       }
/*     */       catch (Throwable ex)
/*     */       {
/* 581 */         throw new ClassNotFoundException(name, ex);
/*     */       }
/*     */     }
/*     */
/* 585 */     Class clazz = null;
/*     */     try
/*     */     {
/* 588 */       clazz = findClassLocally(name);
/*     */     }
/*     */     catch (ClassNotFoundException e)
/*     */     {
/* 592 */       if (trace)
/* 593 */         log.trace("CFNE: Adding to blacklist: " + name);
/* 594 */       addToClassBlackList(name);
/* 595 */       throw e;
/*     */     }
/* 597 */     return clazz;
/*     */   }
/*     */
/*     */   protected Class findClassLocally(String name)
/*     */     throws ClassNotFoundException
/*     */   {
/* 608 */     return super.findClass(name);
/*     */   }
/*     */
/*     */   protected void definePackage(String className)
/*     */   {
/* 619 */     int i = className.lastIndexOf('.');
/* 620 */     if (i == -1) {
/* 621 */       return;
/*     */     }
/*     */     try
/*     */     {
/* 625 */       definePackage(className.substring(0, i), null, null, null, null, null, null, null);
/*     */     }
/*     */     catch (IllegalArgumentException alreadyDone)
/*     */     {
/*     */     }
/*     */   }
/*     */
/*     */   public void addURL(URL url)
/*     */   {
/* 637 */     if (url == null) {
/* 638 */       throw new IllegalArgumentException("url cannot be null");
/*     */     }
/* 640 */     if (this.repository.addClassLoaderURL(this, url) == true)
/*     */     {
/* 642 */       log.debug("Added url: " + url + ", to ucl: " + this);
/*     */
/* 644 */       String query = url.getQuery();
/* 645 */       if (query != null)
/*     */       {
/* 647 */         String ext = url.toExternalForm();
/* 648 */         String ext2 = ext.substring(0, ext.length() - query.length() - 1);
/*     */         try
/*     */         {
/* 651 */           url = new URL(ext2);
/*     */         }
/*     */         catch (MalformedURLException e)
/*     */         {
/* 655 */           log.warn("Failed to strip query from: " + url, e);
/*     */         }
/*     */       }
/* 658 */       super.addURL(url);
/* 659 */       clearBlacklists();
/*     */     }
/* 661 */     else if (log.isTraceEnabled())
/*     */     {
/* 663 */       log.trace("Ignoring duplicate url: " + url + ", for ucl: " + this);
/*     */     }
/*     */   }
/*     */
/*     */   public URL[] getURLs()
/*     */   {
/* 677 */     return EMPTY_URL_ARRAY;
/*     */   }
/*     */
/*     */   public Package getPackage(String name)
/*     */   {
/* 682 */     return super.getPackage(name);
/*     */   }
/*     */
/*     */   public Package[] getPackages()
/*     */   {
/* 687 */     return super.getPackages();
/*     */   }
/*     */
/*     */   public final boolean equals(Object other)
/*     */   {
/* 700 */     return super.equals(other);
/*     */   }
/*     */
/*     */   public final int hashCode()
/*     */   {
/* 711 */     return super.hashCode();
/*     */   }
/*     */
/*     */   public String toString()
/*     */   {
/* 719 */     return super.toString() + "{ url=" + getURL() + " }";
/*     */   }
/*     */
/*     */   protected boolean attempt(long waitMS)
/*     */   {
/* 731 */     boolean acquired = false;
/* 732 */     boolean trace = log.isTraceEnabled();
/*     */
/* 734 */     boolean threadWasInterrupted = Thread.interrupted();
/*     */     try
/*     */     {
/* 737 */       acquired = this.loadLock.attempt(waitMS);
/*     */     }
/*     */     catch (InterruptedException e)
/*     */     {
/*     */     }
/*     */     finally
/*     */     {
/* 745 */       if (threadWasInterrupted)
/* 746 */         Thread.currentThread().interrupt();
/*     */     }
/* 748 */     if (trace)
/* 749 */       log.trace("attempt(" + this.loadLock.holds() + ") was: " + acquired + " for :" + this);
/* 750 */     return acquired;
/*     */   }
/*     */
/*     */   protected void acquire()
/*     */   {
/* 760 */     boolean threadWasInterrupted = Thread.interrupted();
/*     */     try
/*     */     {
/* 763 */       this.loadLock.acquire();
/*     */     }
/*     */     catch (InterruptedException e)
/*     */     {
/*     */     }
/*     */     finally
/*     */     {
/* 771 */       if (threadWasInterrupted)
/* 772 */         Thread.currentThread().interrupt();
/*     */     }
/* 774 */     if (log.isTraceEnabled())
/* 775 */       log.trace("acquired(" + this.loadLock.holds() + ") for :" + this);
/*     */   }
/*     */
/*     */   protected void release()
/*     */   {
/* 782 */     if (log.isTraceEnabled())
/* 783 */       log.trace("release(" + this.loadLock.holds() + ") for :" + this);
/* 784 */     this.loadLock.release();
/* 785 */     if (log.isTraceEnabled())
/* 786 */       log.trace("released, holds: " + this.loadLock.holds());
/*     */   }
/*     */
/*     */   protected byte[] loadByteCode(String classname)
/*     */     throws ClassNotFoundException, IOException
/*     */   {
/* 800 */     byte[] bytecode = null;
/* 801 */     URL classURL = getClassURL(classname);
/*     */
/* 804 */     InputStream is = null;
/*     */     try
/*     */     {
/* 807 */       is = classURL.openStream();
/* 808 */       ByteArrayOutputStream baos = new ByteArrayOutputStream();
/* 809 */       byte[] tmp = new byte[1024];
/* 810 */       int read = 0;
/* 811 */       while ((read = is.read(tmp)) > 0)
/*     */       {
/* 813 */         baos.write(tmp, 0, read);
/*     */       }
/* 815 */       bytecode = baos.toByteArray();
/*     */     }
/*     */     finally
/*     */     {
/* 819 */       if (is != null) {
/* 820 */         is.close();
/*     */       }
/*     */     }
/* 823 */     return bytecode;
/*     */   }
/*     */
/*     */   protected byte[] loadByteCode(URL classURL)
/*     */     throws ClassNotFoundException, IOException
/*     */   {
/* 837 */     byte[] bytecode = null;
/*     */
/* 839 */     InputStream is = null;
/*     */     try
/*     */     {
/* 842 */       is = classURL.openStream();
/* 843 */       ByteArrayOutputStream baos = new ByteArrayOutputStream();
/* 844 */       byte[] tmp = new byte[1024];
/* 845 */       int read = 0;
/* 846 */       while ((read = is.read(tmp)) > 0)
/*     */       {
/* 848 */         baos.write(tmp, 0, read);
/*     */       }
/* 850 */       bytecode = baos.toByteArray();
/*     */     }
/*     */     finally
/*     */     {
/* 854 */       if (is != null) {
/* 855 */         is.close();
/*     */       }
/*     */     }
/* 858 */     return bytecode;
/*     */   }
/*     */
/*     */   protected ProtectionDomain getProtectionDomain(URL codesourceUrl)
/*     */   {
/* 869 */     Certificate[] certs = null;
/* 870 */     CodeSource cs = new CodeSource(codesourceUrl, certs);
/* 871 */     PermissionCollection permissions = Policy.getPolicy().getPermissions(cs);
/* 872 */     if (log.isTraceEnabled()) {
/* 873 */       log.trace("getProtectionDomain, url=" + codesourceUrl + " codeSource=" + cs + " permissions=" + permissions);
/*     */     }
/* 875 */     return new ProtectionDomain(cs, permissions);
/*     */   }
/*     */
/*     */   private URL getCodeSourceURL(String classname, URL classURL)
/*     */     throws MalformedURLException
/*     */   {
/* 884 */     String classRsrcName = classname.replace('.', '/') + ".class";
/* 885 */     String urlAsString = classURL.toString();
/* 886 */     int idx = urlAsString.indexOf(classRsrcName);
/* 887 */     if (idx == -1) return classURL;
/* 888 */     urlAsString = urlAsString.substring(0, idx);
/* 889 */     return new URL(urlAsString);
/*     */   }
/*     */
/*     */   private URL getClassURL(String classname) throws ClassNotFoundException
/*     */   {
/* 894 */     String classRsrcName = classname.replace('.', '/') + ".class";
/* 895 */     URL classURL = getResourceLocally(classRsrcName);
/* 896 */     if (classURL == null)
/*     */     {
/* 898 */       String msg = "Failed to find: " + classname + " as resource: " + classRsrcName;
/* 899 */       throw new ClassNotFoundException(msg);
/*     */     }
/* 901 */     return classURL;
/*     */   }
/*     */ }

/* Location:           /home/mnovotny/projects/EMBEDDED_JBOSS_BETA3_COMMUNITY/embedded/output/lib/embedded-jboss/lib/jboss-embedded-all.jar
* Qualified Name:     org.jboss.mx.loading.RepositoryClassLoader
* JD-Core Version:    0.6.0
*/
TOP

Related Classes of org.jboss.mx.loading.RepositoryClassLoader

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.