org.kalypso.core.catalog.CatalogManager.java Source code

Java tutorial

Introduction

Here is the source code for org.kalypso.core.catalog.CatalogManager.java

Source

/*----------------    FILE HEADER KALYPSO ------------------------------------------
 *
 *  This file is part of kalypso.
 *  Copyright (C) 2004 by:
 *
 *  Technical University Hamburg-Harburg (TUHH)
 *  Institute of River and coastal engineering
 *  Denickestrae 22
 *  21073 Hamburg, Germany
 *  http://www.tuhh.de/wb
 *
 *  and
 *
 *  Bjoernsen Consulting Engineers (BCE)
 *  Maria Trost 3
 *  56070 Koblenz, Germany
 *  http://www.bjoernsen.de
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation; either
 *  version 2.1 of the License, or (at your option) any later version.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 *  Contact:
 *
 *  E-Mail:
 *  belger@bjoernsen.de
 *  schlienger@bjoernsen.de
 *  v.doemming@tuhh.de
 *
 *  ---------------------------------------------------------------------------*/
package org.kalypso.core.catalog;

import java.io.File;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.Unmarshaller;
import javax.xml.namespace.QName;

import oasis.names.tc.entity.xmlns.xml.catalog.Catalog;
import oasis.names.tc.entity.xmlns.xml.catalog.ObjectFactory;

import org.apache.commons.io.IOUtils;
import org.eclipse.wst.common.uriresolver.internal.provisional.URIResolver;
import org.eclipse.wst.common.uriresolver.internal.provisional.URIResolverPlugin;
import org.kalypso.commons.bind.JaxbUtilities;
import org.kalypso.contribs.eclipse.core.runtime.StatusUtilities;
import org.kalypso.core.KalypsoCorePlugin;
import org.kalypso.core.catalog.urn.IURNGenerator;
import org.kalypso.core.i18n.Messages;

/**
 * TODO: This catalog manager does two things, managing the catalogs and also knowning about what things are managed
 * (URNGenerator, ...)
 * <p>
 * In my opinion, this is already too much. We should rather split those two concepts for clarity. Gernot.
 * </p>
 * <p>
 * the default-catalog is dynamic, but changes will not be saved
 * </p>
 *
 * @author doemming
 */
@SuppressWarnings("restriction")
public class CatalogManager {
    public static final JAXBContext JAX_CONTEXT_CATALOG = JaxbUtilities.createQuiet(ObjectFactory.class);

    public static final ObjectFactory OBJECT_FACTORY_CATALOG = new ObjectFactory();

    public final Map<Class<?>, IURNGenerator> m_urnGenerators = new HashMap<>();

    private final Map<URI, ICatalog> m_openCatalogs = new HashMap<>();

    private final File m_baseDir;

    private ICatalog m_baseCatalog;

    /**
     * Normally you should not instantiate this manager yourself but get it via
     * {@link org.kalypso.core.KalypsoCorePlugin#getCatalogManager()}
     */
    public CatalogManager(final File baseDir) {
        m_baseDir = baseDir;
    }

    public synchronized void register(final IURNGenerator urnGenerator) {
        final Class<?> key = urnGenerator.getSupportingClass();
        if (m_urnGenerators.containsKey(key))
            throw new UnsupportedOperationException(
                    Messages.getString("org.kalypso.core.catalog.CatalogManager.0") + key.toString()); //$NON-NLS-1$
        m_urnGenerators.put(key, urnGenerator);
    }

    public synchronized ICatalog getBaseCatalog() {
        if (m_baseCatalog != null)
            return m_baseCatalog;

        final String baseURN = new String("urn:"); //$NON-NLS-1$
        final String path = CatalogUtilities.getPathForCatalog(baseURN);

        final File catalogFile = new File(m_baseDir, path);

        try {
            ensureExisting(baseURN);

            m_baseCatalog = getCatalog(new URI(URLEncoder.encode(catalogFile.toURI().toURL().toString(), "UTF-8"))); //$NON-NLS-1$

            return m_baseCatalog;
        } catch (final Exception e) {
            KalypsoCorePlugin.getDefault().getLog().log(StatusUtilities.statusFromThrowable(e));
            return null;
        }
    }

    synchronized ICatalog getCatalog(final URI catalogURI) {
        if (!m_openCatalogs.containsKey(catalogURI)) {
            final ICatalog newOpenCatalog = readCatalog(catalogURI);
            if (newOpenCatalog != null)
                m_openCatalogs.put(catalogURI, newOpenCatalog);
        }
        return m_openCatalogs.get(catalogURI);
    }

    private ICatalog readCatalog(final URI catalogURI) {
        try (InputStream is = catalogURI.toURL().openStream()) {
            final Unmarshaller unmarshaller = JAX_CONTEXT_CATALOG.createUnmarshaller();

            // REMARK: do not use 'unmarshaller.unmarshal( catalogURL )'
            // It does leave the stream open
            final JAXBElement<Catalog> object = (JAXBElement<Catalog>) unmarshaller.unmarshal(is);
            is.close();

            final Catalog catalog = object.getValue();

            final URL catalogURL = catalogURI.toURL();
            return createCatalog(catalogURL, catalog);
        } catch (final Exception e) {
            e.printStackTrace();
            System.err.println(String.format(Messages.getString("CatalogManager.0"), catalogURI)); //$NON-NLS-1$
            return null;
        }
    }

    /**
     * saves all open catalogs
     */
    public synchronized void saveAll() {
        final List<URI> catalogsToClose = new ArrayList<>();
        for (final ICatalog catalog : m_openCatalogs.values()) {
            try {
                if (catalog instanceof DynamicCatalog) {
                    final DynamicCatalog dynCatalog = (DynamicCatalog) catalog;
                    dynCatalog.save(m_baseDir);
                    final URL location = dynCatalog.getLocation();
                    catalogsToClose.add(new URI(URLEncoder.encode(location.toString(), "UTF-8"))); //$NON-NLS-1$
                }
            } catch (final Exception e) {
                e.printStackTrace();
            }
        }
        // close catalogs that have been saved
        for (final URI catalogURI : catalogsToClose)
            m_openCatalogs.remove(catalogURI);
    }

    synchronized void ensureExisting(final String baseURN) throws MalformedURLException, URISyntaxException {
        if (!baseURN.endsWith(":")) //$NON-NLS-1$
            throw new UnsupportedOperationException(
                    Messages.getString("org.kalypso.core.catalog.CatalogManager.6") + baseURN); //$NON-NLS-1$

        final String href = CatalogUtilities.getPathForCatalog(baseURN);
        final URL catalogURL = new URL(m_baseDir.toURI().toURL(), href);

        URI catalogURI = null;
        try {
            catalogURI = new URI(URLEncoder.encode(catalogURL.toString(), "UTF-8")); //$NON-NLS-1$
        } catch (final UnsupportedEncodingException e) {
            KalypsoCorePlugin.getDefault().getLog().log(StatusUtilities.statusFromThrowable(e));
            return;
        }

        // TODO: problem: not all urls are uris (example: file with spaces), so we might get an URISyntaxException here
        // final URI catalogURI = catalogURL.toURI();
        if (m_openCatalogs.containsKey(catalogURI))
            return;
        boolean exists = true;
        InputStream stream = null;
        try {
            stream = catalogURL.openStream();
        } catch (final Exception e) {
            exists = false;
        } finally {
            IOUtils.closeQuietly(stream);
        }

        if (exists)
            return;
        // create
        final ObjectFactory catalogFac = new ObjectFactory();
        final Catalog catalog = catalogFac.createCatalog();
        final Map<QName, String> attributes = catalog.getOtherAttributes();

        attributes.put(CatalogUtilities.BASE, baseURN);
        catalog.setId(baseURN);

        final ICatalog newOpenCatalog = createCatalog(catalogURL, catalog);
        m_openCatalogs.put(catalogURI, newOpenCatalog);
    }

    private ICatalog createCatalog(final URL catalogURL, final Catalog catalog) {
        return new DynamicCatalog(this, catalogURL, catalog);
    }

    public synchronized IURNGenerator getURNGeneratorFor(final Class<?> supportingClass) {
        return m_urnGenerators.get(supportingClass);
    }

    public synchronized String resolve(final String systemID, final String publicID) {
        /* First try, use wst to resolve uri */
        final URIResolver uriResolver = URIResolverPlugin.createResolver();
        final String resolvedUri = uriResolver.resolve(null, publicID, systemID);
        if (resolvedUri != null && !resolvedUri.equals(systemID))
            return resolvedUri;

        /* FIXME: remove our old implementation */
        final ICatalog baseCatalog = getBaseCatalog();
        return baseCatalog.resolve(systemID, publicID);
    }

    public void addNextCatalog(final URL catalogURL) {
        final ICatalog baseCatalog = getBaseCatalog();
        baseCatalog.addNextCatalog(catalogURL);
    }
}