org.rapidoid.io.watch.WatchingRefresherThread Maven / Gradle / Ivy
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