//================================================================================================== // J a v a Java // R e f l e c t i o n // J i r k C l a s s // By Bruno Bachelet //================================================================================================== // Copyright (c) 1999-2016 // Bruno Bachelet - bruno@nawouak.net - http://www.nawouak.net // // This file is part of the B++ Library. This library is free software; you can redistribute it // and/or modify it under the terms of the GNU Library General Public License as published by the // Free Software Foundation; either version 2 of the License, or (at your option) any later // version. // // This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; // without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See // the GNU Library General Public License for more details (http://www.gnu.org).
/*DESCRIPTION*/ /* This module provides a class to build the Jirk++ representation of a Java class. */
// Package //--------------------------------------------------------------------------------------- package bpp.java.reflection;
// Importation //----------------------------------------------------------------------------------- import bpp.standard.*; import java.io.*; import java.lang.reflect.*; import java.util.*;
@SuppressWarnings("unchecked")
// J i r k C l a s s Class //---------------------------------------------------------------------- /*CLASS JirkClass */ /* Represents a Java class and its Jirk++ representation. */ public class JirkClass implements Comparable { //---------------------------------------------------------------------------------------Attributes protected Vector atAttributeS; // Public attributes of the class. protected Class atClass; // Reference of the class. protected Vector atClassS; // Public inner classes of the class. protected Vector atConstructorS; // Public constructors of the class. protected TreeSet atDependencyS; // Classes the class depends on. protected TreeSet atIncludeS; // Classes to include in the Jirk++ definition. protected Vector atMethodS; // Public methods of the class. protected Vector atPathClassS; // Classes forming the name of the class. protected Vector atPathModuleS; // Modules forming the name of the class. protected Vector atSuperS; // Superclasses of the class. //----------------------------------------------------------------------------------------BuildPath // Stores in vectors the different parts of the full name of the class. protected void buildPath() { int lcEnd = 0; String lcName = javaName();
atPathClassS=new Vector(); atPathModuleS=new Vector(); if (isArray() || isPrimitive()) return;
do { lcEnd=lcName.indexOf('.');
if (lcEnd>=0) { atPathModuleS.add(lcName.substring(0,lcEnd)); lcName=lcName.substring(lcEnd+1,lcName.length()); } } while (lcEnd>=0);
do { lcEnd=lcName.indexOf('$'); atPathClassS.add(lcName.substring(0,(lcEnd<0 ? lcName.length() : lcEnd))); if (lcEnd>=0) lcName=lcName.substring(lcEnd+1,lcName.length()); } while (lcEnd>=0); } //---------------------------------------------------------------------------------BuildInheritance // Builds a list of the inherited classes and interfaces. protected void buildInheritance(TreeSet agDependencyS,TreeSet agIncludeS, TreeSet agToGenerateS,TreeSet agAlreadyGeneratedS) { JirkClass lcClass;
Class lcClassS[] = atClass.getInterfaces(); int lcCounter = 0;
atSuperS=new Vector();
if (atClass.getSuperclass()!=null) { lcClass=new JirkClass(atClass.getSuperclass()); atSuperS.add(lcClass); registerClass(lcClass,agDependencyS,agToGenerateS,agAlreadyGeneratedS); addInclude(lcClass,agIncludeS); }
while (lcCounter<lcClassS.length) { lcClass=new JirkClass(lcClassS[lcCounter]); atSuperS.add(lcClass); registerClass(lcClass,agDependencyS,agToGenerateS,agAlreadyGeneratedS); addInclude(lcClass,agIncludeS); ++lcCounter; } } //-------------------------------------------------------------------------------------BuildClasses // Builds a list of the inner classes of the class. protected void buildClasses(TreeSet agDependencyS,TreeSet agIncludeS, TreeSet agToGenerateS,TreeSet agAlreadyGeneratedS) { JirkClass lcClass;
Class lcClassS[] = atClass.getDeclaredClasses(); int lcCounter = 0;
atClassS=new Vector();
while (lcCounter<lcClassS.length) { lcClass=new JirkClass(lcClassS[lcCounter]);
if (lcClass.isPublic()) { if (agDependencyS==null) lcClass.build(atDependencyS,atIncludeS,agToGenerateS,agAlreadyGeneratedS); else lcClass.build(agDependencyS,agIncludeS,agToGenerateS,agAlreadyGeneratedS);
atClassS.add(lcClass); }
++lcCounter; }
if (agToGenerateS!=null) sortInnerClasses(); } //---------------------------------------------------------------------------------SortInnerClasses // Sorts the list of inner classes according to their interdependency. protected void sortInnerClasses() { JirkClass lcClass1; JirkClass lcClass2; int lcCounter2;
int lcCounter1 = 0;
while (lcCounter1<atClassS.size()) { lcCounter2=lcCounter1+1;
while (lcCounter2<atClassS.size()) { lcClass1=(JirkClass)atClassS.elementAt(lcCounter1); lcClass2=(JirkClass)atClassS.elementAt(lcCounter2);
if (lcClass2.isBefore(lcClass1)) { atClassS.setElementAt(lcClass1,lcCounter2); atClassS.setElementAt(lcClass2,lcCounter1); }
++lcCounter2; }
++lcCounter1; } } //-----------------------------------------------------------------------------------------IsBefore // Indicates if the class must be declared before another one according to their interdependency. protected boolean isBefore(JirkClass agClass) { JirkClass lcClass;
int lcCounter = 0;
while (lcCounter<agClass.atSuperS.size()) { lcClass=(JirkClass)agClass.atSuperS.elementAt(lcCounter); if (lcClass.atClass==atClass) return (true); ++lcCounter; }
return (false); } //----------------------------------------------------------------------------------BuildAttributes // Builds a list of the attributes of the class. protected void buildAttributes(TreeSet agDependencyS,TreeSet agToGenerateS, TreeSet agAlreadyGeneratedS) { JirkAttribute lcAttribute;
Field lcAttributeS[] = atClass.getDeclaredFields(); int lcCounter = 0;
atAttributeS=new Vector();
while (lcCounter<lcAttributeS.length) { lcAttribute=new JirkAttribute(this,lcAttributeS[lcCounter]);
if (lcAttribute.isPublic()) { atAttributeS.add(lcAttribute);
if (!lcAttribute.type().baseType().isPrimitive()) registerClass(lcAttribute.type().baseType(),agDependencyS,agToGenerateS,agAlreadyGeneratedS); }
++lcCounter; } } //--------------------------------------------------------------------------------BuildConstructors // Builds a list of the constructors of the class. protected void buildConstructors(TreeSet agDependencyS,TreeSet agToGenerateS, TreeSet agAlreadyGeneratedS) { int lcCounter2; JirkConstructor lcConstructor;
Constructor lcConstructorS[] = atClass.getDeclaredConstructors(); int lcCounter1 = 0;
atConstructorS=new Vector();
while (lcCounter1<lcConstructorS.length) { lcConstructor=new JirkConstructor(this,lcConstructorS[lcCounter1]);
if (lcConstructor.isPublic()) { atConstructorS.add(lcConstructor); lcCounter2=0;
while (lcCounter2<lcConstructor.argumentTypes().length) { if (!lcConstructor.argumentTypes()[lcCounter2].baseType().isPrimitive()) registerClass(lcConstructor.argumentTypes()[lcCounter2].baseType(),agDependencyS, agToGenerateS,agAlreadyGeneratedS);
++lcCounter2; } }
++lcCounter1; } } //-------------------------------------------------------------------------------------BuildMethods // Builds a list of the methods of the class. protected void buildMethods(TreeSet agDependencyS,TreeSet agToGenerateS, TreeSet agAlreadyGeneratedS) { int lcCounter2; Iterator lcIterator; JirkMethod lcMethod; String lcSignature;
int lcCounter1 = 0; Method lcMethodS[] = atClass.getDeclaredMethods(); TreeSet lcSignatureS = new TreeSet();
atMethodS=new Vector();
while (lcCounter1<lcMethodS.length) { lcMethod=new JirkMethod(this,lcMethodS[lcCounter1]);
// We use the C++ declaration of a method as its signature. If two methods have the same // signature, only one will be considered. For instance, this situation appears in the // "io.PrintStream" class of Java 1.5, where the method "append" is inherited from the // "Appendable" interface, and is overridden in "PrintStream". However, in "Appendable", // the method returns a reference to an "Appendable"; and in "PrintStream", the method // returns a reference to a "PrintStream". Using Java reflection, the method will appear // twice in the "PrintStream" class, returning either an "Appendable" or a "PrintStream" // reference.
lcSignature=""; lcIterator=lcMethod.declaration().iterator(); while (lcIterator.hasNext()) lcSignature+=(String)(lcIterator.next());
if (lcMethod.isPublic() && !lcSignatureS.contains(lcSignature)) { atMethodS.add(lcMethod); lcSignatureS.add(lcSignature);
if (!lcMethod.returnType().baseType().isPrimitive()) registerClass(lcMethod.returnType().baseType(),agDependencyS, agToGenerateS,agAlreadyGeneratedS);
lcCounter2=0;
while (lcCounter2<lcMethod.argumentTypes().length) { if (!lcMethod.argumentTypes()[lcCounter2].baseType().isPrimitive()) registerClass(lcMethod.argumentTypes()[lcCounter2].baseType(),agDependencyS, agToGenerateS,agAlreadyGeneratedS);
++lcCounter2; } }
++lcCounter1; } } //------------------------------------------------------------------------------------RegisterClass // Registers a class for the generation of its Jirk++ representation. protected void registerClass(JirkClass agClass,TreeSet agDependencyS,TreeSet agToGenerateS, TreeSet agAlreadyGeneratedS) { while (agClass.isInner()) agClass=new JirkClass(agClass.atClass.getDeclaringClass()); if (!agAlreadyGeneratedS.contains(agClass)) agToGenerateS.add(agClass);
if (agDependencyS==null) atDependencyS.add(agClass); else agDependencyS.add(agClass); } //---------------------------------------------------------------------------------------AddInclude // Adds a class in the list of classes to include in the Jirk++ definition of the class. protected void addInclude(JirkClass agClass,TreeSet agIncludeS) { while (agClass.isInner()) agClass=new JirkClass(agClass.atClass.getDeclaringClass());
if (agIncludeS==null) atIncludeS.add(agClass); else agIncludeS.add(agClass); } //--------------------------------------------------------------------------------------Constructor /*METHOD JirkClass */ /* Builds an object representing a Java class from its name. */ public JirkClass(String agName) throws Exception { atAttributeS=null; atClassS=null; atConstructorS=null; atDependencyS=null; atIncludeS=null; atMethodS=null; atSuperS=null;
try { atClass=Class.forName(agName); } catch (Exception e) { throw new Exception("Java/Reflection - Class not found."); }
buildPath(); } //--------------------------------------------------------------------------------------Constructor /*METHOD JirkClass */ /* Builds an object representing a Java class from its reference. */ public JirkClass(Class agClass) { atAttributeS=null; atClass=agClass; atClassS=null; atConstructorS=null; atDependencyS=null; atIncludeS=null; atMethodS=null; atSuperS=null; buildPath(); } //--------------------------------------------------------------------------------------Constructor /*METHOD JirkClass */ /* Builds and copies an object. */ public JirkClass(JirkClass agClass) { atAttributeS=null; atClass=agClass.atClass; atClassS=null; atConstructorS=null; atDependencyS=null; atIncludeS=null; atMethodS=null; atSuperS=null; buildPath(); } //----------------------------------------------------------------------------------------CompareTo /*METHOD JirkClass */ /* Compares the class to another one according to the lexicographical order of their name. */ public int compareTo(Object agObject) { return (javaName().compareTo(((JirkClass)agObject).javaName())); } //--------------------------------------------------------------------------------------------Build /*METHOD JirkClass */ /* Builds the whole structure of the class. */ public void build(TreeSet agDependencyS,TreeSet agIncludeS,TreeSet agToGenerateS, TreeSet agAlreadyGeneratedS) { atDependencyS=new TreeSet(); atIncludeS=new TreeSet();
if (agToGenerateS==null) buildClasses(agDependencyS,agIncludeS,agToGenerateS,agAlreadyGeneratedS); else { buildInheritance(agDependencyS,agIncludeS,agToGenerateS,agAlreadyGeneratedS); buildClasses(agDependencyS,agIncludeS,agToGenerateS,agAlreadyGeneratedS); buildAttributes(agDependencyS,agToGenerateS,agAlreadyGeneratedS); buildConstructors(agDependencyS,agToGenerateS,agAlreadyGeneratedS); buildMethods(agDependencyS,agToGenerateS,agAlreadyGeneratedS); } } //---------------------------------------------------------------------------------------Attributes /*METHOD JirkClass */ /* Returns the public attributes of the class. */ public Vector attributes() { return (atAttributeS); } //------------------------------------------------------------------------------------------Classes /*METHOD JirkClass */ /* Returns the public inner classes of the class. */ public Vector classes() { return (atClassS); } //-------------------------------------------------------------------------------------Constructors /*METHOD JirkClass */ /* Returns the public constructors of the class. */ public Vector constructors() { return (atConstructorS); } //-------------------------------------------------------------------------------------Dependencies /*METHOD JirkClass */ /* Returns the classes the class depends on. */ public TreeSet dependencies() { return (atDependencyS); } //-----------------------------------------------------------------------------------------Includes /*METHOD JirkClass */ /* Returns the classes to include in the Jirk++ definition of the class. */ public TreeSet includes() { return (atIncludeS); } //------------------------------------------------------------------------------------------IsArray /*METHOD JirkClass */ /* Indicates if the class represents an array. */ public boolean isArray() { return (atClass.isArray()); } //------------------------------------------------------------------------------------------IsInner /*METHOD JirkClass */ /* Indicates if the class is an inner class. */ public boolean isInner() { return (atClass.getDeclaringClass()!=null); } //--------------------------------------------------------------------------------------IsPrimitive /*METHOD JirkClass */ /* Indicates if the class represents a primitive type. */ public boolean isPrimitive() { return (atClass.isPrimitive()); } //-----------------------------------------------------------------------------------------IsPublic /*METHOD JirkClass */ /* Indicates if the class is public. */ public boolean isPublic() { return (Modifier.isPublic(atClass.getModifiers())); } //-----------------------------------------------------------------------------------------JavaName /*METHOD JirkClass */ /* Returns the Java name of the class. */ public String javaName() { return (atClass.getName()); } //------------------------------------------------------------------------------------------Methods /*METHOD JirkClass */ /* Returns the public methods of the class. */ public Vector methods() { return (atMethodS); } //-------------------------------------------------------------------------------------------Supers /*METHOD JirkClass */ /* Returns the superclasses of the class. */ public Vector supers() { return (atSuperS); } //----------------------------------------------------------------------------------------Dimension /*METHOD JirkClass */ /* If the class represents an array, returns the number of dimensions of the array. */ public int dimension() { Class lcClass = atClass; int lcDimension = 0;
while (lcClass.isArray()) { lcClass=lcClass.getComponentType(); ++lcDimension; }
return (lcDimension); } //-----------------------------------------------------------------------------------------BaseType /*METHOD JirkClass */ /* If the class represents an array, returns the base type of the array, else it returns the class itself. */ public JirkClass baseType() { Class lcClass = atClass;
while (lcClass.isArray()) lcClass=lcClass.getComponentType(); return (new JirkClass(lcClass)); } //----------------------------------------------------------------------------------------Signature /*METHOD JirkClass */ /* Returns the JNI signature of the class. */ public String signature() { int lcCounter = 0; String lcName = "L";
if (isArray()) return ("["+(new JirkClass(atClass.getComponentType())).signature());
if (isPrimitive()) { if (javaName().equals("boolean")) return ("Z"); else if (javaName().equals("byte")) return ("B"); else if (javaName().equals("char")) return ("C"); else if (javaName().equals("short")) return ("S"); else if (javaName().equals("int")) return ("I"); else if (javaName().equals("long")) return ("J"); else if (javaName().equals("float")) return ("F"); else if (javaName().equals("double")) return ("D"); else return ("V"); }
while (lcCounter<atPathModuleS.size()) { lcName+=(String)atPathModuleS.elementAt(lcCounter)+"/"; ++lcCounter; }
lcCounter=0;
while (lcCounter<atPathClassS.size()) { lcName+=(String)atPathClassS.elementAt(lcCounter); ++lcCounter; if (lcCounter<atPathClassS.size()) lcName+="$"; }
return (lcName+";"); } //---------------------------------------------------------------------------------------------Name /*METHOD JirkClass */ /* Returns a descriptive name of the type the class represents. Used to call methods in Jirk++. */ public String name() { if (isPrimitive()) { if (javaName().equals("boolean")) return ("Boolean"); else if (javaName().equals("byte")) return ("Byte"); else if (javaName().equals("char")) return ("Character"); else if (javaName().equals("short")) return ("Short"); else if (javaName().equals("int")) return ("Integer"); else if (javaName().equals("long")) return ("Long"); else if (javaName().equals("float")) return ("Float"); else if (javaName().equals("double")) return ("Double"); else return ("Void"); } else return ("Object"); } //----------------------------------------------------------------------------------------ShortName /*METHOD JirkClass */ /* Returns the Jirk++ short name of the class. */ public String shortName() { int lcCounter = 0; String lcName = "ja";
if (isPrimitive() || isArray()) return ("");
while (lcCounter<atPathClassS.size()) { lcName+=(String)atPathClassS.elementAt(lcCounter); ++lcCounter; if (lcCounter<atPathClassS.size()) lcName+="_"; }
return (lcName); } //-----------------------------------------------------------------------------------------FullName /*METHOD JirkClass */ /* Returns the Jirk++ full name of the class. */ public String fullName() { String lcModule;
int lcCounter = 0; String lcName = "jirk";
if (isArray()) return ("clAbstractArray<"+baseType().fullName()+","+dimension()+">");
if (isPrimitive()) { if (javaName().equals("boolean")) return ("jyBoolean"); else if (javaName().equals("byte")) return ("jyByte"); else if (javaName().equals("char")) return ("jyCharacter"); else if (javaName().equals("short")) return ("jyShort"); else if (javaName().equals("int")) return ("jyInteger"); else if (javaName().equals("long")) return ("jyLong"); else if (javaName().equals("float")) return ("jyFloat"); else if (javaName().equals("double")) return ("jyDouble"); else return ("void"); }
while (lcCounter<atPathModuleS.size()) { lcModule=(String)atPathModuleS.elementAt(lcCounter); if (lcModule.equals("function")) lcModule="_function"; lcName+="::"+lcModule; ++lcCounter; }
lcCounter=0; lcName+="::ja";
while (lcCounter<atPathClassS.size()) { lcName+=(String)atPathClassS.elementAt(lcCounter); ++lcCounter; if (lcCounter<atPathClassS.size()) lcName+="_"; }
return (lcName); } //-------------------------------------------------------------------------------------------Folder /*METHOD JirkClass */ /* Returns the folder where the files containing the Jirk++ representation of the class are located. */ public String folder() { int lcCounter = 0; String lcName = "jirk";
if (isArray() || isPrimitive()) return ("");
while (lcCounter<atPathModuleS.size()) { lcName+="/"+((String)atPathModuleS.elementAt(lcCounter)).toLowerCase(); ++lcCounter; }
return (lcName); } //----------------------------------------------------------------------------------------ShortFile /*METHOD JirkClass */ /* Returns the short name (without the extension) of the files in which the Jirk++ representation of the class is stored. */ public String shortFile() { return (((String)atPathClassS.elementAt(0)).toLowerCase()); } //---------------------------------------------------------------------------------------------File /*METHOD JirkClass */ /* Returns the full name (without the extension) of the files in which the Jirk++ representation of the class is stored. */ public String file() { if (isArray() || isPrimitive()) return (""); return (folder()+"/"+shortFile()); } //-----------------------------------------------------------------------------------------Guardian // C++ writing of the include file guardian. protected String guardian() { String lcString;
int lcCounter = 0; String lcName = "guJirk";
if (isArray() || isPrimitive()) return ("");
while (lcCounter<atPathModuleS.size()) { lcString=(String)atPathModuleS.elementAt(lcCounter); lcName+=lcString.substring(0,1).toUpperCase()+lcString.substring(1,lcString.length()); ++lcCounter; }
lcCounter=0;
while (lcCounter<atPathClassS.size()) { lcName+=(String)atPathClassS.elementAt(lcCounter); ++lcCounter; }
return (lcName); } //------------------------------------------------------------------------------------OpenNamespace // C++ writing of the namespace opening. protected String openNamespace() { String lcModule;
int lcCounter = 0; String lcString = "namespace jirk {";
if (isPrimitive() || isArray()) return (null);
while (lcCounter<atPathModuleS.size()) { lcModule=(String)atPathModuleS.elementAt(lcCounter); if (lcModule.equals("function")) lcModule="_function"; lcString+=" namespace "+lcModule+" {"; ++lcCounter; }
return (lcString); } //-----------------------------------------------------------------------------------CloseNamespace // C++ writing of the namespace closing. protected String closeNamespace() { int lcCounter = 0; String lcString = "}";
if (isPrimitive() || isArray()) return (null);
while (lcCounter<atPathModuleS.size()) { lcString+="}"; ++lcCounter; }
return (lcString); } //--------------------------------------------------------------------------------------Inheritance // C++ writing of the inheritance of the class. protected Vector inheritance() { int lcCounter = 0; Vector lcLineS = new Vector();
if (supers().size()==0) lcLineS.add(": public virtual clObject {"); else lcLineS.add(": public virtual clObject,");
while (lcCounter<supers().size()) { if (lcCounter+1==supers().size()) lcLineS.add(" public virtual "+((JirkClass)supers().elementAt(lcCounter)).fullName()+" {"); else lcLineS.add(" public virtual "+((JirkClass)supers().elementAt(lcCounter)).fullName()+",");
++lcCounter; }
return (lcLineS); } //--------------------------------------------------------------------------WriteForwardDeclaration // Writes the Jirk forward declaration of the class into a stream. protected void writeForwardDeclaration(OutputTextStream agStream,String agSpace) { JirkClass lcClass; Vector lcLineS;
int lcCounter = 0;
if (!isInner()) { if (classes()==null) buildClasses(null,null,null,null);
if (classes().size()==0) agStream.writeLine(agSpace+openNamespace()+" class "+shortName()+"; "+closeNamespace()); else { agStream.writeLine(agSpace+openNamespace()); agSpace+=" "; agStream.writeLine(agSpace+"class "+shortName()+";");
while (lcCounter<classes().size()) { lcClass=(JirkClass)classes().elementAt(lcCounter); lcClass.writeForwardDeclaration(agStream,agSpace); ++lcCounter; }
agSpace=agSpace.substring(0,agSpace.length()-1); agStream.writeLine(agSpace+closeNamespace()); } } else { agStream.writeLine(agSpace+"class "+shortName()+";"); if (classes()==null) buildClasses(null,null,null,null);
while (lcCounter<classes().size()) { lcClass=(JirkClass)classes().elementAt(lcCounter); lcClass.writeForwardDeclaration(agStream,agSpace); ++lcCounter; } } } //---------------------------------------------------------------------------------------WriteLines // Writes into a stream the lines stored in a vector. protected void writeLines(OutputTextStream agStream,Vector agLineS,String agSpace) { int lcCounter = 0;
while (lcCounter<agLineS.size()) { agStream.writeLine(agSpace+(String)agLineS.elementAt(lcCounter)); ++lcCounter; } } //---------------------------------------------------------------------------------WriteDeclaration /*METHOD JirkClass */ /* Writes the Jirk++ declaration of the class into a stream. */ public void writeDeclaration(OutputTextStream agStream,String agSpace) { JirkAttribute lcAttribute; JirkClass lcClass; JirkConstructor lcConstructor; int lcCounter; Iterator lcIterator; Vector lcLineS; JirkMethod lcMethod;
if (!isInner()) { // Head // agStream.writeLine(agSpace+"/*"); agStream.writeLine(agSpace+" Automatically generated by"); agStream.writeLine(agSpace+" B u i l d J i r k"); agStream.writeLine(agSpace+" "+bpp.JavaInformation.copyright()); agStream.writeLine(agSpace+" Bruno Bachelet"); agStream.writeLine(agSpace+" bruno@nawouak.net"); agStream.writeLine(agSpace+" http://www.nawouak.net"); agStream.writeLine(agSpace+"*/"); agStream.writeLine(); agStream.writeLine(agSpace+"// Represents '"+javaName()+"'."); agStream.writeLine();
// Guardian // agStream.writeLine(agSpace+"#ifndef "+guardian()); agStream.writeLine(agSpace+"#define "+guardian()); agStream.writeLine();
// B++ Part // agStream.writeLine(agSpace+"#include <bpp/java.hpp>");
// Includes // lcIterator=includes().iterator();
while (lcIterator.hasNext()) { lcClass=(JirkClass)lcIterator.next();
if (!lcClass.javaName().equals(javaName())) agStream.writeLine(agSpace+"#include <"+lcClass.file()+".hpp>"); }
agStream.writeLine(); agStream.writeLine(agSpace+"#ifdef JIRK_DLL"); agStream.writeLine(agSpace+" #define dll_export DLL_EXPORT"); agStream.writeLine(agSpace+"#else"); agStream.writeLine(agSpace+" #define dll_export DLL_IMPORT"); agStream.writeLine(agSpace+"#endif");
// Dependencies First Declaration // lcIterator=dependencies().iterator();
while (lcIterator.hasNext()) { lcClass=(JirkClass)lcIterator.next();
if (!lcClass.javaName().equals(javaName()) && !includes().contains(lcClass)) { agStream.writeLine(); lcClass.writeForwardDeclaration(agStream,agSpace); } }
agStream.writeLine(); writeForwardDeclaration(agStream,agSpace);
// Namespace // agStream.writeLine(); agStream.writeLine(agSpace+openNamespace()); agSpace+=" "; agStream.writeLine(agSpace+"using namespace ::bpp::java;"); agStream.writeLine(); }
// Class Definition // agStream.writeLine(agSpace+"class "+shortName()); writeLines(agStream,inheritance(),agSpace);
// Constructors & Affectation Operators // agStream.writeLine(agSpace+" private_property static clInitializerMutex atMutex;"); agStream.writeLine(); agStream.writeLine(agSpace+" private_property static jyClass atClassPointer(void);");
agStream.writeLine(agSpace+" private_property static tcString atClassName(void) "+ "{ return (\""+signature().substring(1,signature().length()-1)+"\"); }");
agStream.writeLine(agSpace+" public_property "+shortName()+"(void) : clObject() {}");
agStream.writeLine(agSpace+" public_property "+shortName()+"(const "+shortName()+" & agObject) "+ ": clObject() { clObject::copy(agObject); }");
agStream.writeLine(agSpace+" public_property "+shortName()+"(jyObject agPointer) "+ ": clObject() { clObject::copy(agPointer); }");
agStream.writeLine(agSpace+" public_property virtual tcString className(void) const "+ "{ return ("+shortName()+"::atClassName()); }");
agStream.writeLine(agSpace+" public_property virtual jyClass classPointer(void) const "+ "{ return ("+shortName()+"::atClassPointer()); }");
agStream.writeLine(agSpace+" public_property "+shortName()+" & operator = (const "+shortName()+ " & agObject) { clObject::copy(agObject); return (*this); }");
agStream.writeLine(agSpace+" public_property "+shortName()+" & operator = (jyObject agPointer) "+ "{ clObject::copy(agPointer); return (*this); }");
if (javaName().equals("java.lang.String")) { agStream.writeLine(agSpace+" public_property "+shortName()+"(tcString agString) "+ ": clObject() { clObject::copy(clContext().newString(agString)); }");
agStream.writeLine(agSpace+" public_property "+shortName()+"(ctString & agString) "+ ": clObject() { clObject::copy(clContext().newString(agString.data())); }");
agStream.writeLine(agSpace+" public_property "+shortName()+" & operator = (tcString agString) "+ "{ clObject::copy(clContext().newString(agString)); return (*this); }");
agStream.writeLine(agSpace+" public_property "+shortName()+" & operator = (ctString & agString) "+ "{ clObject::copy(clContext().newString(agString.data())); "+ "return (*this); }");
agStream.writeLine(agSpace+" public_property clString native(void) const;");
agStream.writeLine(agSpace+" public_property static jyObject j_new(tcString agString) "+ "{ return (clContext().newString(agString)); }");
agStream.writeLine(agSpace+" public_property static jyObject j_new(ctString & agString) "+ "{ return (clContext().newString(agString.data())); }"); }
agStream.writeLine(); agStream.writeLine(agSpace+" #ifdef VIRTUAL_INHERITANCE_BUG");
agStream.writeLine(agSpace+" public_property virtual ~"+shortName()+"(void) "+ "{ unregisterObject(atJniPointer); atJniPointer=nil; }");
agStream.writeLine(agSpace+" #endif");
// Attributes Declaration // lcCounter=0;
while (lcCounter<attributes().size()) { agStream.writeLine(); lcAttribute=(JirkAttribute)attributes().elementAt(lcCounter); writeLines(agStream,lcAttribute.declaration(),agSpace); ++lcCounter; }
// Constructors Declaration // if (constructors().size()>0) agStream.writeLine(); lcCounter=0;
while (lcCounter<constructors().size()) { lcConstructor=(JirkConstructor)constructors().elementAt(lcCounter); writeLines(agStream,lcConstructor.declaration(),agSpace); ++lcCounter; }
// Methods Declaration // if (methods().size()>0) agStream.writeLine(); lcCounter=0;
while (lcCounter<methods().size()) { lcMethod=(JirkMethod)methods().elementAt(lcCounter); writeLines(agStream,lcMethod.declaration(),agSpace); ++lcCounter; }
// Class Closing // agStream.writeLine(agSpace+"};");
// Inner Classes Declaration // lcCounter=0;
while (lcCounter<classes().size()) { agStream.writeLine(); lcClass=(JirkClass)classes().elementAt(lcCounter); lcClass.writeDeclaration(agStream,agSpace); ++lcCounter; }
// End // if (!isInner()) { agSpace=agSpace.substring(0,agSpace.length()-1); agStream.writeLine(agSpace+closeNamespace()); agStream.writeLine(); agStream.writeLine("#undef dll_export"); agStream.writeLine(agSpace+"#endif"); } } //----------------------------------------------------------------------------------WriteDefinition /*METHOD JirkClass */ /* Writes the Jirk++ definition of the class into a stream. */ public void writeDefinition(OutputTextStream agStream,String agSpace) { JirkAttribute lcAttribute; JirkClass lcClass; JirkConstructor lcConstructor; int lcCounter; Iterator lcIterator; Vector lcLineS; JirkMethod lcMethod;
if (!isInner()) { // Head // agStream.writeLine(agSpace+"/*"); agStream.writeLine(agSpace+" Automatically generated by"); agStream.writeLine(agSpace+" B u i l d J i r k"); agStream.writeLine(agSpace+" "+bpp.JavaInformation.copyright()); agStream.writeLine(agSpace+" Bruno Bachelet"); agStream.writeLine(agSpace+" bruno@nawouak.net"); agStream.writeLine(agSpace+" http://www.nawouak.net"); agStream.writeLine(agSpace+"*/"); agStream.writeLine(); agStream.writeLine(agSpace+"// Represents '"+javaName()+"'."); agStream.writeLine();
// DLL Instruction // agStream.writeLine(agSpace+"#define JIRK_DLL"); agStream.writeLine();
// Includes // lcCounter=0; lcIterator=dependencies().iterator();
while (lcIterator.hasNext()) { lcClass=(JirkClass)lcIterator.next();
if (!lcClass.javaName().equals(javaName())) { agStream.writeLine(agSpace+"#include <"+lcClass.file()+".hpp>"); ++lcCounter; } }
agStream.writeLine(agSpace+"#include <"+file()+".hpp>"); agStream.writeLine(); agStream.writeLine(agSpace+"#define dll_export DLL_EXPORT"); agStream.writeLine();
// Namespace // agStream.writeLine(agSpace+openNamespace()); agSpace+=" "; agStream.writeLine(agSpace+"using namespace ::bpp::java;"); agStream.writeLine(); }
// Class Pointer // agStream.writeLine(agSpace+"property clInitializerMutex "+shortName()+"::atMutex;"); agStream.writeLine(); agStream.writeLine(agSpace+"property jyClass "+shortName()+"::atClassPointer(void) {"); agStream.writeLine(agSpace+" static jyClass lcClassPointer;"); agStream.writeLine(agSpace+" if (atMutex.tryLock()) {"); agStream.write(agSpace+" lcClassPointer=clContext().globalClass(clContext()"); agStream.writeLine(".getClass(atClassName()));"); agStream.writeLine(agSpace+" atMutex.release();"); agStream.writeLine(agSpace+" }"); agStream.writeLine(agSpace+" return (lcClassPointer);"); agStream.writeLine(agSpace+"}");
// Native String // if (javaName().equals("java.lang.String")) { agStream.writeLine();
agStream.writeLine(agSpace+"property clString jaString::native(void) const "+ "{ return (clContext().getString(jniPointer())); }"); }
// Inner Classes Definition // lcCounter=0;
while (lcCounter<classes().size()) { agStream.writeLine(); lcClass=(JirkClass)classes().elementAt(lcCounter); lcClass.writeDefinition(agStream,agSpace); ++lcCounter; }
// Attributes Definition // lcCounter=0;
while (lcCounter<attributes().size()) { agStream.writeLine(); lcAttribute=(JirkAttribute)(attributes().elementAt(lcCounter)); writeLines(agStream,lcAttribute.definition(),agSpace); ++lcCounter; }
// Constructors Definition // lcCounter=0;
while (lcCounter<constructors().size()) { agStream.writeLine(); lcConstructor=(JirkConstructor)(constructors().elementAt(lcCounter)); writeLines(agStream,lcConstructor.definition(),agSpace); ++lcCounter; }
// Methods Definition // lcCounter=0;
while (lcCounter<methods().size()) { agStream.writeLine(); lcMethod=(JirkMethod)(methods().elementAt(lcCounter)); writeLines(agStream,lcMethod.definition(),agSpace); ++lcCounter; }
// End // if (!isInner()) { agSpace=agSpace.substring(0,agSpace.length()-1); agStream.writeLine(agSpace+closeNamespace()); } } //--------------------------------------------------------------------------------GenerateHierarchy /*METHOD JirkClass */ /* Generates the Jirk++ hierarchy representing a given list of Java classes and the classes they depend on. If the Jirk++ representation of a Java class already exists, nothing is done. Only the missing classes are added to the Jirk++ hierarchy. */ public static void generateHierarchy(String agPath,TreeSet agToGenerateS, OutputTextStream agStream, boolean agDisplayed) throws Exception { JirkClass lcClass; OutputTextFile lcFile; File lcPath;
TreeSet lcAlreadyGeneratedS = new TreeSet(); String lcRoot = agPath+"/";
if (agDisplayed) agStream.writeLine("[>] Generating Jirk++ Hierarchy...");
while (agToGenerateS.size()>0) { lcClass=(JirkClass)agToGenerateS.first(); agToGenerateS.remove(lcClass); lcAlreadyGeneratedS.add(new JirkClass(lcClass)); lcClass.build(null,null,agToGenerateS,lcAlreadyGeneratedS);
if (!lcClass.isPrimitive() && !lcClass.isArray()) { lcPath=new File(lcRoot+lcClass.folder()); if (!lcPath.exists()) lcPath.mkdirs(); lcPath=new File(lcRoot+lcClass.file()+".hpp");
if (!lcPath.exists()) { if (agDisplayed) agStream.writeLine(" "+lcClass.javaName()); lcFile=new OutputTextFile(lcRoot+lcClass.file()+".hpp"); lcClass.writeDeclaration(lcFile,""); lcFile=new OutputTextFile(lcRoot+lcClass.file()+".cpp"); lcClass.writeDefinition(lcFile,""); lcFile=null; } } } } }
// End //------------------------------------------------------------------------------------------- |
|