📄 productversionholder.java
字号:
/* Derby - Class org.apache.derby.iapi.services.info.ProductVersionHolder Copyright 1998, 2004 The Apache Software Foundation or its licensors, as applicable. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.*/package org.apache.derby.iapi.services.info;import java.io.InputStream;import java.io.IOException;import java.util.Properties;/** Class to hold a cloudscape Product version. This class includes the following product version features. <OL> <LI>Save the product version information this holds as a String. We call the string a 'product version string'. <LI>Construct a ProductVersionHolder from a valid 'product version string'. <LI>Determine if two product versions are feature compatible. This means products of these versions may interoperate with ***NO*** compatibility problems. <LI>Determine if two product versions are the same. This is a stronger test than the test for feature compatibility. </OL> Cloudscape 5.1 and older versions used the majorVersion, minorVersion, maintVersion versions directly. That is a three part version number, majorVersion.minorVersion.maintVersion, e.g. 5.1.21. For Cloudscape 5.2 onwards a four part name is required. majorVersion.minorVersion.fixPack.bugVersion e.g. 5.2.1.2 This follows the IBM standard and allows us to state that a fix pack will be 5.2.3 without worrying about how many maintence fixes there are between fix packs. We implement this using the existing format of ProductVersionHolder to reduce disruption to the code, however we make the maintVersion encode the {fixPack.bugVersion}. Since the maintVersion is represented by a int (2G values) we have plenty of room for encoding. If we assign a given majorVersion.minorVersion.fixPack a 10 year life, then we about the maximum number of individual releases it can have is 10 years * 365 days/year = 3650. Thus with the pre 5.2 scheme we would not expect a 5.1.x to have an x > 3650 (approximately). Usually the rate of point releases has been much less than one per day, 5.1.31 is released about 225 days after GA which makes around a point release every 7 days. But in the encoding we need to be conservative. With fix packs the maximum is about 2 per year and fix packs are only made to the current release, thus with a yearly minor release cycle we would imagine only 2 fixpacks per major.minor. However like other IBM products or release cycle may be extended thus we can expect up to a handful of fix packs. Thus we might imagine releases like 5.2.0.12 5.2.0.234 5.2.1.34 5.2.4.2445 but highly unlikey to have 5.2.2.59321 5.2.23.1 The encoding number must continue to increase so that the encodedMaintB > encodedMaintA if (fixPackB > fixPackA) || ((fixPackB == fixPackA) && (bugB > bugA)) Selected encoding encodedMaint = (fixPack * 1,000,000) + (bugVersion); Handles many many fixpacks and upto one million bug fixes per fix pack and remains somewhat human readable. Special fix packs fixpack == 0 = alpha (version off main codeline) fixpack == 1 = first release of major.minor (may be marked with beta) fixpack == 2 = first fix pack (displayed as 1) The drdaMaintVersion is sent in the Network Server PRDID. It never displays but may be used by the client for version specific behaviour. It should be reset to 0 with each minor release. The product version string has the form: <PRE> productVendorName - ProductName - majorVersion.minorVersion.maintVersion [beta] - (buildNumber) </PRE> */public final class ProductVersionHolder implements java.security.PrivilegedAction{ // //Used as an invalid value for numbers. This works because all //the numbers in a product version must be non-negative. private static final int BAD_NUMBER = -1; private static final String ALPHA = "alpha"; private static final String BETA = "beta"; private final static int MAINT_ENCODING = 1000000; private String productVendorName; private String productName; private String productTechnologyName; private int majorVersion = BAD_NUMBER; private int minorVersion = BAD_NUMBER; private int maintVersion = BAD_NUMBER; private int drdaMaintVersion = BAD_NUMBER; private String buildNumber = "????"; private Boolean isBeta; private ProductVersionHolder() { } /** Create a ProductVersionHolder <P>Please see the documentation for the varient of getProductVesionHolder that takes the same parameters as this for a description of the parameters. */ private ProductVersionHolder(String productVendorName, String productName, String productTechnologyName, int majorVersion, int minorVersion, int maintVersion, int drdaMaintVersion, String buildNumber, Boolean isBeta) { if (productVendorName != null) this.productVendorName = productVendorName.trim(); if (productName != null) this.productName = productName.trim(); if (productTechnologyName != null) this.productTechnologyName = productTechnologyName.trim(); this.majorVersion = majorVersion; this.minorVersion = minorVersion; this.maintVersion = maintVersion; this.drdaMaintVersion = drdaMaintVersion; this.buildNumber = buildNumber; this.isBeta = isBeta; } /** Create a valid ProductVersionHolder. If any of the parameters provided is invalid, this returns null. @param productName The name of the product. productName.length() must be greater than 0. The syntax for a product name is 'productGenus[:productSpecies]'. @param majorVersion The most significant portion of a 3 part product version. Must be non-negative. @param minorVersion The second portion of a 3 part product version. Must be non-negative. @param maintVersion The least significant portion of a 3 part product version. Must be non-negative. @param drdaMaintVersion The protocol modification number for minor release. @param buildNumber The buildNumber for a product. @param isBeta true iff the product is beta. @return A valid ProductVersionHolder of null if any of the parameters provided are not valid. */ public static ProductVersionHolder getProductVersionHolder( String productVendorName, String productName, String productTechnologyName, int majorVersion, int minorVersion, int maintVersion, int drdaMaintVersion, String buildNumber, Boolean isBeta) { ProductVersionHolder pvh = new ProductVersionHolder(productVendorName, productName, productTechnologyName, majorVersion, minorVersion, maintVersion, drdaMaintVersion, buildNumber, isBeta); return pvh; } /** Get a ProductVersionHolder for a product of a given genus, that is available in the caller's environment. Even though this uses a priv bock, it may stil fail when the jar the version is being fetched from, is different to the one that loaded this class, AND the jars are in different security contexts. @param productGenus The genus for the product. @return The ProductVersionHolder or null if a product with the given genus is not available in the caller's environment. */ public static ProductVersionHolder getProductVersionHolderFromMyEnv(String productGenus) { ProductVersionHolder tempPVH = new ProductVersionHolder(); tempPVH.productGenus = productGenus; Properties p = (Properties) java.security.AccessController.doPrivileged(tempPVH); if (p == null) return null; return getProductVersionHolder(p); } /** Load the version info from the already opened properties files. We need to do this because if the jar files (e.g. db2jtools and db2j) are in different security contexts (entries in the policy files) then we cannot load the version information for one of them correctly. This is because the this class will either have been loaded from only one of the jars and hence can only access the resource in its own jar. By making code specific to the jar open the resource we are guaranteed it will work. */ public static ProductVersionHolder getProductVersionHolderFromMyEnv(InputStream propertiesStream) { if (propertiesStream == null) return null; Properties p = new Properties(); try { p.load(propertiesStream); } catch (IOException ioe) { System.out.println("IOE " + ioe.getMessage()); // //This case is a bit ugly. If we get an IOException, we return //null. Though this correctly reflects that the product is not //available for use, it may be confusing to users that we swallow //the IO error here. return null; } finally { try { propertiesStream.close(); } catch (IOException ioe2) { } } return getProductVersionHolder(p); } /** Get a ProductVersionHolder based on the information in
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -