X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=blobdiff_plain;f=opendaylight%2Fconfig%2Fconfig-api%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fconfig%2Fspi%2FAbstractModule.java;h=29a8ce3ebe498ceadbbae08f2b7b662190773bba;hp=772bacce891ce0abb7e83c74bbdc2f11ce26b585;hb=2d60632f7cf63712e8357a3cf3fc40d83366e5e6;hpb=a4f9b6ea19d8f1ef1d6e9e4c2e5f39520a44a2a2 diff --git a/opendaylight/config/config-api/src/main/java/org/opendaylight/controller/config/spi/AbstractModule.java b/opendaylight/config/config-api/src/main/java/org/opendaylight/controller/config/spi/AbstractModule.java index 772bacce89..29a8ce3ebe 100644 --- a/opendaylight/config/config-api/src/main/java/org/opendaylight/controller/config/spi/AbstractModule.java +++ b/opendaylight/config/config-api/src/main/java/org/opendaylight/controller/config/spi/AbstractModule.java @@ -1,3 +1,11 @@ +/* + * Copyright (c) 2014, 2017 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + package org.opendaylight.controller.config.spi; import org.opendaylight.controller.config.api.DependencyResolver; @@ -6,38 +14,54 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** - * Base implementation of Module. This implementation contains base logic for Module reconfiguration with associated fields. - * @param Type of module implementation. Enables easier implementation for the {@link #isSame} method + * Base implementation of Module. This implementation contains base logic for + * Module reconfiguration with associated fields. + * + * @param + * Type of module implementation. Enables easier implementation for + * the isSame() method */ -public abstract class AbstractModule> implements org.opendaylight.controller.config.spi.Module { +public abstract class AbstractModule> + implements org.opendaylight.controller.config.spi.Module { private static final Logger LOG = LoggerFactory.getLogger(AbstractModule.class); - private final M oldModule; - private final AutoCloseable oldInstance; + protected final DependencyResolver dependencyResolver; protected final ModuleIdentifier identifier; + + private AutoCloseable oldInstance; + private M oldModule; private AutoCloseable instance; - protected final DependencyResolver dependencyResolver; + private boolean canReuseInstance = true; /** * Called when module is configured. * - * @param identifier id of current instance. - * @param dependencyResolver resolver used in dependency injection and validation. + * @param identifier + * id of current instance. + * @param dependencyResolver + * resolver used in dependency injection and validation. */ - public AbstractModule(ModuleIdentifier identifier, DependencyResolver dependencyResolver) { + public AbstractModule(final ModuleIdentifier identifier, final DependencyResolver dependencyResolver) { this(identifier, dependencyResolver, null, null); } /** * Called when module is reconfigured. * - * @param identifier id of current instance. - * @param dependencyResolver resolver used in dependency injection and validation. - * @param oldModule old instance of module that is being reconfigred(replaced) by current instance. The old instance can be examined for reuse. - * @param oldInstance old instance wrapped by the old module. This is the resource that is actually being reused if possible or closed otherwise. + * @param identifier + * id of current instance. + * @param dependencyResolver + * resolver used in dependency injection and validation. + * @param oldModule + * old instance of module that is being reconfigred(replaced) by + * current instance. The old instance can be examined for reuse. + * @param oldInstance + * old instance wrapped by the old module. This is the resource that + * is actually being reused if possible or closed otherwise. */ - public AbstractModule(ModuleIdentifier identifier, DependencyResolver dependencyResolver, M oldModule, AutoCloseable oldInstance) { + public AbstractModule(final ModuleIdentifier identifier, final DependencyResolver dependencyResolver, + final M oldModule, final AutoCloseable oldInstance) { this.identifier = identifier; this.dependencyResolver = dependencyResolver; this.oldModule = oldModule; @@ -49,67 +73,91 @@ public abstract class AbstractModule> implements org return identifier; } + public final void setCanReuseInstance(final boolean canReuseInstance) { + this.canReuseInstance = canReuseInstance; + } + /** - * * General algorithm for spawning/closing and reusing wrapped instances. * - * @return current instance of wrapped resource either by reusing the old one (if present) or constructing a brand new. + * @return current instance of wrapped resource either by reusing the old one + * (if present) or constructing a brand new. */ @Override + @SuppressWarnings("IllegalCatch") public final AutoCloseable getInstance() { - if(instance==null) { - if(oldInstance!=null && canReuseInstance(oldModule)) { + if (instance == null) { + if (oldInstance != null && canReuseInstance && canReuseInstance(oldModule)) { resolveDependencies(); instance = reuseInstance(oldInstance); } else { - if(oldInstance!=null) { + if (oldInstance != null) { try { oldInstance.close(); - } catch(Exception e) { - LOG.error("An error occurred while closing old instance {} for module {}", oldInstance, getIdentifier(), e); + } catch (final Exception exception) { + LOG.error("An error occurred while closing old instance {} for module {}", oldInstance, + getIdentifier(), exception); } } resolveDependencies(); instance = createInstance(); if (instance == null) { - throw new IllegalStateException("Error in createInstance - null is not allowed as return value. Module: " + getIdentifier()); + throw new IllegalStateException( + "Error in createInstance - null is not allowed as return value. Module: " + + getIdentifier()); } } + + // Prevent serial memory leak: clear these references as we will not use them + // again. + oldInstance = null; + oldModule = null; } + return instance; } /** - * @return Brand new instance of wrapped class in case no previous instance is present or reconfiguration is impossible. + * Create instance. + * + * @return Brand new instance of wrapped class in case no previous instance is + * present or reconfiguration is impossible. */ protected abstract AutoCloseable createInstance(); @Override - public final boolean canReuse(Module oldModule) { + public final boolean canReuse(final Module prevModule) { // Just cast into a specific instance - // TODO unify this method with canReuseInstance (required Module interface to be generic which requires quite a lot of changes) - return getClass().isInstance(oldModule) ? canReuseInstance((M) oldModule) : false; + // TODO unify this method with canReuseInstance (required Module interface to be + // generic which requires quite a lot of changes) + return canReuseInstance && getClass().isInstance(prevModule) ? canReuseInstance((M) prevModule) : false; } /** + * Users are welcome to override this method to provide custom logic for + * advanced reusability detection. * - * Users are welcome to override this method to provide custom logic for advanced reusability detection. - * - * @param oldModule old instance of a Module - * @return true if the old instance is reusable false if a new one should be spawned + * @param prevModule + * old instance of a Module + * @return true if the old instance is reusable false if a new one should be + * spawned */ - protected abstract boolean canReuseInstance(final M oldModule); + protected abstract boolean canReuseInstance(M prevModule); /** - * By default the oldInstance is returned since this method is by default called only if the oldModule had the same configuration and dependencies configured. - * Users are welcome to override this method to provide custom logic for advanced reusability. + * By default the oldInstance is returned since this method is by default called + * only if the oldModule had the same configuration and dependencies configured. + * Users are welcome to override this method to provide custom logic for + * advanced reusability. * - * @param oldInstance old instance of a class wrapped by the module + * @param prevInstance + * old instance of a class wrapped by the module * @return reused instance */ - protected AutoCloseable reuseInstance(AutoCloseable oldInstance) { - // implement if instance reuse should be supported. Override canReuseInstance to change the criteria. - return oldInstance; + protected AutoCloseable reuseInstance(final AutoCloseable prevInstance) { + // implement if instance reuse should be supported. Override canReuseInstance to + // change the criteria. + return prevInstance; } /**