⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 launchclassloader.java

📁 主要是对串口驱动的的一些控制源码!!! 在下载javacomm20-win32.zip后就可以使用。
💻 JAVA
字号:
package de.fhm.jkf.launch.cl;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.Iterator;
import java.util.List;
import java.util.zip.InflaterInputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

import de.fhm.jkf.launch.clsv.ArchiveInfo;
import de.fhm.jkf.launch.clsv.LaunchLogger;
import de.fhm.jkf.launch.clsv.LaunchParameter;

/**
 * <br><br><center><table border="1" width="80%"><hr>
 * <strong><a href="http://jkf.sourceforge.net">The JKF Project</a></strong>
 * <p>
 * Copyright (C) 2002 by Theodor Willax
 * <p>
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 * <p>
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 * <p>
 * You should have received a copy of the <a href="http://www.gnu.org/copyleft/lesser.html">
 * GNU Lesser General Public License</a> along with this library; if not, write to
 * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 * MA  02111-1307  USA
 * <hr></table></center>
 *
 * The <code>ClassLoader</code> every jkf_launcher based application starts with.
 * The <code>LaunchClassLoader</code> is responsible for providing the necessary
 * archives respective classes to run the application. His strategy is do get at startup
 * a list of known classes and archives from the server and uses this information for
 * retrieving the class bytes from the right archive. It stores archives in the local
 * <code>Cache</code>, so future startups are faster.
 * <br>
 * Archives are only downloaded, if needed (lazy downloading).
 * 
 * @author Theodor Willax
 */
public class LaunchClassLoader extends ClassLoader implements Runnable {

	/** The <code>Cache</code> where local archives are stored. */
	private Cache cache = null;

	/** <code>URL</code> where to get archives from. */
	private URL servletURL = null;

	/**
	 * This <code>List</code> is read from the server
	 * at construction time. It contains all archives
	 * and containing classes of the archives.
	 */
	private List archiveInfo = null;

	/**
	 * Creates an new class loader, initializes the <code>Cache</code> and
	 * the configuration for the jkf framework.
	 * 
	 * @param appName The name of the application this class loader is for.
	 * @param url The url the archives for this application can be loaded from.
	 * 
	 * @exception IOException if no cache could be created.
	 * @exception MalformedURLException if the url to the server is incorrect.
	 * @exception ClassNotFoundException if the class the archiveInfo is sent
	 * with is not found (should never happen).
	 */
	public LaunchClassLoader(String appName, String url, ClassLoader parent)
		throws MalformedURLException, IOException, ClassNotFoundException {
		super(parent);
		servletURL = new URL(url);
		cache = new Cache(appName);
		// @todo progress bar with completion status
		URL u =
			new URL(
				servletURL.toExternalForm()
					+ "?"
					+ LaunchParameter.GET_ARCH_LIST
					+ "=1");
		ObjectInputStream in =
			new ObjectInputStream(new InflaterInputStream(u.openStream()));
		archiveInfo = (List) in.readObject();
		in.close();
		cache.init(archiveInfo);
		loadConfiguration();
	}

	/**
	 * Starts the application. Reads the parameter <tt>mainClass</tt>
	 * from the <tt>application.properties</tt> file. This class is
	 * invoked in this <code>Thread</code>.
	 */
	public void run() {
		TextResource tr = new TextResource();
		String mainClassName = tr.getString("mainClass");
		// Call main
		try {
			LaunchLogger.info("Try to load " + mainClassName);
			Class main = loadClass(mainClassName);

			// Close launch indicator
			//			if( launchIndicator != null )
			//				launchIndicator.close();

			Method mainMain =
				main.getMethod("main", new Class[] { String[].class });
			// @todo: main arguments
			mainMain.invoke(null, new Object[] { new String[] {
				}
			});
		} catch (Exception e) {
			new ErrorFrame(e).setVisible(true);
			e.printStackTrace();
		}
	}

	/**
	 * Searches the archive which contains the wanted class.
	 * 
	 * @param className the class to search for
	 * @return String the archive name which contains the class,
	 * <code>null</code> otherwise.
	 */
	private String getArchiveForClass(String className) {
		LaunchLogger.debug("searching archive for: " + className);
		Iterator it = archiveInfo.iterator();
		while (it.hasNext()) {
			ArchiveInfo ai = (ArchiveInfo) it.next();
			Iterator jt = ai.getClassList().iterator();
			LaunchLogger.debug("archive: " + ai.getName());
			while (jt.hasNext()) {
				LaunchLogger.debug(jt.next().toString());
			}
		}
		it = archiveInfo.iterator();
		while (it.hasNext()) {
			ArchiveInfo ai = (ArchiveInfo) it.next();
			if (ai.getClassList().contains(className)) {
				LaunchLogger.debug("found archive: " + ai.getName());
				return ai.getName();
			}
		}
		LaunchLogger.debug("did not found archive for: " + className);
		return null;
	}

	/**
	 * This method is called if resources like images or text files
	 * are searched. Because we only use jar archives on the client,
	 * this method only returns jar urls pointing to the resources!
	 * 
	 * @param name The wanted resource.
	 * @return URL JAR-URL pointing to the wanted resource.
	 */
	public URL findResource(String name) {
		String arch = getArchiveForClass(name);
		File file;
		try {
			file = cache.getFile(arch);
			// a jar:-URL *could* change even between minor releases, but
			// didn't between JVM's 1.1.6 and 1.3beta. Tested on JVM's from
			// IBM, Blackdown, Microsoft, Sun @ Windows and Sun @ Solaris
			System.err.println(file.getAbsolutePath());
			ZipFile zf = new ZipFile(file.getAbsolutePath());
			ZipEntry ze = zf.getEntry(name);

			if (ze != null) {
				try {
					return new URL(
						"jar:file:" + file.getAbsolutePath() + "!/" + name);
				} catch (java.net.MalformedURLException badurl) {
					badurl.printStackTrace();
					return null;
				}
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException ioe) {
			ioe.printStackTrace();
		}
		return null;
	}

	/**
	 * Searches the <code>Class</code> with the specified name.
	 * 
	 * @exception ClassNotFoundException if <code>Class</code> is
	 * not available in the classpath, <code>Cache</code> or on
	 * the server.
	 */
	public Class findClass(String name) throws ClassNotFoundException {
		byte[] b = loadClassData(name);
		return defineClass(name, b, 0, b.length);
	}

	/**
	 * Tries to load the <code>byte</code>S for the wanted
	 * class.
	 * 
	 * @param name The class to load (complete specified with package path).
	 * @return the <code>byte</code>S which represent the class.
	 * @exception ClassNotFoundException if the wanted class cant
	 * be found.
	 */
	private byte[] loadClassData(String name) throws ClassNotFoundException {
		// try to load the class data from the cache
		ByteArray b = cache.getBytesForClass(name);
		// or load archive from server
		if (b == null) {
			String arch = getArchiveForClass(name);
			if (arch == null) {
				throw new ClassNotFoundException(
					"archive for class " + name + " not found");
			}
			try {
				URL url =
					new URL(
						servletURL.toExternalForm()
							+ "?"
							+ LaunchParameter.GET_ARCHIVE
							+ "="
							+ arch);
				URLConnection con = url.openConnection();
				con.setDoInput(true);
				con.setUseCaches(false);
				InputStream in = con.getInputStream();
				long size =
					Long.parseLong(con.getHeaderField("archive-length"));
				ArchiveLoader loader = new ArchiveLoader(in, size, arch);
				loader.loadArchive();

				cache.put(new Archive(arch, loader.getData()));
			} catch (IOException e) {
				LaunchLogger.error(
					getClass().getName()
						+ ".loadClassData(): "
						+ e.getMessage());
				e.printStackTrace();
				throw new ClassNotFoundException(
					"class " + name + " could not be loaded");
			}
			// retry to get the bytes
			b = cache.getBytesForClass(name);
		}
		return b.getBytes();
	}

	/**
	 * Loads the configuration file from the server. Sets the 
	 * system property <code>jkf.client.config.path</code>, which
	 * is necessery to start the jkf client framework. It points
	 * to the directory, where the configuration files where
	 * extraced to.
	 */
	private void loadConfiguration()
		throws MalformedURLException, IOException {
		URL u =
			new URL(
				servletURL.toExternalForm()
					+ "?"
					+ LaunchParameter.GET_CONFIG_FILES
					+ "=1");
		InputStream in = u.openStream();
		ByteArrayOutputStream out = new ByteArrayOutputStream();
		int len;
		byte[] buf = new byte[4096];
		while ((len = in.read(buf)) > 0) {
			out.write(buf, 0, len);
		}
		in.close();
		cache.putConfiguration(
			new Archive("jkf-client-configuration-archive", out.toByteArray()));
		out.close();
		System.setProperty("jkf.client.config.path", cache.getCacheDir());
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -