001 /**
002 * Copyright (C) 2009-2013 Barchart, Inc. <http://www.barchart.com/>
003 *
004 * All rights reserved. Licensed under the OSI BSD License.
005 *
006 * http://www.opensource.org/licenses/bsd-license.php
007 */
008 package com.barchart.udt.lib;
009
010 import java.io.BufferedInputStream;
011 import java.io.BufferedOutputStream;
012 import java.io.File;
013 import java.io.FileOutputStream;
014 import java.io.InputStream;
015 import java.io.OutputStream;
016 import java.net.URL;
017 import java.net.URLConnection;
018
019 import org.slf4j.Logger;
020 import org.slf4j.LoggerFactory;
021
022 /**
023 * class path resource extractor and system loader
024 */
025 public class ResourceManagerUDT {
026
027 protected final static Logger log = LoggerFactory
028 .getLogger(ResourceManagerUDT.class);
029
030 protected static boolean isSameResource(final URLConnection conONE,
031 final URLConnection conTWO) throws Exception {
032
033 final long timeONE = conONE.getLastModified();
034 final long sizeONE = conONE.getContentLength();
035
036 final long timeTWO = conTWO.getLastModified();
037 final long sizeTWO = conTWO.getContentLength();
038
039 return sizeONE == sizeTWO && timeONE == timeTWO;
040
041 }
042
043 protected static URLConnection fileConnection(final File file)
044 throws Exception {
045
046 final URL url = file.toURI().toURL();
047
048 final URLConnection connection = url.openConnection();
049
050 return connection;
051
052 }
053
054 protected final static int EOF = -1;
055
056 /** will use time stamp of jar file */
057 protected static long timeStamp(final URLConnection connIN) {
058 return connIN.getLastModified();
059 }
060
061 /**
062 * extract resource from class path into local file system
063 */
064 protected static void extractResource(final String sourcePath,
065 final String targetPath) throws Exception {
066
067 final URL sourceUrl = ResourceManagerUDT.class.getResource(sourcePath);
068
069 if (sourceUrl == null) {
070 log.warn("classpath resource not found: {}", sourcePath);
071 throw new IllegalArgumentException("resource not found");
072 }
073
074 log.debug("sourceURL={} ", sourceUrl);
075
076 final URLConnection sourceConn = sourceUrl.openConnection();
077
078 if (sourceConn == null) {
079 log.warn("classpath resource connection not available: {}",
080 sourcePath);
081 throw new IllegalArgumentException("resource not found");
082 }
083
084 final File targetFile = new File(targetPath).getAbsoluteFile();
085 log.debug("targetFile={} ", targetFile);
086
087 final File targetFolder = targetFile.getParentFile().getAbsoluteFile();
088 log.debug("targetFolder={} ", targetFolder);
089
090 ensureTargetFolder(targetFolder);
091
092 final URLConnection targetConn = fileConnection(targetFile);
093
094 if (isSameResource(sourceConn, targetConn)) {
095 log.debug("already extracted; sourcePath={} targetPath={}",
096 sourcePath, targetPath);
097 return;
098 } else {
099 log.debug("make new extraction destination for targetPath={}",
100 targetPath);
101 targetFile.delete();
102 targetFile.createNewFile();
103 }
104
105 final long sourceTime = timeStamp(sourceConn);
106
107 final InputStream sourceStream = new BufferedInputStream(//
108 sourceUrl.openStream());
109
110 final OutputStream targetStream = new BufferedOutputStream(//
111 new FileOutputStream(targetFile));
112
113 final byte[] array = new byte[64 * 1024];
114
115 int readCount = 0;
116
117 while ((readCount = sourceStream.read(array)) != EOF) {
118 targetStream.write(array, 0, readCount);
119 }
120
121 targetStream.flush();
122
123 sourceStream.close();
124 targetStream.close();
125
126 /** synchronize target time stamp with source to avoid repeated copy */
127 targetFile.setLastModified(sourceTime);
128
129 log.debug("extracted OK; sourcePath={} targetPath={}", sourcePath,
130 targetPath);
131
132 }
133
134 protected static void ensureTargetFolder(final File folder)
135 throws Exception {
136 if (folder.exists()) {
137 if (folder.isDirectory()) {
138 log.debug("found folder={}", folder);
139 } else {
140 log.error("not a directory; folder={}", folder);
141 throw new IllegalArgumentException(
142 "extract destination exists, but as a file and not a folder");
143 }
144 } else {
145 final boolean isSuccess = folder.mkdirs();
146 if (isSuccess) {
147 log.debug("mkdirs : folder={}", folder);
148 } else {
149 log.error("mkdirs failure; folder={}", folder);
150 throw new IllegalStateException(
151 "failed to make extract destination folder");
152 }
153 }
154 }
155
156 protected static void ensureTargetFolder(final String targetFolder)
157 throws Exception {
158
159 final File folder = new File(targetFolder).getAbsoluteFile();
160
161 ensureTargetFolder(folder);
162
163 }
164
165 /**
166 * load library using absolute file path
167 */
168 protected static void systemLoad(final String targetPath) throws Exception {
169
170 final File loadFile = new File(targetPath);
171
172 final String loadPath = loadFile.getAbsolutePath();
173
174 System.load(loadPath);
175
176 }
177
178 /**
179 * load library using absolute file path
180 */
181 protected static void systemLoad(final String sourcePath,
182 final String targetPath) throws Exception {
183
184 extractResource(sourcePath, targetPath);
185
186 systemLoad(targetPath);
187
188 }
189
190 }