src.com.ibm.as400.access.ProductLicense Maven / Gradle / Ivy
Show all versions of jt400-jdk8 Show documentation
///////////////////////////////////////////////////////////////////////////////
//
// 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