/* * Jar Monitor - Watches a jar folder and notify jar classes changes * Copyright (C) 2007 Federico Fissore * * 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 it.fridrik.filemonitor; import java.io.IOException; import java.util.Enumeration; import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.jar.JarEntry; import java.util.jar.JarFile; import java.util.logging.Level; import java.util.logging.Logger; /** * JarMonitor uses FileMonitor to receive notifications about jar changes, then * looks into the changed jar for the changed classes and then tells its * listeners about the changed classes in the changed jars * * @author Federico Fissore (federico@fissore.org) * @since 1.0 */ public class JarMonitor implements FileModifiedListener, FileAddedListener, FileDeletedListener, Runnable { private final static Logger log = Logger.getLogger(JarMonitor.class.getName()); private final FileMonitor fileMonitor; private final String absoluteFolderPath; private final Map<String, Map<String, Long>> jarsMap; private final List<JarModifiedListener> jarModifiedListeners; public JarMonitor(String absoluteFolderPath) { this.absoluteFolderPath = absoluteFolderPath; this.jarsMap = new HashMap<String, Map<String, Long>>(); this.jarModifiedListeners = new LinkedList<JarModifiedListener>(); fileMonitor = new FileMonitor(absoluteFolderPath, "jar"); fileMonitor.addModifiedListener(this); fileMonitor.addAddedListener(this); fileMonitor.addDeletedListener(this); } public void run() { fileMonitor.run(); } public void fileModified(FileEvent event) { JarFile file = getJarFile(event); if (file != null) { Map<String, Long> jarEntries = jarsMap.get(event.getSource()); for (Enumeration<JarEntry> entries = file.entries(); entries .hasMoreElements();) { JarEntry entry = entries.nextElement(); if (!jarEntries.containsKey(entry.getName())) { jarEntries.put(entry.getName(), Long.valueOf(entry.getTime())); } if (entry.getTime() != jarEntries.get(entry.getName()).longValue()) { jarEntries.put(entry.getName(), Long.valueOf(entry.getTime())); notifyJarModifiedListeners(new JarEvent(file, entry.getName())); } } } } public void fileAdded(FileEvent event) { JarFile file = getJarFile(event); if (file != null) { Map<String, Long> jarEntries = new HashMap<String, Long>(); jarsMap.put(event.getSource(), jarEntries); for (Enumeration<JarEntry> entries = file.entries(); entries .hasMoreElements();) { JarEntry entry = entries.nextElement(); if (entry.getName().endsWith("jar")) { jarEntries.put(entry.getName(), Long.valueOf(entry.getTime())); notifyJarModifiedListeners(new JarEvent(file, entry.getName())); } } } } public void fileDeleted(FileEvent event) { jarsMap.remove(event.getSource()); } public void addJarModifiedListener(JarModifiedListener listener) { jarModifiedListeners.add(listener); } private void notifyJarModifiedListeners(JarEvent event) { for (JarModifiedListener listener : jarModifiedListeners) { listener.jarModified(event); } } private JarFile getJarFile(FileEvent event) { try { return new JarFile(absoluteFolderPath + event.getSource()); } catch (IOException e) { log.log(Level.SEVERE, "error", e); return null; } } }