/*
* 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 org.apache.aries.subsystem.core.internal;
import org.apache.aries.util.io.IOUtils;
import org.osgi.resource.Resource;
import org.osgi.service.subsystem.Subsystem;
import org.osgi.service.subsystem.Subsystem.State;
import org.osgi.service.subsystem.SubsystemException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class SubsystemResourceUninstaller extends ResourceUninstaller {
private static final Logger logger = LoggerFactory.getLogger(BasicSubsystem.class);
private static void removeChild(BasicSubsystem parent, BasicSubsystem child) {
Activator.getInstance().getSubsystems().removeChild(parent, child);
}
public SubsystemResourceUninstaller(Resource resource, BasicSubsystem subsystem) {
super(resource, subsystem);
}
public void uninstall() {
removeReferences();
try {
if (isResourceUninstallable())
uninstallSubsystem();
}
finally {
removeConstituents();
removeChildren();
removeSubsystem();
}
}
private void removeChildren() {
if (!isExplicit()) {
removeChild((BasicSubsystem)subsystem, (BasicSubsystem)resource);
return;
}
for (Subsystem subsystem : ((BasicSubsystem)resource).getParents())
removeChild((BasicSubsystem)subsystem, (BasicSubsystem)resource);
}
private void removeConstituents() {
if (!isExplicit()) {
removeConstituent();
return;
}
for (Subsystem subsystem : ((BasicSubsystem)resource).getParents())
removeConstituent((BasicSubsystem)subsystem, (BasicSubsystem)resource);
}
private void removeReferences() {
if (!isExplicit()) {
removeReference();
}
else {
for (Subsystem subsystem : ((BasicSubsystem)resource).getParents())
removeReference((BasicSubsystem)subsystem, (BasicSubsystem)resource);
Subsystems subsystems = Activator.getInstance().getSubsystems();
// for explicit uninstall remove all references to subsystem.
for (BasicSubsystem s : subsystems.getSubsystemsReferencing(resource)) {
removeReference(s, resource);
}
}
}
private void removeSubsystem() {
Activator.getInstance().getSubsystems().removeSubsystem((BasicSubsystem)resource);
}
private void uninstallSubsystem() {
BasicSubsystem subsystem = (BasicSubsystem) resource;
try {
if (subsystem.getState().equals(Subsystem.State.RESOLVED))
subsystem.setState(State.INSTALLED);
subsystem.setState(State.UNINSTALLING);
Throwable firstError = null;
for (Resource resource : Activator.getInstance().getSubsystems()
.getResourcesReferencedBy(subsystem)) {
// Don't uninstall the region context bundle here.
if (Utils.isRegionContextBundle(resource))
continue;
try {
ResourceUninstaller.newInstance(resource, subsystem)
.uninstall();
} catch (Throwable t) {
logger.error("An error occurred while uninstalling resource "
+ resource + " of subsystem " + subsystem, t);
if (firstError == null)
firstError = t;
}
}
subsystem.setState(State.UNINSTALLED);
Activator activator = Activator.getInstance();
activator.getSubsystemServiceRegistrar().unregister(subsystem);
if (subsystem.isScoped()) {
RegionContextBundleHelper.uninstallRegionContextBundle(subsystem);
activator.getRegionDigraph().removeRegion(subsystem.getRegion());
}
if (firstError != null)
throw new SubsystemException(firstError);
}
finally {
// Let's be sure to always clean up the directory.
IOUtils.deleteRecursive(subsystem.getDirectory());
}
}
}