/* Copyright (c) 2011 GeoSolutions - http://www.geo-solutions.it/. All rights reserved. * This code is licensed under the GPL 2.0 license, available at the root * application directory. */ package it.geosolutions.geoserver.jms.server; import it.geosolutions.geoserver.jms.JMSApplicationListener; import it.geosolutions.geoserver.jms.JMSPublisher; import it.geosolutions.geoserver.jms.impl.handlers.DocumentFile; import java.io.File; import java.util.Properties; import javax.jms.JMSException; import org.geoserver.catalog.Catalog; import org.geoserver.catalog.CatalogException; import org.geoserver.catalog.CatalogInfo; import org.geoserver.catalog.StyleInfo; import org.geoserver.catalog.WorkspaceInfo; import org.geoserver.catalog.event.CatalogAddEvent; import org.geoserver.catalog.event.CatalogListener; import org.geoserver.catalog.event.CatalogModifyEvent; import org.geoserver.catalog.event.CatalogPostModifyEvent; import org.geoserver.catalog.event.CatalogRemoveEvent; import org.geoserver.platform.GeoServerExtensions; import org.geoserver.platform.GeoServerResourceLoader; import org.geotools.util.logging.Logging; /** * JMS MASTER (Producer) Listener used to send GeoServer Catalog events over the JMS channel. * * @see {@link JMSApplicationListener} * * @author Carlo Cancellieri - carlo.cancellieri@geo-solutions.it * */ public class JMSCatalogListener extends JMSAbstractGeoServerProducer implements CatalogListener { private final static java.util.logging.Logger LOGGER = Logging.getLogger(JMSCatalogListener.class); private final JMSPublisher jmsPublisher; /** * Constructor * * @param topicTemplate the getJmsTemplate() object used to send message to the topic queue * */ public JMSCatalogListener(final Catalog catalog, final JMSPublisher jmsPublisher) { super(); this.jmsPublisher = jmsPublisher; catalog.addListener(this); } @Override public void handleAddEvent(CatalogAddEvent event) throws CatalogException { if (LOGGER.isLoggable(java.util.logging.Level.FINE)) { LOGGER.fine("Incoming event of type " + event.getClass().getSimpleName() + " from Catalog"); } // skip incoming events if producer is not Enabled if (!isEnabled()) { if (LOGGER.isLoggable(java.util.logging.Level.FINE)) { LOGGER.fine("skipping incoming event: context is not initted"); } return; } // update properties final Properties options = getProperties(); try { // check if we may publish also the file GeoServerResourceLoader loader = GeoServerExtensions.bean(GeoServerResourceLoader.class); final CatalogInfo info = event.getSource(); if (info instanceof StyleInfo) { final StyleInfo sInfo=((StyleInfo) info); WorkspaceInfo wInfo =sInfo.getWorkspace(); File styleFile=null; // make sure we work fine with workspace specific styles if(wInfo!=null){ styleFile=new File( loader.getBaseDirectory()+ File.separator+ "workspaces"+ File.separator+ wInfo.getName()+ File.separator+ "styles"+ File.separator+ sInfo.getFilename()); }else{ styleFile=loader.find("styles/" + sInfo.getFilename()); } // checks if(!styleFile.exists()||!styleFile.canRead()||!styleFile.isFile()){ throw new IllegalStateException("Unable to find style for event: "+sInfo.toString()); } // transmit the file jmsPublisher.publish(getTopic(), getJmsTemplate(), options, new DocumentFile(styleFile)); } // propagate the event jmsPublisher.publish(getTopic(), getJmsTemplate(), options, event); } catch (Exception e) { if (LOGGER.isLoggable(java.util.logging.Level.SEVERE)) { LOGGER.severe(e.getLocalizedMessage()); } final CatalogException ex = new CatalogException(e); throw ex; } } @Override public void handleRemoveEvent(CatalogRemoveEvent event) throws CatalogException { if (LOGGER.isLoggable(java.util.logging.Level.FINE)) { LOGGER.fine("Incoming message event of type " + event.getClass().getSimpleName() + " from Catalog"); } // skip incoming events until context is loaded if (!isEnabled()) { if (LOGGER.isLoggable(java.util.logging.Level.FINE)) { LOGGER.fine("skipping incoming event: context is not initted"); } return; } // update properties Properties options = getProperties(); try { jmsPublisher.publish(getTopic(), getJmsTemplate(), options, event); } catch (JMSException e) { if (LOGGER.isLoggable(java.util.logging.Level.SEVERE)) { LOGGER.severe(e.getLocalizedMessage()); } throw new CatalogException(e); } } @Override public void handleModifyEvent(CatalogModifyEvent event) throws CatalogException { if (LOGGER.isLoggable(java.util.logging.Level.FINE)) { LOGGER.fine("Incoming message event of type " + event.getClass().getSimpleName() + " from Catalog"); } // skip incoming events until context is loaded if (!isEnabled()) { if (LOGGER.isLoggable(java.util.logging.Level.FINE)) { LOGGER.fine("skipping incoming event: context is not initted"); } return; } // update properties Properties options = getProperties(); try { // check if we may publish also the file GeoServerResourceLoader loader = GeoServerExtensions.bean(GeoServerResourceLoader.class); final CatalogInfo info = event.getSource(); if (info instanceof StyleInfo) { // build local datadir file style path final String canonicalStyleFileName = File.separator + "styles" + File.separator + ((StyleInfo) info).getFilename(); File styleFile = new File(loader.getBaseDirectory().getCanonicalPath(), canonicalStyleFileName); if ( !styleFile.exists() ) { final String workspace = ((StyleInfo) info).getWorkspace().getName(); final String styleFileName = File.separator + "workspaces" + File.separator + workspace + File.separator + "styles" + File.separator + ((StyleInfo) info).getFilename(); styleFile = new File(loader.getBaseDirectory().getCanonicalPath(), styleFileName); } // publish the style xml document jmsPublisher.publish(getTopic(), getJmsTemplate(), options, new DocumentFile( styleFile)); } // propagate the event jmsPublisher.publish(getTopic(), getJmsTemplate(), options, event); } catch (Exception e) { if (LOGGER.isLoggable(java.util.logging.Level.SEVERE)) { LOGGER.severe(e.getLocalizedMessage()); } final CatalogException ex = new CatalogException(e); throw ex; } } @Override public void handlePostModifyEvent(CatalogPostModifyEvent event) throws CatalogException { if (LOGGER.isLoggable(java.util.logging.Level.FINE)) { LOGGER.fine("Incoming message event of type " + event.getClass().getSimpleName() + " from Catalog"); } // EAT EVENT // this event should be generated locally (to slaves) by the catalog // itself } @Override public void reloaded() { // skip incoming events until context is loaded if (!isEnabled()) { if (LOGGER.isLoggable(java.util.logging.Level.FINE)) { LOGGER.fine("skipping incoming event: context is not initted"); } return; } // EAT EVENT // TODO disable and re-enable the producer!!!!! // this is potentially a problem since this listener should be the first // called by the GeoServer. } }