<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml" lang=""><head><meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/><link rel="stylesheet" href="../jacoco-resources/report.css" type="text/css"/><link rel="shortcut icon" href="../jacoco-resources/report.gif" type="image/gif"/><title>BaseUnicastRemoteService.java</title><link rel="stylesheet" href="../jacoco-resources/prettify.css" type="text/css"/><script type="text/javascript" src="../jacoco-resources/prettify.js"></script></head><body onload="window['PR_TAB_WIDTH']=4;prettyPrint()"><div class="breadcrumb" id="breadcrumb"><span class="info"><a href="../jacoco-sessions.html" class="el_session">Sessions</a></span><a href="../index.html" class="el_report">Apache Turbine</a> &gt; <a href="index.source.html" class="el_package">org.apache.turbine.services</a> &gt; <span class="el_source">BaseUnicastRemoteService.java</span></div><h1>BaseUnicastRemoteService.java</h1><pre class="source lang-java linenums">package org.apache.turbine.services;


/*
 * 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
 * &quot;License&quot;); 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
 * &quot;AS IS&quot; 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.
 */


import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.util.Properties;

import org.apache.commons.configuration2.Configuration;
import org.apache.commons.configuration2.ConfigurationConverter;

/**
 * A base implementation of an {@link java.rmi.server.UnicastRemoteObject}
 * as a Turbine {@link org.apache.turbine.services.Service}.
 *
 * @author &lt;a href=&quot;mailto:dlr@collab.net&quot;&gt;Daniel Rall&lt;/a&gt;
 */
public class BaseUnicastRemoteService extends UnicastRemoteObject
        implements Service
{
    /**
     * Serial version.
     */
    private static final long serialVersionUID = -7775459623190960297L;

    protected Configuration configuration;
    private boolean isInitialized;
    private InitableBroker initableBroker;
    private String name;
    private ServiceBroker serviceBroker;

    /**
     * Default constructor
     * @throws RemoteException if the remote object cannot be created
     */
    public BaseUnicastRemoteService()
            throws RemoteException
<span class="nc" id="L57">    {</span>
<span class="nc" id="L58">        isInitialized = false;</span>
<span class="nc" id="L59">        initableBroker = null;</span>
<span class="nc" id="L60">        name = null;</span>
<span class="nc" id="L61">        serviceBroker = null;</span>
<span class="nc" id="L62">    }</span>

    /**
     * Returns the configuration of this service.
     *
     * @return The configuration of this service.
     */
    @Override
    public Configuration getConfiguration()
    {
<span class="nc bnc" id="L72" title="All 2 branches missed.">        if (name == null)</span>
        {
<span class="nc" id="L74">            return null;</span>
        }
        else
        {
<span class="nc bnc" id="L78" title="All 2 branches missed.">            if (configuration == null)</span>
            {
<span class="nc" id="L80">                configuration = getServiceBroker().getConfiguration(name);</span>
            }
<span class="nc" id="L82">            return configuration;</span>
        }
    }

    @Override
    public void setInitableBroker(InitableBroker broker)
    {
<span class="nc" id="L89">        this.initableBroker = broker;</span>
<span class="nc" id="L90">    }</span>

    /**
     * Get the {@link InitableBroker} instance
     * @return the broker instance
     */
    public InitableBroker getInitableBroker()
    {
<span class="nc" id="L98">        return initableBroker;</span>
    }

    @Override
    public void init(Object data)
            throws InitializationException
    {
<span class="nc" id="L105">        init();</span>
<span class="nc" id="L106">    }</span>

    @Override
    public void init() throws InitializationException
    {
<span class="nc" id="L111">        setInit(true);</span>
<span class="nc" id="L112">    }</span>

    protected void setInit(boolean value)
    {
<span class="nc" id="L116">        isInitialized = value;</span>
<span class="nc" id="L117">    }</span>

    @Override
    public boolean getInit()
    {
<span class="nc" id="L122">        return isInitialized;</span>
    }

    /**
     * Shuts down this service.
     */
    @Override
    public void shutdown()
    {
<span class="nc" id="L131">        setInit(false);</span>
<span class="nc" id="L132">    }</span>

    @Override
    public Properties getProperties()
    {
<span class="nc" id="L137">        return ConfigurationConverter.getProperties(getConfiguration());</span>
    }

    @Override
    public void setName(String name)
    {
<span class="nc" id="L143">        this.name = name;</span>
<span class="nc" id="L144">    }</span>

    @Override
    public String getName()
    {
<span class="nc" id="L149">        return name;</span>
    }

    /**
     * Get the {@link ServiceBroker} instance
     * @return the broker instance
     */
    public ServiceBroker getServiceBroker()
    {
<span class="nc" id="L158">        return serviceBroker;</span>
    }

    @Override
    public void setServiceBroker(ServiceBroker broker)
    {
<span class="nc" id="L164">        this.serviceBroker = broker;</span>
<span class="nc" id="L165">    }</span>
}
</pre><div class="footer"><span class="right">Created with <a href="http://www.jacoco.org/jacoco">JaCoCo</a> 0.8.12.202403310830</span></div></body></html>