br.com.objectos.office.core.OfficeRuntime.java Source code

Java tutorial

Introduction

Here is the source code for br.com.objectos.office.core.OfficeRuntime.java

Source

/*
 * Copyright 2014 Objectos, Fbrica de Software LTDA.
 *
 * 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 br.com.objectos.office.core;

import java.util.concurrent.ExecutionException;

import br.com.objectos.way.core.auto.AutoPojo;
import br.com.objectos.way.core.lang.ProcessException;
import br.com.objectos.way.core.lang.ProcessManager;
import br.com.objectos.way.core.lang.ProcessManager.RestartCallback;
import br.com.objectos.way.core.testing.Testable;

import com.google.common.base.MoreObjects;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.sun.star.connection.NoConnectException;
import com.sun.star.lang.DisposedException;

/**
 * @author marcio.endo@objectos.com.br (Marcio Endo)
 */
@AutoPojo
abstract class OfficeRuntime implements Testable<OfficeRuntime> {

    private static final int MAX_TRIES = 100;
    private static final long SLEEP_TIME = 15;

    private final LoadingCache<Boolean, Office> officeCache;

    abstract ProcessManager processManager();

    abstract UnoUrl unoUrl();

    OfficeRuntime() {
        officeCache = CacheBuilder.newBuilder().maximumSize(1).build(new OfficeCacheLoader());
    }

    public static OfficeRuntimeBuilder builder() {
        return new OfficeRuntimeBuilderPojo();
    }

    @Override
    public String toString() {
        return MoreObjects.toStringHelper(this).addValue(unoUrl()).toString();
    }

    public Office get() throws OfficeException {
        try {
            ensureRunning();
            return officeCache.get(Boolean.TRUE);
        } catch (ExecutionException e) {
            throw new OfficeException("Could not connect to external Office process.", e);
        }
    }

    public void stop() {
        processManager().destroy();
        int tryNo = 0;
        boolean success = false;

        while (!success && tryNo++ < MAX_TRIES) {
            try {
                unoUrl().createInjector();
                Thread.sleep(SLEEP_TIME);
            } catch (NoConnectException e) {
                success = true;
            } catch (DisposedException e) {
                success = true;
            } catch (InterruptedException e) {
            } catch (OfficeException e) {
            }
        }
    }

    private void ensureRunning() throws OfficeException {
        try {
            processManager().ensureRunning(new RestartCallback() {
                @Override
                public void onRestart(ProcessManager processManager) {
                    officeCache.invalidateAll();
                }
            });
        } catch (ProcessException e) {
            throw new OfficeException("Could not start external Office process.", e);
        }
    }

    private class OfficeCacheLoader extends CacheLoader<Boolean, Office> {
        @Override
        public Office load(Boolean key) throws Exception {
            UnoInjector injector = null;
            int tryNo = 0;
            boolean success = false;

            while (!success && tryNo++ < MAX_TRIES) {
                try {
                    injector = unoUrl().createInjector();
                    success = true;
                } catch (NoConnectException e) {
                    Thread.sleep(SLEEP_TIME);
                }
            }

            UnoDesktop desktop = UnoDesktopProvider.INSTANCE.get(injector);
            return Office.builder().desktop(desktop).build();
        }
    }

}