# NativeAPIEntry.java

    /*
    ** Module   : NativeAPIEntry.java
    ** Abstract : stores metadata relating to a native API call
    **
    ** Copyright (c) 2013-2018, Golden Code Development Corporation.
    **
    ** -#- -I- --Date-- ---------------------------------Description---------------------------------
    ** 001 GES 20131125 First version.
    ** 002 ECF 20150601 Dropped type parameter from c'tor; type is implied.
    ** 003 CA  20181029 Added getters for the Native API configuration.
    **                  Added THREAD-SAFE flag - not in use at this time.
    */
    /*
    ** This program is free software: you can redistribute it and/or modify
    ** it under the terms of the GNU Affero General Public License as
    ** published by the Free Software Foundation, either version 3 of the
    ** License, or (at your option) any later version.
    **
    ** This program 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 Affero General Public License for more details.
    **
    ** You may find a copy of the GNU Affero GPL version 3 at the following
    ** location: https://www.gnu.org/licenses/agpl-3.0.en.html
    **
    ** Additional terms under GNU Affero GPL version 3 section 7:
    **
    **   Under Section 7 of the GNU Affero GPL version 3, the following additional
    **   terms apply to the works covered under the License.  These additional terms
    **   are non-permissive additional terms allowed under Section 7 of the GNU
    **   Affero GPL version 3 and may not be removed by you.
    **
    **   0. Attribution Requirement.
    **
    **     You must preserve all legal notices or author attributions in the covered
    **     work or Appropriate Legal Notices displayed by works containing the covered
    **     work.  You may not remove from the covered work any author or developer
    **     credit already included within the covered work.
    **
    **   1. No License To Use Trademarks.
    **
    **     This license does not grant any license or rights to use the trademarks
    **     Golden Code, FWD, any Golden Code or FWD logo, or any other trademarks
    **     of Golden Code Development Corporation. You are not authorized to use the
    **     name Golden Code, FWD, or the names of any author or contributor, for
    **     publicity purposes without written authorization.
    **
    **   2. No Misrepresentation of Affiliation.
    **
    **     You may not represent yourself as Golden Code Development Corporation or FWD.
    **
    **     You may not represent yourself for publicity purposes as associated with
    **     Golden Code Development Corporation, FWD, or any author or contributor to
    **     the covered work, without written authorization.
    **
    **   3. No Misrepresentation of Source or Origin.
    **
    **     You may not represent the covered work as solely your work.  All modified
    **     versions of the covered work must be marked in a reasonable way to make it
    **     clear that the modified work is not originating from Golden Code Development
    **     Corporation or FWD.  All modified versions must contain the notices of
    **     attribution required in this license.
    */

    package com.goldencode.p2j.library;

    import com.goldencode.p2j.util.*;

    /**
     * Container for legacy info belonging to an native API call.
     */
    public class NativeAPIEntry
    extends InternalEntry
    {
       /** Library name in which this native API exists. */
       private String libname = null;

       /** The API calling convention. */
       private CallingConvention callconv = CallingConvention.DEFAULT;

       /** Flag to determine if a library loaded just for this call should be kept in memory. */
       private boolean persistent = false;

       /** The ordinal if the API is exported via ordinal instead of name. */
       private int ordinal = -1;

       /** Marks this native API as having the legacy THREAD-SAFE option. */
       private boolean threadSafe = false;

       /**
        * Construct an instance.
        *
        * @param    pname
        *           Legacy 4GL name for this internal-entry.
        * @param    jname
        *           Converted Java name for this internal-entry.
        */
       public NativeAPIEntry(String pname, String jname)
       {
          super(pname, jname, InternalEntry.Type.DLL_ENTRY);
       }

       /**
        * Set the value of the given attribute.  Any attributes that are specific to the native
        * API call will be parsed and stored as members, instead of being added to the map of
        * attributes.
        *
        * @param    name
        *           The attribute's name.
        * @param    value
        *           The attribute's value.
        */
       public void putAttribute(String name, String value)
       {
          // TODO: we could also check for empty string here, but I don't know if it is safe (it
          //       might be used for the non-native attributes)
          if (name == null || value == null)
             return;

          name = name.toLowerCase();

          if ("thread-safe".equals(name))
          {
             threadSafe = true;
          }
          else if ("libname".equals(name))
          {
             libname = value;
          }
          else if ("callconv".equals(name))
          {
             try
             {
                callconv = CallingConvention.valueOf(value.toUpperCase());
             }

             catch (IllegalArgumentException iae)
             {
                // misformed value, ignore it
             }
          }
          else if ("persistent".equals(name))
          {
             // any misformed value should parse as false
             persistent = Boolean.parseBoolean(value);
          }
          else if ("ordinal".equals(name))
          {
             try
             {
                ordinal = Integer.parseInt(value);
             }

             catch (NumberFormatException nfe)
             {
                // misformed value, ignore it
             }
          }

          // always save the attribute into the map because the SourceNameMapper uses it that way
          super.putAttribute(name, value);
       }

       /**
        * Get the library name.
        *
        * @return   The library name.
        */
       public String getLibraryName()
       {
          return libname;
       }

       /**
        * Set the {@link #libname library name}.
        *
        * @param    libname
        *           The library name.
        */
       public void setLibraryName(String libname)
       {
          this.libname = libname;
       }

       /**
        * Get the calling convention.
        *
        * @return   The calling convention.
        */
       public CallingConvention getCallingConvention()
       {
          return callconv;
       }

       /**
        * Set the {@link #callconv calling convention}.
        *
        * @param    callconv
        *           The calling convention.
        */
       public void setCallingConvention(CallingConvention callconv)
       {
          this.callconv = callconv;
       }

       /**
        * Checks if the library should be loaded persistently.
        *
        * @return   <code>true</code> if the library should be loaded persistently.
        */
       public boolean isPersistent()
       {
          return persistent;
       }

       /**
        * Set the {@link #persistent} flag.
        *
        * @param    persistent
        *           The new value of this flag.
        */
       public void setPersistent(boolean persistent)
       {
          this.persistent = persistent;
       }

       /**
        * Get the ordinal.
        *
        * @return   The ordinal that the API is exported as or -1 if no ordinal was specified.
        */
       public int getOrdinal()
       {
          return ordinal;
       }

       /**
        * Set the {@link #ordinal} for this API.
        *
        * @param    ordinal
        *           The ordinal value.
        */
       public void setOrdinal(int ordinal)
       {
          this.ordinal = ordinal;
       }

       /**
        * Get the state of the {@link #threadSafe thread-safe} option.
        *
        * @return   See above.
        */
       public boolean isThreadSafe()
       {
          return threadSafe;
       }

       /**
        * Set the {@link #threadSafe thread-safe} option.
        *
        * @param    threadSafe
        *           The new value of this flag.
        */
       public void setThreadSafe(boolean threadSafe)
       {
          this.threadSafe = threadSafe;
       }
    }