All Downloads are FREE. Search and download functionalities are using the official Maven repository.

src.com.ibm.as400.access.ProductLicense Maven / Gradle / Ivy

There is a newer version: 20.0.7
Show newest version
///////////////////////////////////////////////////////////////////////////////
//
// JTOpen (IBM Toolbox for Java - OSS version)
//
// Filename:  ProductLicense.java
//
// The source code contained herein is licensed under the IBM Public License
// Version 1.0, which has been approved by the Open Source Initiative.
// Copyright (C) 1997-2004 International Business Machines Corporation and
// others.  All rights reserved.
//
///////////////////////////////////////////////////////////////////////////////


package com.ibm.as400.access;

import java.beans.PropertyChangeSupport;                        // @A2A
import java.beans.PropertyChangeListener;                       // @A2A
import java.io.IOException;
import java.io.ObjectInputStream;
import java.util.Vector;                                        // @A2A



/**
*   Represents a license for a product on the IBM i system. To request
*   a license, construct a ProductLicense object then invoke the request() method.
*   The caller must keep a reference to the ProductLicense object until the
*   license is no longer needed since the ProductLicense object will release
*   the license when it is garbage collected.  Licenses are managed on a
*   per-connection basis.  Each ProductLicense object has a separate connection to
*   the system.  If the connection ends unexpectedly the system
*   releases the license.  To maintain an accurate count, the application should
*   call release() instead of relying on the license being released when the object
*   is garbage collected or when the connection ends.  Cleanup during garbage
*   collection and/or system cleanup is not as reliable as calling release().
*
*  

* The ProductLicense class does not enforce the license policy. It is up to the * application to enforce the policy based on information contained in the ProductLicense * object after the license is requested. If a license is not granted, indicated by a * LicenseException, it is up to the application to notify the user and not perform the * behavior that requires a license. * *

* The ProductLicense object may successfully get a license even though there was an error * retrieving the product license. These "soft" errors are usage limit exceeded, but license * limit not strictly enforced (CONDITION_EXCEEDED_OK), usage limit exceeded, but within grace * period (CONDITION_EXCEED_GRACE_PERIOD) and usage limit exceeded and grace period expired * but not strictly enforced (CONDITION_GRACE_PERIOD_EXPIRED.) The application must decide * to continue or end the application based on this information. * *

* The request() method will throw a LicenseException if no license is available. If a license * is granted, the ProductLicense object contains information about the license such * as the compliance type and license condition. * *

Example

* *
*
*        AS400 system = new AS400("myas400");
*        // request a license for "myproductID" and "myfeatureID" for "myrelease"
*        try
*        {
*            ProductLicense license = new ProductLicense(system,
*                                                        "myproductID",
*                                                        "myfeatureID",
*                                                        "myrelease");
*            license.request();
*            switch (license.getCondition())
*            {
*                case ProductLicense.CONDITION_OK:
*                    // license retrieved successfully
*                    break;
*                case ProductLicense.CONDITION_EXCEEDED_OK:
*                    // usage limit exceeded, but license limit not strictly enforced
*                    // issue message but allow to proceed.
*                    sendMessage("Usage limit exceeded, but license limit not strictly enforced");
*                    break;
*                case ProductLicense.CONDITION_EXCEEDED_GRACE_PERIOD:
*                    // usage limit exceeded, but within grace period
*                    // issue message but allow to proceed
*                    sendMessage("Usage limit exceeded, but within grace period");
*                    break;
*                case ProductLicense.CONDITION_GRACE_PERIOD_EXPIRED:
*                    // usage limit exceeded and grace period expired but not strictly enforced
*                    // issue message but allow to proceed
*                    sendMessage("Usage limit exceeded and grace period expired but not strictly enforced");
*                    break;
*                default:
*                    // Some other condition.
*                    // This should never happen, but if it does, display value.
*                    sendMessage("Unrecognized condition: " + license.getCondition());
*            }
*            ..
*            ..
*            // product code...
*            ..
*            ..
*            // release the license
*            license.release();
*        }
*        catch (LicenseException le)
*        {
*            // handle license failures such as license expired...
*        }
*        catch (Exception e)
*        {
*            // handle general failures (security error, communication error, etc.)
*        }
*
* 
**/ public class ProductLicense implements java.io.Serializable { /** * Value for license usage type, concurrent usage license type. **/ public final static int USAGE_CONCURRENT = 1; /** * Value for license usage type, registered usage license type. **/ public final static int USAGE_REGISTERED = 2; /** * Value for compliance type, operator action compliance indicates a form * of soft compliance that will not allow a license in the usage limit exceeded * case until the operator increases the maximum number of licenses on the system * (this does not require a license key to increase.) **/ public final static int COMPLIANCE_OPERATOR_ACTION = 1; /** * Value for compliance type, warning compliance indicates that a * warning message will be sent to the system operators message queue * when a license violation, such as usage limit exceeded is encountered. **/ public final static int COMPLIANCE_WARNING = 2; /** * Value for compliance type, keyed compliance indicates a license * that requires a license key to activate the license. **/ public final static int COMPLIANCE_KEYED = 3; /** * Value for license condition, license granted. **/ public static final int CONDITION_OK = 0; /** * Value for license condition, usage limit exceeded, but not enforced. **/ public static final int CONDITION_EXCEEDED_OK = 0x002b; /** * Value for license condition, usage limit exceeded, but within grace period. **/ public static final int CONDITION_EXCEEDED_GRACE_PERIOD = 0x002c; /** * Value for license condition, usage limit exceeded and grace period expired, but not * enforced. **/ public static final int CONDITION_GRACE_PERIOD_EXPIRED = 0x002e; static { AS400Server.addReplyStream(new NLSExchangeAttrReply(), "as-central"); AS400Server.addReplyStream(new LicenseGetReply(), "as-central"); AS400Server.addReplyStream(new LicenseReleaseReply(), "as-central"); AS400Server.addReplyStream(new LicenseGetInformationReply(), "as-central"); } transient private PropertyChangeSupport changes_; // @A2A transient private Vector productLicenseListeners_; // @A2A static final long serialVersionUID = 4L; // @A2A transient private boolean released_; // @A2C transient private int condition_; // @A2C transient private AS400 sys_; // @A2C transient private AS400Server server_; // @A2C transient private AS400ImplRemote sysImpl_; // @A2C private String productID_; private String featureID_; private String releaseLevel_; // @A1C transient private int usageLimit_; // @A2C transient private int usageCount_; // @A2C transient private int usageType_; // @A2C transient private int complianceType_; // @A2C transient private String licenseTerm_; // @A2C /** * Constructs a default ProductLicense object. The system, * product, feature and release must be set for requesting a license. **/ public ProductLicense() { initializeTransient(); // @A2A productID_ = null; featureID_ = null; } /** * Constructs a ProductLicense object for a system, product, feature, * and release. * @param system the system from which the license will be requested. * @param productID the product identifier. For example, "5769JC1". * @param featureID the product feature. For example, "5050". * @param release the product release. For example, "V4R5M0". **/ public ProductLicense(AS400 system, String productID, String featureID, String release) { this(); // get a new AS400 object to make sure we get a separate connection sys_ = new AS400(system); if(sys_ == null) { throw new NullPointerException("system"); } if(productID == null) { throw new NullPointerException("productID"); } else { productID_ = productID; } if(featureID == null) { throw new NullPointerException("featureID"); } else { featureID_ = featureID; } if(release == null) { releaseLevel_ = " "; // set correct release variable @A1C } else { releaseLevel_ = release; // set correct release variable @A1C } } /** Adds a file listener to receive file events from this IFSFile. @param listener The file listener. **/ // This function added to enable beans @A2A public void addProductLicenseListener(ProductLicenseListener listener) { if (listener == null) throw new NullPointerException("listener"); productLicenseListeners_.addElement(listener); } /** Adds a property change listener. @param listener The property change listener to add. **/ // This function added to enable beans @A2A public void addPropertyChangeListener(PropertyChangeListener listener) { if (listener == null) throw new NullPointerException("listener"); changes_.addPropertyChangeListener(listener); } /** * Disconnect from the host server. **/ void disconnect() { synchronized(sys_) { if(server_ != null) { if(Trace.traceOn_) { Trace.log(Trace.DIAGNOSTIC, "Disconnecting from server"); } try { sysImpl_.disconnectServer(server_); server_ = null; } catch(Exception e) { if(Trace.traceOn_) { Trace.log(Trace.ERROR, "Exception encountered while disconnecting", e); } } } // (server_ != null) } // synchronized(sys_) } // disconnect() /** * The finalizer. **/ protected void finalize() { if(Trace.traceOn_) { Trace.log(Trace.DIAGNOSTIC, "finalize() - ProductLicense"); } try { release(); } catch(Exception e) { if(Trace.traceOn_) { Trace.log(Trace.ERROR, "release license failed", e); } } } // Fire connect events here so source is public object. private void fireProductLicenseEvent(int status) { ProductLicenseEvent event = new ProductLicenseEvent(this, status); Vector targets = (Vector)productLicenseListeners_.clone(); for (int i = 0; i < targets.size(); ++i) { ProductLicenseListener target = (ProductLicenseListener)targets.elementAt(i); switch(status) { case ProductLicenseEvent.PRODUCT_LICENSE_RELEASED: target.licenseReleased(event); break; case ProductLicenseEvent.PRODUCT_LICENSE_REQUESTED: target.licenseRequested(event); break; default: // This should never happen, but if it does, trace it. Trace.log(Trace.ERROR, "Event status:", status); } } } /** * Returns the compliance type for this license. Possible values are * COMPLIANCE_OPERATOR_ACTION, COMPLIANCE_WARNING and COMPLIANCE_KEYED. * A license must have been requested prior to calling this method. * @return The compliance type. **/ public int getComplianceType() { if(released_) { throw new ExtendedIllegalStateException(ExtendedIllegalStateException.INFORMATION_NOT_AVAILABLE); } return complianceType_; } /** * Returns the condition of the license. Possible values are CONDITION_OK, * CONDITION_EXCEEDED_OK, CONDITION_EXCEEDED_GRACE_PERIOD, * and CONDITION_GRACE_EXPIRED. A license must have been requested prior to * calling this method. * @return The license condition. **/ public int getCondition() { if(released_) throw new ExtendedIllegalStateException(("Object= "+ sys_.getSystemName()), ExtendedIllegalStateException.INFORMATION_NOT_AVAILABLE); return condition_; } /** * Returns the feature identifier for this license. * @return The feature identifier. **/ public String getFeature() { return featureID_; } /** * Returns the license term for this license. A license must * have been requested prior to calling this method. * @return The license term. **/ public String getLicenseTerm() { if(released_) throw new ExtendedIllegalStateException(("Object= "+ sys_.getSystemName()), ExtendedIllegalStateException.INFORMATION_NOT_AVAILABLE); return licenseTerm_; } /** * Returns the product identifier for this license. * @return The product identifier. **/ public String getProductID() { return productID_; } /** * Returns the release level for this license. * @return The release level. **/ public String getReleaseLevel() { return releaseLevel_; } /** * Return the name of the system for this license. A license must have been * requested prior to calling this method. * @return The name of the AS400. **/ /* String getSystemName() { if(released_) throw new ExtendedIllegalStateException(ExtendedIllegalStateException.INFORMATION_NOT_AVAILABLE); return sys_.getSystemName(); } */ /** * Returns the system object for this license. * @return The system. **/ public AS400 getSystem() { return sys_; } /** * Returns the usage count for this license. The count returned is the number * of licenses that are in use on the system for that product ID, feature, and * release when this license was requested. A license must have been requested * prior to calling this method. * @return The usage count when this license was retrieved. **/ public int getUsageCount() { if(released_) throw new ExtendedIllegalStateException(ExtendedIllegalStateException.INFORMATION_NOT_AVAILABLE); return usageCount_; } /** * Returns the usage limit for this license.A license must have been requested prior to * calling this method. * @return The usage limit. **/ public int getUsageLimit() { if(released_) throw new ExtendedIllegalStateException(("Object= "+ sys_.getSystemName()), ExtendedIllegalStateException.INFORMATION_NOT_AVAILABLE); return usageLimit_; } /** * Returns the usage type for this license. Possible values are USAGE_CONCURRENT and * USAGE_REGISTERED. A license must have been requested prior to calling this method. * @return The usage type. **/ public int getUsageType() { if(released_) throw new ExtendedIllegalStateException("UsageType", ExtendedIllegalStateException.INFORMATION_NOT_AVAILABLE); return usageType_; } /** Provided to initialize transient data if this object is de-serialized. // @A2A **/ private void initializeTransient() { changes_ = new PropertyChangeSupport(this); productLicenseListeners_ = new Vector(); sys_ = null; sysImpl_ = null; condition_ = CONDITION_OK; released_ = true; usageLimit_ = 0; usageCount_ = -1; usageType_ = -1; complianceType_ = -1; licenseTerm_ = null; releaseLevel_ = null; } /** * Release this license. This method must be called to release the license. Failure * to do so may result in incorrect license usage count. Calling this method will * disconnect from the IBM i Optimized License Management server. * @exception IOException If an error occurs while communicating with the system. * @exception InterruptedException If this thread is interrupted. * @exception LicenseException If a license error occurs. **/ public void release() throws IOException, InterruptedException, LicenseException { // Verify that the bean properties are set prior to attempting the release. if (sys_ == null) { if(Trace.traceOn_) { Trace.log(Trace.ERROR, "System not set yet."); } throw new ExtendedIllegalStateException("system", ExtendedIllegalStateException.PROPERTY_NOT_SET); } if (productID_ == null) { if(Trace.traceOn_) { Trace.log(Trace.ERROR, "Product ID not set yet."); } throw new ExtendedIllegalStateException("productID", ExtendedIllegalStateException.PROPERTY_NOT_SET); } if (featureID_ == null) { if(Trace.traceOn_) { Trace.log(Trace.ERROR, "Feature ID not set yet."); } throw new ExtendedIllegalStateException("featureID", ExtendedIllegalStateException.PROPERTY_NOT_SET); } if (releaseLevel_ == null) { if(Trace.traceOn_) { Trace.log(Trace.ERROR, "Release not set yet."); } throw new ExtendedIllegalStateException("release", ExtendedIllegalStateException.PROPERTY_NOT_SET); } synchronized(sys_) { if(released_) return; if(Trace.traceOn_) { // release license from server Trace.log(Trace.DIAGNOSTIC, "Releasing license from server"); } if(server_ != null) { LicenseReleaseRequest releaseRequest = new LicenseReleaseRequest(sys_); releaseRequest.setProductID(productID_); releaseRequest.setFeature(featureID_); releaseRequest.setRelease(releaseLevel_); DataStream baseReply = server_.sendAndReceive(releaseRequest); if(baseReply instanceof LicenseReleaseReply) { LicenseReleaseReply releaseReply = (LicenseReleaseReply)baseReply; released_ = true; disconnect(); if(releaseReply.getPrimaryRC() != 0) { Trace.log(Trace.DIAGNOSTIC, "Release license failed, primary return code = ", releaseReply.getPrimaryRC()); Trace.log(Trace.DIAGNOSTIC, "Release license failed, secondary return code = ", releaseReply.getSecondaryRC()); throw new LicenseException(releaseReply.getPrimaryRC(), releaseReply.getSecondaryRC()); } // Fire the license released event. fireProductLicenseEvent(ProductLicenseEvent.PRODUCT_LICENSE_RELEASED); } // baseReply instanceof LicenseReleaseReply } // server_ != null } // synchronized(sys_) } // public void release() /** * Request a license. * @return The condition of the license. Possible values are CONDITION_OK, * CONDITION_EXCEEDED_OK, CONDITION_EXCEEDED_GRACE_PERIOD, * and CONDITION_GRACE_EXPIRED. * @exception IOException If an error occurs while communicating with the system. * @exception AS400SecurityException Unable to connect due to some problem with the user ID or password used to authenticate. * @exception InterruptedException If this thread is interrupted. * @exception LicenseException If a license error occurs. * @exception ExtendedIllegalStateException If a license is requested a second time for the same ProductLicense object. **/ public int request() throws IOException, AS400SecurityException, InterruptedException, LicenseException { // Verify that the bean properties are set prior to attempting the release. if (sys_ == null) { if(Trace.traceOn_) { Trace.log(Trace.ERROR, "System not set yet."); } throw new ExtendedIllegalStateException("system", ExtendedIllegalStateException.PROPERTY_NOT_SET); } if (productID_ == null) { if(Trace.traceOn_) { Trace.log(Trace.ERROR, "Product ID not set yet."); } throw new ExtendedIllegalStateException("productID", ExtendedIllegalStateException.PROPERTY_NOT_SET); } if (featureID_ == null) { if(Trace.traceOn_) { Trace.log(Trace.ERROR, "Feature ID not set yet."); } throw new ExtendedIllegalStateException("featureID", ExtendedIllegalStateException.PROPERTY_NOT_SET); } if (releaseLevel_ == null) { if(Trace.traceOn_) { Trace.log(Trace.ERROR, "Release not set yet."); } throw new ExtendedIllegalStateException("release", ExtendedIllegalStateException.PROPERTY_NOT_SET); } synchronized(sys_) { if(!released_) throw new ExtendedIllegalStateException(("Object= "+ sys_.getSystemName()), ExtendedIllegalStateException.LICENSE_CAN_NOT_BE_REQUESTED); if(Trace.traceOn_) { // request license from server Trace.log(Trace.DIAGNOSTIC, "retrieving license from server"); } sys_.connectService(AS400.CENTRAL); sysImpl_= (AS400ImplRemote) sys_.getImpl(); server_ = sysImpl_.getConnection(AS400.CENTRAL, false, false); NLSExchangeAttrRequest request = new NLSExchangeAttrRequest(); try { server_.sendExchangeAttrRequest(request); } catch(IOException e) { Trace.log(Trace.ERROR, "IOException After Exchange Attribute Request", e); disconnect(); throw e; } DataStream baseReply = server_.getExchangeAttrReply(); if(baseReply instanceof NLSExchangeAttrReply) { // means request completed CONDITION_OK NLSExchangeAttrReply NLSReply = (NLSExchangeAttrReply)baseReply; if(NLSReply.primaryRC_ != 0) { Trace.log(Trace.ERROR, ("Exchange attribute failed, primary return code =" + NLSReply.primaryRC_ + "secondary return code =" + NLSReply.getSecondaryRC_()) ); disconnect(); throw new IOException(); } } else { // unknown data stream if(Trace.traceOn_) { Trace.log(Trace.ERROR, "Unknown instance returned from Exchange Attribute Reply"); } throw new InternalErrorException(InternalErrorException.DATA_STREAM_UNKNOWN); } LicenseGetRequest getLicReq = new LicenseGetRequest(sys_); getLicReq.setProductID(productID_); getLicReq.setFeature(featureID_); getLicReq.setRelease(releaseLevel_); try { baseReply = server_.sendAndReceive(getLicReq); } catch(IOException e) { Trace.log(Trace.ERROR, "IOException occured - Request license", e); disconnect(); throw e; } if(baseReply instanceof LicenseGetReply) { LicenseGetReply getReply = (LicenseGetReply)baseReply; if(getReply.getPrimaryRC() == 0) { usageLimit_ = getReply.getUsageLimit(); usageCount_ = getReply.getUsageCount(); // bump usage count by one, because server gets usage count before retrieving // license, so the count is off by 1. usageCount_++; usageType_ = getReply.getUsageType(); complianceType_ = getReply.getComplianceType(); licenseTerm_ = getReply.getLicenseTerm(); releaseLevel_ = getReply.getReleaseLevel(); condition_ = getReply.getSecondaryRC(); switch (condition_) // verify that it's a recognized value { case CONDITION_OK: case CONDITION_EXCEEDED_OK: case CONDITION_EXCEEDED_GRACE_PERIOD: case CONDITION_GRACE_PERIOD_EXPIRED: break; default: // This should never happen; but if it does, trace it. Trace.log(Trace.ERROR, "LicenseGetReply.getSecondaryRC():", condition_); } released_ = false; // Fire the license released event. fireProductLicenseEvent(ProductLicenseEvent.PRODUCT_LICENSE_REQUESTED); } else { if(Trace.traceOn_) { Trace.log(Trace.DIAGNOSTIC, ("Request license failed, primary return code =" + getReply.getPrimaryRC() + "secondary return code =" + getReply.getSecondaryRC()) ); } throw new LicenseException(getReply.getPrimaryRC(), getReply.getSecondaryRC()); } } else { if(Trace.traceOn_) { Trace.log(Trace.ERROR, "Unknown instance returned from Get License Reply"); } throw new InternalErrorException(InternalErrorException.DATA_STREAM_UNKNOWN); } return condition_; } // synchronized(sys_) } // public void request() /** Removes this listener from being notified when a bound property changes. @param listener The PropertyChangeListener. **/ public void removePropertyChangeListener(PropertyChangeListener listener) { if (listener == null) { Trace.log(Trace.ERROR, "Parameter 'listener' is null."); throw new NullPointerException("listener"); } changes_.removePropertyChangeListener(listener); } /** Removes a listener from the ProductLicense listeners list. @param listener The product license listener. **/ public void removeProductLicenseListener(ProductLicenseListener listener) { if (listener == null) { Trace.log(Trace.ERROR, "Parameter 'listener' is null."); throw new NullPointerException("listener"); } productLicenseListeners_.removeElement(listener); } /** * Sets the feature identifier for this license. * @param featureID the product feature. For example, "5050". **/ public void setFeature(String featureID) { if(featureID == null) // @A2C { throw new NullPointerException("featureID"); // @A2C } // Ensure that the featureID is not altered after the connection is // established. if (sysImpl_ != null) { throw new ExtendedIllegalStateException("featureID", ExtendedIllegalStateException.PROPERTY_NOT_CHANGED); // @A2A } String oldFeatureID = featureID_; // @A2A featureID_ = featureID; // Fire the property change event having null as the name to // indicate that the path, parent, etc. have changed. changes_.firePropertyChange("featureID", oldFeatureID, featureID_); // @A2A } /** * Sets the product identifier for this license. * @param productID the product identifier. For example, "5769JC1". **/ public void setProductID(String productID) { if(productID == null) { throw new NullPointerException("productID"); } // Ensure that the productID is not altered after the connection is // established. if (sysImpl_ != null) { throw new ExtendedIllegalStateException("productID", ExtendedIllegalStateException.PROPERTY_NOT_CHANGED); // @A2A } String oldProductID = productID_; // @A2A productID_ = productID; // Fire the property change event having null as the name to // indicate that the path, parent, etc. have changed. changes_.firePropertyChange("productID", oldProductID, productID_); // @A2A } /** * Sets the product release for this license. * @param releaseLevel the product release. For example, "V4R5M0". **/ public void setReleaseLevel(String releaseLevel) { if(releaseLevel == null) { throw new NullPointerException("releaseLevel"); } // Ensure that the releaseLevel is not altered after the connection is // established. if (sysImpl_ != null) { throw new ExtendedIllegalStateException("releaseLevel", ExtendedIllegalStateException.PROPERTY_NOT_CHANGED); // @A2A } String oldReleaseLevel = releaseLevel_; // @A2A releaseLevel_ = releaseLevel; // Fire the property change event having null as the name to // indicate that the path, parent, etc. have changed. changes_.firePropertyChange("releaseLevel", oldReleaseLevel, releaseLevel_); // @A2A } /** * Sets the system object for this license. * @param system the system from which the license will be requested. **/ public void setSystem(AS400 system) // @A2C { if(system == null) // @A2C { throw new NullPointerException("system"); // @A2C } // Ensure that the system is not altered after the connection is // established. if (sysImpl_ != null) { throw new ExtendedIllegalStateException("system", ExtendedIllegalStateException.PROPERTY_NOT_CHANGED); // @A2A } AS400 oldSystem = sys_; // @A2A sys_ = system; // @A2C // Fire the property change event having null as the name to // indicate that the path, parent, etc. have changed. changes_.firePropertyChange("path", oldSystem, sys_); } // Called when this object is de-serialized private void readObject(ObjectInputStream in) throws ClassNotFoundException, IOException { in.defaultReadObject(); initializeTransient(); } } // public class ProductLicense




© 2015 - 2024 Weber Informatics LLC | Privacy Policy