Java tutorial
/* * FileLicenseProvider.java from LicenseManager modified Tuesday, September 4, 2012 14:17:42 CDT (-0500). * * Copyright 2010-2013 the original author or authors. * * 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 net.nicholaswilliams.java.licensing; import org.apache.commons.codec.binary.Base64; import org.apache.commons.io.FileUtils; import java.io.File; import java.io.IOException; import java.net.URISyntaxException; import java.net.URL; /** * A default implementation of the {@link LicenseProvider} that assumes the binary data from the signed and serialized * license is stored in a file. Various properties of this provider allow configuration of file prefixes (such as * a directory), file suffixes (such as an extension), whether or not the file can be found on the classpath, and * whether or not the contents of the file are Base64 encoded.<br /> * <br /> * This implementation also assumes that license contexts (lookup keys) are always either strings or have a meaningful * {@link Object#toString()} implementation that can be used within the file name. * * @author Nick Williams * @version 1.0.0 * @since 1.0.0 */ public class FileLicenseProvider extends DeserializingLicenseProvider { protected ClassLoader classLoader; private String filePrefix = ""; private String fileSuffix = ""; private boolean fileOnClasspath = false; private boolean base64Encoded = false; /** * Constructs a file-based license provider with the same class loader as the loader of this class and * {@link #setFileOnClasspath(boolean) fileOnClasspath} set to {@code false}. The class loader is only used if * {@code fileOnClasspath} is subsequently changed to {@code true}. */ public FileLicenseProvider() { this.classLoader = this.getClass().getClassLoader(); this.fileOnClasspath = false; } /** * Constructs a file-based license provider with the provided class loader and * {@link #setFileOnClasspath(boolean) fileOnClasspath} set to {@code true}. The class loader will be used to * locate the file unless {@code fileOnClasspath} is subsequently changed to {@code false}. * * @param classLoader The class loader to use for finding the file */ public FileLicenseProvider(ClassLoader classLoader) { if (classLoader == null) throw new IllegalArgumentException("Argument classLoader cannot be null."); this.classLoader = classLoader; this.fileOnClasspath = true; } /** * Gets the stored, still-encrypted, still-serialized license content and signature from the persistence store. * Returns null (not an empty array) if no license is found. * * @param context The context for which to get the license * @return the signed license data. */ @Override protected byte[] getLicenseData(Object context) { if (context == null) throw new IllegalArgumentException("Argument context cannot be null."); File file = this.getLicenseFile(context); if (file == null || !file.exists() || !file.canRead()) return null; try { byte[] data = FileUtils.readFileToByteArray(file); if (this.isBase64Encoded()) { data = Base64.decodeBase64(data); } return data; } catch (IOException e) { return null; } } /** * Gets the license file handle. Returns null if if no license is found, but if a license is found, this may * return a file handle to a non-existent file. So, the file should be checked for existence and readability. * * @param context The context for which to get the license * @return the license file handle. */ protected File getLicenseFile(Object context) { String fileName = this.getFilePrefix() + context.toString() + this.getFileSuffix(); if (this.isFileOnClasspath()) { if (fileName.startsWith("/")) fileName = fileName.substring(1); URL url = this.classLoader.getResource(fileName); if (url == null) fileName = null; else { try { return new File(url.toURI()); } catch (URISyntaxException e) { return new File(url.getPath()); } } } return fileName == null ? null : new File(fileName); } /** * Gets the prefix that will be prepended to the file name before looking for it. For example, if a license * context was "customer01" and the file name was "C:\product\licenses\file-customer01.lic", then the prefix * would be "C:\product\licenses\file-" and the suffix would be ".lic". * * @return the file prefix. */ public String getFilePrefix() { return this.filePrefix; } /** * Sets the prefix that will be prepended to the file name before looking for it. For example, if a license * context was "customer01" and the file name was "C:\product\licenses\file-customer01.lic", then the prefix * would be "C:\product\licenses\file-" and the suffix would be ".lic". * * @param filePrefix The file prefix */ public void setFilePrefix(String filePrefix) { if (filePrefix == null) throw new IllegalArgumentException("Argument filePrefix cannot be null."); this.filePrefix = filePrefix; } /** * Gets the file suffix that will be appended to the file name before looking for it. For example, if a license * context was "customer01" and the file name was "C:\product\licenses\file-customer01.lic", then the prefix * would be "C:\product\licenses\file-" and the suffix would be ".lic". * * @return the file suffix. */ public String getFileSuffix() { return this.fileSuffix; } /** * Sets the file suffix that will be appended to the file name before looking for it. For example, if a license * context was "customer01" and the file name was "C:\product\licenses\file-customer01.lic", then the prefix * would be "C:\product\licenses\file-" and the suffix would be ".lic". * * @param fileSuffix The file suffix */ public void setFileSuffix(String fileSuffix) { if (fileSuffix == null) throw new IllegalArgumentException("Argument fileSuffix cannot be null."); this.fileSuffix = fileSuffix; } /** * Indicates whether the file should be found on the file system or on the classpath via a class loader. If * {@code false} it will be looked for on the file system; if {@code true} it will be looked for on the classpath. * If {@code true}, the file prefix should be the package-path and prefix and the suffix the suffix.<br /> * <br /> * For example, if a license context was "customer02" and the file name was "file-customer02.lic" and was located * in the package net.nicholaswilliams.java.licensing.licenses, then the prefix would be * "net/nicholaswilliams/java/licensing/licenses/file-" and the suffix should be ".lic". * * @return whether the file is on the classpath. */ public boolean isFileOnClasspath() { return this.fileOnClasspath; } /** * Sets whether the file should be found on the file system or on the classpath via a class loader. If * {@code false} it will be looked for on the file system; if {@code true} it will be looked for on the classpath. * If {@code true}, the file prefix should be the package-path and prefix and the suffix the suffix.<br /> * <br /> * For example, if a license context was "customer02" and the file name was "file-customer02.lic" and was located * in the package net.nicholaswilliams.java.licensing.licenses, then the prefix would be * "net/nicholaswilliams/java/licensing/licenses/file-" and the suffix should be ".lic". * * @param fileOnClasspath Whether the file is on the classpath */ public void setFileOnClasspath(boolean fileOnClasspath) { this.fileOnClasspath = fileOnClasspath; } /** * Indicates whether the file is Base64 encoded. If the file is Base64 encoded, its data will be decoded before * being returned by {@link #getLicenseData(Object)}. * * @return whether the file is Base64 encoded. */ public boolean isBase64Encoded() { return this.base64Encoded; } /** * Sets whether the file is Base64 encoded. If the file is Base64 encoded, its data will be decoded before * being returned by {@link #getLicenseData(Object)}. * * @param base64Encoded Whether the file is Base64 encoded. */ public void setBase64Encoded(boolean base64Encoded) { this.base64Encoded = base64Encoded; } }