All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.rapidoid.io.watch.WatchingRefresherThread Maven / Gradle / Ivy

There is a newer version: 5.5.5
Show newest version
package org.rapidoid.io.watch;

import org.rapidoid.activity.AbstractLoopThread;
import org.rapidoid.annotation.Authors;
import org.rapidoid.annotation.Since;
import org.rapidoid.log.Log;
import org.rapidoid.reload.Reload;
import org.rapidoid.u.U;

import java.io.File;
import java.util.Collection;
import java.util.List;
import java.util.Queue;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;

/*
 * #%L
 * rapidoid-watch
 * %%
 * Copyright (C) 2014 - 2016 Nikolche Mihajlovski and contributors
 * %%
 * 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.
 * #L%
 */

@Authors("Nikolche Mihajlovski")
@Since("4.1.0")
public class WatchingRefresherThread extends AbstractLoopThread {

	private static final AtomicInteger idGen = new AtomicInteger();

	private final ClassRefresher refresher;

	private final Set createdFilenames = U.set();
	private final Set modifiedFilenames = U.set();
	private final Set deletedFilenames = U.set();

	private final Collection folders;

	private final Queue created;
	private final Queue modified;
	private final Queue deleted;

	public WatchingRefresherThread(Collection folders, Queue created, Queue modified, Queue deleted, ClassRefresher refresher) {
		this.folders = folders;
		this.created = created;
		this.modified = modified;
		this.deleted = deleted;
		this.refresher = refresher;

		setName("reloader" + idGen.incrementAndGet());
	}

	@Override
	protected void loop() {
		boolean found = false;
		String filename;

		while ((filename = created.poll()) != null) {
			createdFilenames.add(filename);
			found = true;
		}
		while ((filename = modified.poll()) != null) {
			modifiedFilenames.add(filename);
			found = true;
		}
		while ((filename = deleted.poll()) != null) {
			deletedFilenames.add(filename);
			found = true;
		}

		// when the changes are complete
		if (!found && (!createdFilenames.isEmpty() || !modifiedFilenames.isEmpty() || !deletedFilenames.isEmpty())) {
			reload();
			createdFilenames.clear();
			modifiedFilenames.clear();
			deletedFilenames.clear();
		}

		U.sleep(100);
	}

	protected void reload() {
		Set filenames = U.set();
		filenames.addAll(createdFilenames);
		filenames.addAll(modifiedFilenames);

		Log.debug("Detected changes in classes", "created", createdFilenames, "modified", modifiedFilenames, "deleted", deletedFilenames);

		try {
			List classnames = filenamesToClassnames(filenames);
			List> classes = Reload.reloadClasses(folders, classnames);
			refresher.refresh(classes, filenamesToClassnames(deletedFilenames));
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private String filenameToClassname(String filename) {
		for (String dir : folders) {
			if (filename.endsWith(".class") && filename.startsWith(dir + File.separatorChar)) {
				return filename.substring(dir.length() + 1, filename.length() - 6).replace(File.separatorChar, '.');
			}

			if (filename.endsWith(".class") && filename.startsWith(dir + "/")) {
				return filename.substring(dir.length() + 1, filename.length() - 6).replace('/', '.');
			}
		}

		return null;
	}

	private List filenamesToClassnames(Set filenames) {
		List list = U.list();

		for (String filename : filenames) {
			String classname = filenameToClassname(filename);

			if (classname != null) {
				list.add(classname);
			}
		}

		return list;
	}

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy