blob: 24d93babd0f873ce87fb73f2bda2e2a8dcf28c8d [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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 org.netbeans.core.startup;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.logging.Level;
import org.netbeans.Util;
import org.openide.modules.ModuleInfo;
import org.openide.modules.Modules;
import org.openide.util.Lookup;
import org.openide.util.LookupEvent;
import org.openide.util.LookupListener;
import org.openide.util.RequestProcessor;
import org.openide.util.Task;
import org.openide.util.lookup.Lookups;
/**
*
* @author Jaroslav Tulach <jtulach@netbeans.org>
*/
final class NbStartStop implements LookupListener {
private static final RequestProcessor RP = new RequestProcessor("On Start/Stop", 8); // NOI18N
private final Map<String, RequestProcessor.Task> onStart = new HashMap<String, RequestProcessor.Task>();
private final Lookup lkpStart;
private final Lookup lkpStop;
private Lookup.Result<Runnable> resStart;
NbStartStop(Lookup lkp, Lookup lkp2) {
lkpStart = lkp;
lkpStop = lkp2;
}
void initialize() {
for (Lookup.Item<Runnable> item : onStart().allItems()) {
synchronized (onStart) {
RequestProcessor.Task already = onStart.get(item.getId());
if (already == null) {
Runnable r = item.getInstance();
if (r != null) {
onStart.put(item.getId(), RP.post(r));
}
}
}
}
}
private synchronized Lookup.Result<Runnable> onStart() {
if (resStart == null) {
Lookup lkp = lkpStart != null ? lkpStart : Lookups.forPath("Modules/Start"); // NOI18N
resStart = lkp.lookupResult(Runnable.class);
resStart.addLookupListener(this);
}
return resStart;
}
private Lookup onStop() {
return lkpStop != null ? lkpStop : Lookups.forPath("Modules/Stop"); // NOI18N
}
void waitOnStart() {
RequestProcessor.Task[] all;
synchronized (onStart) {
Collection<RequestProcessor.Task> values = onStart.values();
all = values.toArray(new RequestProcessor.Task[values.size()]);
}
for (RequestProcessor.Task t : all) {
t.waitFinished();
}
}
boolean closing(List<? extends ModuleInfo> modules) {
for (Callable<?> c : onStop().lookupAll(Callable.class)) { // NOI18N
if (!modules.contains(Modules.getDefault().ownerOf(c.getClass()))) {
continue;
}
try {
if (Boolean.FALSE.equals(c.call())) {
Util.err.log(Level.FINE, "{0} refused to close", c.getClass()); // NOI18N
return false;
}
} catch (Exception ex) {
Util.err.log(Level.FINE, c.getClass() + " thrown an exception", ex); // NOI18N
return false;
}
}
return true;
}
List<Task> startClose(List<? extends ModuleInfo> modules) {
List<Task> waitFor = new ArrayList<Task>();
for (Runnable r : onStop().lookupAll(Runnable.class)) { // NOI18N
if (!modules.contains(Modules.getDefault().ownerOf(r.getClass()))) {
continue;
}
waitFor.add(RP.post(r));
}
return waitFor;
}
@Override
public void resultChanged(LookupEvent ev) {
initialize();
}
}