Package org.drools.base

Source Code of org.drools.base.ClassFieldAccessorStore$BaseLookupEntry

/*
* Copyright 2010 JBoss Inc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.drools.base;

import org.drools.RuntimeDroolsException;
import org.drools.base.AccessorKey.AccessorType;
import org.drools.base.extractors.MVELDateClassFieldReader;
import org.drools.base.extractors.MVELNumberClassFieldReader;
import org.drools.base.extractors.MVELObjectClassFieldReader;
import org.drools.definition.type.FactField;
import org.drools.rule.TypeDeclaration;
import org.drools.spi.Acceptor;
import org.drools.spi.AcceptsClassObjectType;
import org.drools.spi.AcceptsReadAccessor;
import org.drools.spi.AcceptsWriteAccessor;
import org.drools.spi.ClassWireable;
import org.drools.spi.InternalReadAccessor;

import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.IdentityHashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

public class ClassFieldAccessorStore
    implements
    Externalizable {

    private static final long serialVersionUID = 510l;

    private Map<AccessorKey, BaseLookupEntry> lookup;

    private ClassFieldAccessorCache           cache;

    /**
     * This field is just there to assist in testing
     */
    private boolean                           eagerWire = true;

    public ClassFieldAccessorStore() {
        lookup = new HashMap<AccessorKey, BaseLookupEntry>();
    }

    public void writeExternal(ObjectOutput out) throws IOException {
        out.writeObject( lookup );
    }

    public void readExternal(ObjectInput in) throws IOException,
                                            ClassNotFoundException {
        lookup = (Map<AccessorKey, BaseLookupEntry>) in.readObject();
    }

    public void setEagerWire(boolean eagerWire) {
        this.eagerWire = eagerWire;
    }

    public void setClassFieldAccessorCache(ClassFieldAccessorCache cache) {
        this.cache = cache;
    }

    public ClassFieldWriter getWriter(Class cls,
                                      String fieldName,
                                      ClassLoader classLoader) {
        return getWriter( cls.getName(),
                          fieldName,
                          null );
    }

    public ClassFieldReader getReader(Class cls,
                                      String fieldName,
                                      ClassLoader classLoader) {
        return getReader( cls.getName(),
                          fieldName,
                          null,
                          AccessorKey.AccessorType.FieldAccessor );
    }

    public ClassFieldReader getReader(final String className,
                                      final String fieldName,
                                      final AcceptsReadAccessor target) {
        return getReader( className,
                          fieldName,
                          target,
                          AccessorKey.AccessorType.FieldAccessor );
    }

    public synchronized ClassFieldReader getReader(final String className,
                                                   String fieldName,
                                                   final AcceptsReadAccessor target,
                                                   final AccessorKey.AccessorType accessorType) {
        AccessorKey key = new AccessorKey( className,
                                           fieldName,
                                           accessorType );
        FieldLookupEntry entry = (FieldLookupEntry) this.lookup.get( key );

        boolean exists = true;
        if ( entry == null ) {
            exists = false;
            entry = new FieldLookupEntry( new ClassFieldReader( className,
                                                                fieldName ) );
        }

        if ( this.eagerWire ) {
            wire( entry.getClassFieldReader() );
        }


        if ( target != null ) {
            target.setReadAccessor( entry.getClassFieldReader() );
            entry.addAccessorTarget( target );
        }

        if ( !exists ) {
            // we delay the key writing as we only want to do it if the wiring was successful
            this.lookup.put( key,
                             entry );
        }

        return ( ClassFieldReader ) entry.getClassFieldReader();
    }


    public InternalReadAccessor getMVELReader(final String pkgName,
                                                    final String className,
                                                    final String expr,
                                                    final boolean typesafe,
                                                    Class returnType) {
        AccessorKey key = new AccessorKey( pkgName + className,
                                           expr,
                                           AccessorKey.AccessorType.FieldAccessor );
        FieldLookupEntry entry = (FieldLookupEntry) this.lookup.get( key );
        if ( entry == null ) {
            InternalReadAccessor reader  = getReadAcessor( className, expr, typesafe, returnType );
            entry = new FieldLookupEntry( reader );
            this.lookup.put( key,
                             entry );
        }

        return entry.getClassFieldReader();
    }
   
    public static InternalReadAccessor getReadAcessor(String className, String expr, boolean typesafe, Class returnType) {
        if (Number.class.isAssignableFrom( returnType ) ||
            ( returnType == byte.class ||
              returnType == short.class ||
              returnType == int.class ||
              returnType == long.class ||
              returnType == float.class ||
              returnType == double.class ) ) {           
            return new MVELNumberClassFieldReader( className, expr, typesafe );           
        } else if Date.class.isAssignableFrom( returnType ) ) {
          return new MVELDateClassFieldReader( className, expr, typesafe );
        } else {
          return new MVELObjectClassFieldReader( className, expr, typesafe );
        }      
    }    

    public synchronized ClassFieldWriter getWriter(final String className,
                                                   final String fieldName,
                                                   final AcceptsWriteAccessor target) {
        AccessorKey key = new AccessorKey( className,
                                           fieldName,
                                           AccessorKey.AccessorType.FieldAccessor );
        FieldLookupEntry entry = (FieldLookupEntry) this.lookup.get( key );
        boolean exists = true;
        if ( entry == null ) {
            exists = false;
            entry = new FieldLookupEntry( new ClassFieldWriter( className,
                                                                fieldName ) );
        }

        if ( this.eagerWire ) {
            wire( entry.getClassFieldReader() );
        }

        if ( target != null ) {
            target.setWriteAccessor( entry.getClassFieldWriter() );
            entry.addAccessorTarget( target );
        }

        if ( !exists ) {
            // we delay the key writing as we only want to do it if the wiring was successful
            this.lookup.put( key,
                             entry );
        }

        return entry.getClassFieldWriter();
    }

    public ClassFieldAccessor getAccessor(Class cls,
                                          String fieldName,
                                          ClassLoader classLoader) {
        return getAccessor( cls.getName(),
                            fieldName );
    }

    public ClassFieldAccessor getAccessor(final String className,
                                          final String fieldName) {
        AccessorKey key = new AccessorKey( className,
                                           fieldName,
                                           AccessorKey.AccessorType.FieldAccessor );
        FieldLookupEntry entry = (FieldLookupEntry) this.lookup.get( key );
        if ( entry == null ) {
            entry = new FieldLookupEntry( new ClassFieldReader( className,
                                                                fieldName ),
                                          new ClassFieldWriter( className,
                                                                fieldName ) );
            this.lookup.put( key,
                             entry );
        }

        ClassFieldAccessor accessor = new ClassFieldAccessor( (ClassFieldReader) entry.getClassFieldReader(),
                                                              entry.getClassFieldWriter() );

        entry.addAccessorTarget( accessor );

        if ( this.eagerWire ) {
            wire( entry.getClassFieldReader() );
            wire( entry.getClassFieldWriter() );
        }

        return accessor;
    }

    //    public PatternExtractor getObjectAccessor(final Class cls,
    //                                              final String identifier,
    //                                              final Declaration declaration) {
    //        AccessorKey key = new AccessorKey( cls.getName(),
    //                                           identifier, // we are re-using the fieldName as a global identifier
    //                                           AccessorKey.AccessorType.GlobalAccessor );
    //
    //        ObjectExtractorLookupEntry entry = (ObjectExtractorLookupEntry) this.lookup.get( key );
    //        if ( entry == null ) {
    //            PatternExtractor extractor = (PatternExtractor) declaration.getExtractor();
    //            entry = new ObjectExtractorLookupEntry( extractor );
    //            this.lookup.put( key,
    //                             entry );
    //        }
    //
    //        entry.addAccessorTarget( declaration );
    //
    //        // there is no wiring here as the GlobalExtractor already references the class,
    //        // although we will need to re-wire on serialisation
    //
    //        return entry.getObjectExtractor();
    //    }
    //
    //    public GlobalExtractor getGlobalAccessor(final ClassObjectType classObjectType,
    //                                             final String identifier,
    //                                             final Declaration declaration) {
    //        AccessorKey key = new AccessorKey( classObjectType.getClassType().getName(),
    //                                           identifier, // we are re-using the fieldName as a global identifier
    //                                           AccessorKey.AccessorType.GlobalAccessor );
    //
    //        GlobalExtractorLookupEntry entry = (GlobalExtractorLookupEntry) this.lookup.get( key );
    //        if ( entry == null ) {
    //            entry = new GlobalExtractorLookupEntry( new GlobalExtractor( identifier,
    //                                                                         classObjectType ) );
    //            this.lookup.put( key,
    //                             entry );
    //        }
    //
    //        entry.addAccessorTarget( declaration );
    //        declaration.setReadAccessor( entry.getGlobalExtractor() );
    //
    //        // there is no wiring here as the GlobalExtractor already references the class,
    //        // although we will need to re-wire on serialisation
    //
    //        return entry.getGlobalExtractor();
    //    }

    public ClassObjectType getClassObjectType(final ClassObjectType objectType,
                                              final AcceptsClassObjectType target) {
        return getClassObjectType( objectType,
                                   objectType.isEvent(),
                                   target );
    }

    public ClassObjectType getClassObjectType(final ClassObjectType objectType,
                                              final boolean isEvent,
                                              final AcceptsClassObjectType target) {
        AccessorKey key = new AccessorKey( objectType.getClassName(),
                                           isEvent ? "$$DROOLS__isEvent__" : null,
                                           AccessorKey.AccessorType.ClassObjectType );

        ClassObjectTypeLookupEntry entry = (ClassObjectTypeLookupEntry) this.lookup.get( key );
        if ( entry == null ) {
            entry = new ClassObjectTypeLookupEntrycache.getClassObjectType( objectType ) );
            this.lookup.put( key,
                             entry );
        }

        if ( target != null ) {
            entry.addAccessorTarget( target );
            target.setClassObjectType( entry.getClassObjectType() );
        }

        return entry.getClassObjectType();
    }

    public void removeType(TypeDeclaration type) {
        lookup.remove(new AccessorKey( type.getTypeClassName(), null, AccessorKey.AccessorType.ClassObjectType ));
        for (FactField field : type.getTypeClassDef().getFields()) {
            lookup.remove(new AccessorKey( type.getTypeClassName(), field.getName(), AccessorKey.AccessorType.FieldAccessor ));
        }
    }

    public void merge(ClassFieldAccessorStore other) {
        for ( Entry<AccessorKey, BaseLookupEntry> entry : other.lookup.entrySet() ) {

            switch ( entry.getValue().getAccessorType() ) {
                case FieldAccessor : {
                    FieldLookupEntry lookupEntry = (FieldLookupEntry) this.lookup.get( entry.getKey() );
                    if ( lookupEntry == null ) {
                        lookupEntry = (FieldLookupEntry) entry.getValue();
                        this.lookup.put( entry.getKey(),
                                         lookupEntry );
                        for ( Acceptor target : lookupEntry.getAccessorTargets() ) {
                            if ( target instanceof ClassWireable ) {
                                wire( (ClassWireable) target );
                            }
                        }
                    } else {
                        // iterate through new targets adding them and wiring them up
                        // to the existing ClassFieldReader, no need to wire generated accessor
                        // as we know it already exists
                        for ( Acceptor target : entry.getValue().getAccessorTargets() ) {
                            if ( target instanceof AcceptsReadAccessor ) {
                                ((AcceptsReadAccessor) target).setReadAccessor( lookupEntry.getClassFieldReader() );
                            } else if ( target instanceof AcceptsWriteAccessor ) {
                                ((AcceptsWriteAccessor) target).setWriteAccessor( lookupEntry.getClassFieldWriter() );
                            }
                            lookupEntry.addAccessorTarget( target );
                        }
                    }
                    // wire up ClassFieldReaders
                    if (lookupEntry.getClassFieldReader() != null ) {
                        wire(((FieldLookupEntry)entry.getValue()).getClassFieldReader());
                    }
                    if (lookupEntry.getClassFieldWriter() != null) {
                        wire(((FieldLookupEntry)entry.getValue()).getClassFieldWriter());
                    }
                    break;
                }

                case ClassObjectType : {
                    ClassObjectTypeLookupEntry lookupEntry = (ClassObjectTypeLookupEntry) this.lookup.get( entry.getKey() );
                    if ( lookupEntry == null ) {
                                                // Create new entry with correct ClassObjectType and targets
                        lookupEntry = new ClassObjectTypeLookupEntrycache.getClassObjectType( ((ClassObjectTypeLookupEntry) entry.getValue()).getClassObjectType() ) );

                        this.lookup.put( entry.getKey(),
                                         lookupEntry );

                    }

                    for ( Acceptor target : entry.getValue().getAccessorTargets() ) {
                        ((AcceptsClassObjectType) target).setClassObjectType( lookupEntry.getClassObjectType() );
                        lookupEntry.addAccessorTarget( target );
                    }
                }

                    //                case ObjectAccessor : {
                    //                    ObjectExtractorLookupEntry lookupEntry = ( ObjectExtractorLookupEntry ) this.lookup.get( entry.getKey() );
                    //                    if ( lookupEntry == null ) {
                    //                        lookupEntry = ( ObjectExtractorLookupEntry )  entry.getValue();
                    //                        this.lookup.put( entry.getKey(),
                    //                                         lookupEntry );
                    //                        wire( lookupEntry.getObjectExtractor() );
                    //                    } else {
                    //                        for ( Acceptor target : entry.getValue().getAccessorTargets() ) {
                    //                            ((Declaration)target).setReadAccessor( lookupEntry.getObjectExtractor() );
                    //                            lookupEntry.addAccessorTarget( target );
                    //                        }
                    //                    }
                    //                    break;
                    //                }
                    //                case GlobalAccessor : {
                    //                    GlobalExtractorLookupEntry lookupEntry = ( GlobalExtractorLookupEntry ) this.lookup.get( entry.getKey() );
                    //                    if ( lookupEntry == null ) {
                    //                        lookupEntry = ( GlobalExtractorLookupEntry )  entry.getValue();
                    //                        this.lookup.put( entry.getKey(),
                    //                                         lookupEntry );
                    //                        wire( lookupEntry.getGlobalExtractor() );
                    //                    } else {
                    //                        for ( Acceptor target : entry.getValue().getAccessorTargets() ) {
                    //                            ((Declaration)target).setReadAccessor( lookupEntry.getGlobalExtractor() );
                    //                            lookupEntry.addAccessorTarget( target );
                    //                        }
                    //                    }
                    //                    break;
                    //                }
            }
        }
    }

    public void wire() {
        for ( Entry<AccessorKey, BaseLookupEntry> entry : lookup.entrySet() ) {
            switch ( entry.getValue().getAccessorType() ) {
                case FieldAccessor : {
                    InternalReadAccessor reader = ((FieldLookupEntry) entry.getValue()).getClassFieldReader();
                    if ( reader != null ) {
                        wire( reader );
                    }

                    ClassFieldWriter writer = ((FieldLookupEntry) entry.getValue()).getClassFieldWriter();
                    if ( writer != null ) {
                        wire( writer );
                    }
                    break;
                }
                case ClassObjectType : {
                    ClassObjectType classObjectType = ((ClassObjectTypeLookupEntry) entry.getValue()).getClassObjectType();
                    wire( classObjectType );
                    break;
                }

                    //                case ObjectAccessor : {
                    //                    PatternExtractor reader = ((ObjectExtractorLookupEntry) entry.getValue()).getObjectExtractor();
                    //                    wire( reader );
                    //                    break;
                    //                }
                    //                case GlobalAccessor : {
                    //                    GlobalExtractor reader = ((GlobalExtractorLookupEntry) entry.getValue()).getGlobalExtractor();
                    //                    wire( reader );
                    //                    break;
                    //                }
            }
        }
    }

    public void wire(InternalReadAccessor reader) {
        if ( reader  instanceof ClassFieldReader ) {
            ((ClassFieldReader)reader).setReadAccessor( cache.getReadAcessor( (ClassFieldReader) reader ) );
        }
    }

    public void wire(ClassFieldWriter writer) {
        if (writer != null) {
            writer.setWriteAccessor( cache.getWriteAcessor( writer ) );
        }
    }

    public void wire( ClassWireable wireable ) {
        try {
            if ( wireable.getClassType() == null || ! wireable.getClassType().isPrimitive() ) {
                Class cls = this.cache.getClassLoader().loadClass( wireable.getClassName() );
                wireable.wire( cls );
            }
        } catch ( ClassNotFoundException e ) {
            throw new RuntimeDroolsException( "Unable to load ClassObjectType class '" + wireable.getClassName() + "'" );
        }
    }

    public static abstract class BaseLookupEntry
        implements
        Externalizable {
        // we use an identity hashmap to avoid hashcode/equals being called on stored targets
        private Map<Acceptor, Object> accessorTargets = Collections.<Acceptor, Object> emptyMap();

        public BaseLookupEntry() {

        }

        public void writeExternal(ObjectOutput out) throws IOException {
            out.writeObject( accessorTargets );
        }

        public void readExternal(ObjectInput in) throws IOException,
                                                ClassNotFoundException {
            accessorTargets = (Map<Acceptor, Object>) in.readObject();

        }

        public Set<Acceptor> getAccessorTargets() {
            return accessorTargets.keySet();
        }

        public void addAccessorTarget(Acceptor target) {
            if ( this.accessorTargets == Collections.EMPTY_MAP ) {
                this.accessorTargets = new IdentityHashMap<Acceptor, Object>();
            }

            this.accessorTargets.put( target, null );
        }

        public void addAccessorTargets(Set<Acceptor> targets) {
            if ( this.accessorTargets == Collections.EMPTY_MAP ) {
                this.accessorTargets = new IdentityHashMap<Acceptor, Object>( );
            }

            for ( Acceptor target : targets ) {
                this.accessorTargets.put( target, null );
            }
        }

        public void removeTarget(Acceptor target) {
            this.accessorTargets.remove( target );
        }

        public abstract AccessorKey.AccessorType getAccessorType();

    }

    public static class ClassObjectTypeLookupEntry extends BaseLookupEntry {
        ClassObjectType classObjectType;

        public ClassObjectTypeLookupEntry() {
            super();
        }

        public ClassObjectTypeLookupEntry(ClassObjectType classObjectType) {
            super();
            this.classObjectType = classObjectType;
        }

        public void writeExternal(ObjectOutput out) throws IOException {
            super.writeExternal( out );
            out.writeObject( classObjectType );
        }

        public void readExternal(ObjectInput in) throws IOException,
                                                ClassNotFoundException {
            super.readExternal( in );
            classObjectType = (ClassObjectType) in.readObject();
        }

        public ClassObjectType getClassObjectType() {
            return classObjectType;
        }

        public void setClassObjectType(ClassObjectType classObjectType) {
            this.classObjectType = classObjectType;
        }

        public AccessorType getAccessorType() {
            return AccessorKey.AccessorType.ClassObjectType;
        }

    }

    //
    //    public static class GlobalExtractorLookupEntry extends BaseLookupEntry {
    //        GlobalExtractor globalExtractor;
    //
    //        public GlobalExtractorLookupEntry() {
    //            super();
    //        }
    //
    //        public GlobalExtractorLookupEntry(GlobalExtractor globalExtractor) {
    //            super();
    //            this.globalExtractor = globalExtractor;
    //        }
    //
    //        public void writeExternal(ObjectOutput out) throws IOException {
    //            super.writeExternal( out );
    //            out.writeObject( globalExtractor );
    //        }
    //
    //        public void readExternal(ObjectInput in) throws IOException,
    //                                                ClassNotFoundException {
    //            super.readExternal( in );
    //            globalExtractor = (GlobalExtractor) in.readObject();
    //        }
    //
    //        public GlobalExtractor getGlobalExtractor() {
    //            return globalExtractor;
    //        }
    //
    //        public AccessorType getAccessorType() {
    //            return AccessorKey.AccessorType.GlobalAccessor;
    //        }
    //
    //    }
    //
    //    public static class ObjectExtractorLookupEntry extends BaseLookupEntry {
    //        PatternExtractor patternExtractor;
    //
    //        public ObjectExtractorLookupEntry() {
    //            super();
    //        }
    //
    //        public ObjectExtractorLookupEntry(PatternExtractor patternExtractor) {
    //            super();
    //            this.patternExtractor = patternExtractor;
    //        }
    //
    //        public void writeExternal(ObjectOutput out) throws IOException {
    //            super.writeExternal( out );
    //            out.writeObject( patternExtractor );
    //        }
    //
    //        public void readExternal(ObjectInput in) throws IOException,
    //                                                ClassNotFoundException {
    //            super.readExternal( in );
    //            patternExtractor = (PatternExtractor) in.readObject();
    //        }
    //
    //        public PatternExtractor getObjectExtractor() {
    //            return patternExtractor;
    //        }
    //
    //        public AccessorType getAccessorType() {
    //            return AccessorKey.AccessorType.ObjectAccessor;
    //        }
    //    }
    //
    public static class FieldLookupEntry extends BaseLookupEntry {
        private InternalReadAccessor reader;
        private ClassFieldWriter writer;

        public FieldLookupEntry() {

        }

        public FieldLookupEntry(InternalReadAccessor reader) {
            this.reader = reader;
        }

        public FieldLookupEntry(ClassFieldWriter writer) {
            this.writer = writer;
        }

        public FieldLookupEntry(ClassFieldReader reader,
                                ClassFieldWriter writer) {
            this.writer = writer;
            this.reader = reader;
        }

        public void writeExternal(ObjectOutput out) throws IOException {
            super.writeExternal( out );
            out.writeObject( reader );
            out.writeObject( writer );
        }

        public void readExternal(ObjectInput in) throws IOException,
                                                ClassNotFoundException {
            super.readExternal( in );
            reader = (InternalReadAccessor) in.readObject();
            writer = (ClassFieldWriter) in.readObject();
        }

        public InternalReadAccessor getClassFieldReader() {
            return reader;
        }

        public ClassFieldWriter getClassFieldWriter() {
            return this.writer;
        }

        public AccessorType getAccessorType() {
            return AccessorKey.AccessorType.FieldAccessor;
        }
    }

    //    public static class LookupEntry
    //        implements
    //        Externalizable {
    //        private ClassFieldReader     reader;
    //        private ClassFieldWriter     writer;
    //        private Set<AcceptsAccessor> accessorTargets = Collections.<AcceptsAccessor> emptySet();
    //
    //        public LookupEntry() {
    //
    //        }
    //
    //        public void writeExternal(ObjectOutput out) throws IOException {
    //            out.writeObject( reader );
    //            out.writeObject( writer );
    //            out.writeObject( accessorTargets );
    //        }
    //
    //        public void readExternal(ObjectInput in) throws IOException,
    //                                                ClassNotFoundException {
    //            reader = (ClassFieldReader) in.readObject();
    //            writer = (ClassFieldWriter) in.readObject();
    //            accessorTargets = (Set<AcceptsAccessor>) in.readObject();
    //
    //        }
    //
    //        public LookupEntry(ClassFieldReader reader) {
    //            this.reader = reader;
    //        }
    //
    //        public LookupEntry(ClassFieldWriter writer) {
    //            this.writer = writer;
    //        }
    //
    //        public LookupEntry(ClassFieldReader reader,
    //                           ClassFieldWriter writer) {
    //            this.writer = writer;
    //            this.reader = reader;
    //        }
    //
    //        public ClassFieldReader getClassFieldReader() {
    //            return reader;
    //        }
    //
    //        public ClassFieldWriter getClassFieldWriter() {
    //            return this.writer;
    //        }
    //
    //        public Set<AcceptsAccessor> getAccessorTargets() {
    //            return accessorTargets;
    //        }
    //
    //        public void addAccessorTarget(AcceptsAccessor target) {
    //            if ( this.accessorTargets == Collections.EMPTY_SET ) {
    //                this.accessorTargets = new HashSet<AcceptsAccessor>();
    //            }
    //
    //            this.accessorTargets.add( target );
    //        }
    //
    //        public void removeConstraint(Constraint constraint) {
    //            this.accessorTargets.remove( constraint );
    //        }
    //    }
}
TOP

Related Classes of org.drools.base.ClassFieldAccessorStore$BaseLookupEntry

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.