/** * This file is part of ObjectFabric (http://objectfabric.org). * * ObjectFabric is licensed under the Apache License, Version 2.0, the terms * of which may be found at http://www.apache.org/licenses/LICENSE-2.0.html. * * Copyright ObjectFabric Inc. * * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ package org.objectfabric; class FileGeneratorObjectModel extends FileGenerator { FileGeneratorObjectModel(GeneratorBase generator) { super(generator, generator.objectModel().rootPackage().fullName(), generator.objectModel().Name); } @Override String onLine(String line) { return FileGeneratorClass.replace(line, g().isCSharp()); } @Override void header() { copyright(); wl(); if (g().isCSharp()) { wl("using System;"); wl(); warning(); wl(); wl("namespace " + Package); wl("{"); tab(); } else { wl("package " + Package + ";"); wl(); warning(); } if (g().isJava()) wl("@SuppressWarnings({ \"hiding\", \"unchecked\", \"static-access\", \"rawtypes\" })"); String public_ = g().objectModel().Public ? "public " : ""; String final_ = g().isCSharp() ? "sealed " : "final "; wl(public_ + final_ + "class " + Name + " " + g().target().extendsString() + " org.objectfabric.ObjectModel {"); wl(); byte[] uid = g().objectModelUID(); String uidText = "" + (g().isJava() ? uid[0] : uid[0] & 0xff); for (int i = 1; i < uid.length; i++) uidText += ", " + (g().isJava() ? uid[i] : uid[i] & 0xff); wl(" private static " + (g().isCSharp() ? "readonly" : "final") + " byte[] UID = { " + uidText + " };"); wl(); wl(" // volatile not needed, models have no state"); wl(" private static " + g().objectModel().Name + " _instance;"); wl(); wl(" private static " + (g().isCSharp() ? "readonly" : "final") + " java.lang.Object _lock = new java.lang.Object();"); wl(); wl(" protected " + Name + "() {"); wl(" }"); wl(); if (g().isCSharp()) { wl(" public static " + g().objectModel().Name + " Instance"); wl(" {"); wl(" get"); wl(" {"); wl(" if (_instance == null)"); wl(" lock (_lock)"); wl(" if (_instance == null)"); wl(" _instance = new " + g().objectModel().Name + "();"); wl(); wl(" return _instance;"); wl(" }"); wl(" }"); } else { wl(" public static " + g().objectModel().Name + " instance() {"); wl(" if (_instance == null) {"); wl(" synchronized (_lock) {"); wl(" if (_instance == null)"); wl(" _instance = new " + g().objectModel().Name + "();"); wl(" }"); wl(" }"); wl(); wl(" return _instance;"); wl(" }"); } wl(); wl(" public static byte[] uid() {"); wl(" byte[] copy = new byte[UID.length];"); wl(" arraycopy(UID, copy);"); wl(" return copy;"); wl(" }"); wl(); if (g().isJava()) wl(" @Override"); wl(" protected" + g().target().overrideString() + "byte[] uid_() {"); wl(" return UID;"); wl(" }"); wl(); wl(" /**"); wl(" * Registers this object model so that its classes can be serialized by the"); wl(" * system."); wl(" */"); wl(" public static void " + (g().isCSharp() ? "R" : "r") + "egister() {"); wl(" register(" + (g().isCSharp() ? "Instance" : "instance()") + ");"); wl(" }"); wl(); if (g().isJava()) wl(" @Override"); wl(" protected" + g().target().overrideString() + g().target().stringString() + " objectFabricVersion() {"); wl(" return \"" + TObject.OBJECT_FABRIC_VERSION + "\";"); wl(" }"); wl(); } @Override void body() { List<String> names = g().objectModel().allFullClassNames(); wl(" public static final int CLASS_COUNT = " + names.size() + ";"); wl(); for (int i = 0; i < g().objectModel().allClassIds().size(); i++) { wl(" public static final int " + g().objectModel().allClassIds().get(i) + " = " + i + ";"); wl(); } List<MethodDef> methods = g().objectModel().allMethods(); wl(" public static final int METHOD_COUNT = " + methods.size() + ";"); wl(); for (int i = 0; i < g().objectModel().allMethodIds().size(); i++) { wl(" public static final int " + g().objectModel().allMethodIds().get(i) + " = " + (i + names.size()) + ";"); wl(); } if (g().isJava()) wl(" @Override"); String types = g().isCSharp() ? "" : ", org.objectfabric.TType[] genericParameters"; wl(" protected" + g().target().overrideString() + g().target().classString() + " getClass(int classId" + types + ") {"); wl(" switch (classId) {"); for (int i = 0; i < g().objectModel().allClassIds().size(); i++) { wl(" case " + g().objectModel().allClassIds().get(i) + ":"); if (g().isJava()) wl(" return " + names.get(i) + ".class;"); else wl(" return typeof(" + names.get(i) + ");"); } for (int i = 0; i < g().objectModel().allMethodIds().size(); i++) { wl(" case " + g().objectModel().allMethodIds().get(i) + ":"); if (g().isJava()) wl(" return Method" + i + ".class;"); else wl(" return typeof(Method" + i + ");"); } wl(" }"); wl(); if (g().isJava()) wl(" return super.getClass(classId, genericParameters);"); else wl(" return base.getClass(classId);"); wl(" }"); wl(); if (g().isJava()) wl(" @Override"); String ret = g().isCSharp() ? "object" : "org.objectfabric.TObject"; wl(" protected" + g().target().overrideString() + ret + " createInstance(org.objectfabric.Resource resource, int classId" + types + ") {"); wl(" switch (classId) {"); for (int i = 0; i < g().objectModel().allClasses().size(); i++) { StringBuilder args = new StringBuilder(); List<ValueDef> values = g().objectModel().allClasses().get(i).allValues(g().objectModel()); for (int t = 0; t < values.size(); t++) if (values.get(t).isReadOnly()) args.append(", " + values.get(t).type().defaultString()); wl(" case " + g().objectModel().allClassIds().get(i) + ":"); wl(" return new " + names.get(i) + "(resource" + args + ");"); } for (int i = 0; i < g().objectModel().allMethodIds().size(); i++) { wl(" case " + g().objectModel().allMethodIds().get(i) + ":"); wl(" return new Method" + i + "(resource);"); } wl(" }"); wl(); if (g().isJava()) wl(" return super.createInstance(resource, classId, genericParameters);"); else wl(" return base.createInstance(resource, classId);"); wl(" }"); wl(); for (int i = 0; i < methods.size(); i++) { String ext; if (methods.get(i).lessOr32Fields(g().objectModel())) ext = "org.objectfabric.TIndexed.Version32"; else ext = "org.objectfabric.TIndexed.VersionN"; ext += (g().isJava() ? " implements" : ",") + " org.objectfabric.TObject.UserTObject.Method"; String name = methods.get(i).actualName(g().objectModel()); wl(); wl(" public " + (g().isCSharp() ? "" : "static ") + "class " + name + " " + g().target().extendsString() + " " + ext + " {"); wl(); wl(" private static final org.objectfabric.TObject.UserTObject.MethodCache<" + name + "> _cache = new org.objectfabric.TObject.UserTObject.MethodCache<" + name + ">() {"); wl(); if (g().isJava()) wl(" @Override"); wl(" protected " + name + " create(java.lang.Object param) {"); wl(" return new " + name + "((org.objectfabric.View) param);"); wl(" }"); wl(" };"); wl(); if (g().isJava()) { wl(" private " + name + "(org.objectfabric.Resource resource) {"); wl(" super(resource, new Version(null, FIELD_COUNT));"); } else { wl(" internal " + name + "(org.objectfabric.Resource resource)"); wl(" : base(resource, new Version(null, FIELD_COUNT)) {"); } wl(" }"); wl(); wl(" public java.lang.String name() {"); wl(" return \"" + methods.get(i).Name + "\";"); wl(" }"); wl(); wl(" public static " + name + " getOrCreateInstance(org.objectfabric.Resource resource) {"); wl(" return _cache.getOrCreate(resource);"); wl(" }"); wl(); if (g().isJava()) wl(" @Override"); wl(" public void release() {"); wl(" _cache.recycle(this);"); wl(" }"); tab(); FileGeneratorValueSet dsWriter = new FileGeneratorValueSet(g(), methods.get(i), this); dsWriter.writeType(); dsWriter.writeFieldsConstantsAndCount(); dsWriter.writeVersion(); untab(); wl(" }"); } } @Override void footer() { if (g().isCSharp()) { wl("}"); untab(); } wl("}"); } }