//==================================================================================================
// J a v a                                                                                     Java
// R e f l e c t i o n
// J i r k A t t r i b u t e
//                                                                                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 attribute. */

// Package //---------------------------------------------------------------------------------------
package bpp.java.reflection;

// Inportation //-----------------------------------------------------------------------------------
import java.lang.reflect.*;
import java.util.*;

@SuppressWarnings("unchecked")

// J i r k A t t r i b u t e  Class //--------------------------------------------------------------
/*CLASS JirkAttribute */
/* Represents an attribute of a Java class and its Jirk++ representation. */
public class JirkAttribute {
 //---------------------------------------------------------------------------------------Attributes
 protected Field     atAttribute; // Reference of the attribute.
 protected JirkClass atClass;     // Class the attribute belongs to.
 //--------------------------------------------------------------------------------------Constructor
 /*METHOD JirkAttribute */
 /* Builds an object representing a given attribute of a given class. */
 public JirkAttribute(JirkClass agClass,Field agAttribute) {
  atAttribute=agAttribute;
  atClass=agClass;
 }
 //---------------------------------------------------------------------------------------------Name
 /*METHOD JirkAttribute */ /* Returns the name of the attribute. */
 public String name() { return (atAttribute.getName()); }
 //-----------------------------------------------------------------------------------------IsPublic
 /*METHOD JirkAttribute */ /* Indicates if the attribute is public. */
 public boolean isPublic() { return (Modifier.isPublic(atAttribute.getModifiers())); }
 //-----------------------------------------------------------------------------------------IsStatic
 /*METHOD JirkAttribute */ /* Indicates if the attribute is static. */
 public boolean isStatic() { return (Modifier.isStatic(atAttribute.getModifiers())); }
 //---------------------------------------------------------------------------------------------Type
 /*METHOD JirkAttribute */ /* Returns the type of the attribute. */
 public JirkClass type() { return (new JirkClass(atAttribute.getType())); }
 //--------------------------------------------------------------------------------------Declaration
 /*METHOD JirkAttribute */ /* Returns the Jirk++ declaration of the attribute. */
 public Vector declaration() {
  String lcConst      = (isStatic() ? "" : " const");
  String lcConstValue = (type().isArray() ? "" : "const ");
  Vector lcLineS      = new Vector();
  String lcType       = (type().isPrimitive() ? type().fullName() : "jyObject");
  String lcStatic     = (isStatic() ? "static " : "");

  lcLineS.add(" public_property "+lcStatic+lcType+" j_"+name()+"(void)"+lcConst+";");

  lcLineS.add(" public_property "+lcStatic+"void j_"+name()+
              "("+lcConstValue+type().fullName()+" &)"+lcConst+";");

  return (lcLineS);
 }
 //---------------------------------------------------------------------------------------Definition
 /*METHOD JirkAttribute */ /* Returns the Jirk++ definition of the attribute. */
 public Vector definition() {
  String lcClass      = atClass.shortName()+(isStatic() ? "::atC" : "::c")+"lassPointer()";
  String lcConst      = (isStatic() ? "" : " const" );
  String lcConstValue = (type().isArray() ? "" : "const ");
  String lcInstance   = (isStatic() ? "Class" : "Instance");
  Vector lcLineS      = new Vector();
  String lcPointer    = (isStatic() ? lcClass : "jniPointer()");
  String lcStatic     = (isStatic() ? "static " : "");
  String lcType       = (type().isPrimitive() ? type().fullName() : "jyObject");
  String lcValue      = (type().isPrimitive() ? "agValue" : "agValue.jniPointer()");

  lcLineS.add("property "+lcType+" "+atClass.shortName()+"::j_"+name()+"(void)"+lcConst+" {");

  lcLineS.add(" safe_static jyAttribute lcAttribute = clContext().get"+lcInstance+"Attribute("+
              lcClass+",\""+name()+"\",\""+type().signature()+"\");");

  lcLineS.add(" return (clContext().read"+lcInstance+type().name()+"Attribute("+
              lcPointer+",lcAttribute));");

  lcLineS.add("}");
  lcLineS.add("");

  lcLineS.add("property void "+atClass.shortName()+"::j_"+name()+
              "("+lcConstValue+type().fullName()+" & agValue)"+lcConst+" {");

  lcLineS.add(" safe_static jyAttribute lcAttribute = clContext().get"+lcInstance+"Attribute("+
              lcClass+",\""+name()+"\",\""+type().signature()+"\");");

  if (type().isArray()) lcLineS.add(" agValue.synchronizeJavaSide();");

  lcLineS.add(" clContext().write"+lcInstance+type().name()+"Attribute"+
              "("+lcPointer+",lcAttribute,"+lcValue+");");

  lcLineS.add("}");
  return (lcLineS);
 }
}

// End //-------------------------------------------------------------------------------------------