/*
* Copyright (C) 1999-2008 Jive Software. All rights reserved.
*
* 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 org.jivesoftware.openfire.plugin.spark.manager;
import java.io.File;
import org.dom4j.Element;
import org.jivesoftware.openfire.XMPPServer;
import org.jivesoftware.util.JiveGlobals;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xmpp.component.Component;
import org.xmpp.component.ComponentException;
import org.xmpp.component.ComponentManager;
import org.xmpp.component.ComponentManagerFactory;
import org.xmpp.packet.IQ;
import org.xmpp.packet.JID;
import org.xmpp.packet.Packet;
import org.xmpp.packet.PacketError;
/**
* Provides support for server administrators to control the global updating of the Jive Spark IM client.
* (<a href="http://www.igniterealtime.org/projects/spark/index.jsp">Spark</a>).<p>
* <p/>
* The basic functionality is to query the server for the latest client
* version and return that information. The version comparison is left to
* the client itself, so as to keep the SparkVersionManager simple.
* <p/>
*
* @author Derek DeMoro
*/
public class SparkVersionManager implements Component {
private static final Logger Log = LoggerFactory.getLogger(SparkVersionManager.class);
private ComponentManager componentManager;
public static String SERVICE_NAME = "updater";
/**
* Empty constructor for initializing.
*/
public SparkVersionManager() {
// Initialize ComponentManager
componentManager = ComponentManagerFactory.getComponentManager();
}
/**
* Returns the name of this plugin.
*
* @return the name of this plugin.
*/
public String getName() {
return "Spark Version Manager";
}
/**
* Returns a brief description of this plugin.
*
* @return a brief description of this plugin.
*/
public String getDescription() {
return "Allow admins to control the updating of the Spark IM Client.";
}
public void processPacket(Packet packet) {
if (packet instanceof IQ) {
IQ iqPacket = (IQ)packet;
if (IQ.Type.get == iqPacket.getType()) {
Element childElement = (iqPacket).getChildElement();
String namespace = null;
if (childElement != null) {
namespace = childElement.getNamespaceURI();
}
// Handle any disco info requests.
if ("http://jabber.org/protocol/disco#info".equals(namespace)) {
handleDiscoInfo(iqPacket);
}
// Handle any disco item requests.
else if ("http://jabber.org/protocol/disco#items".equals(namespace)) {
handleDiscoItems(iqPacket);
}
// Handle a jabber spark request.
else if ("jabber:iq:spark".equals(namespace)) {
handleSparkIQ(iqPacket);
}
}
else if (IQ.Type.error == iqPacket.getType() || IQ.Type.result == iqPacket.getType()) {
// Ignore these packets
}
else {
// Return error since this is an unknown service request
IQ reply = IQ.createResultIQ(iqPacket);
reply.setError(PacketError.Condition.service_unavailable);
sendPacket(reply);
}
}
}
private void handleSparkIQ(IQ packet) {
IQ reply;
Element iq = packet.getChildElement();
// Define default values
String os = iq.element("os").getText();
reply = IQ.createResultIQ(packet);
// Handle Invalid Requests
if (os == null || (!os.equals("windows") && !os.equals("mac") && !os.equals("linux"))) {
reply.setChildElement(packet.getChildElement().createCopy());
reply.setError(new PacketError(PacketError.Condition.not_acceptable));
sendPacket(reply);
return;
}
Element sparkElement = reply.setChildElement("query", "jabber:iq:spark");
String client = null;
// Handle Windows clients
if (os.equals("windows")) {
client = JiveGlobals.getProperty("spark.windows.client");
}
// Handle Mac clients.
else if (os.equals("mac")) {
client = JiveGlobals.getProperty("spark.mac.client");
}
// Handle Linux Client.
else if (os.equals("linux")) {
client = JiveGlobals.getProperty("spark.linux.client");
}
if (client != null) {
int index = client.indexOf("_");
// Add version number
String versionNumber = client.substring(index + 1);
int indexOfPeriod = versionNumber.indexOf(".");
versionNumber = versionNumber.substring(0, indexOfPeriod);
versionNumber = versionNumber.replaceAll("_", ".");
sparkElement.addElement("version").setText(versionNumber);
// Add updated time.
File clientFile = new File(JiveGlobals.getHomeDirectory(), "enterprise/spark/" + client);
if (!clientFile.exists()) {
reply.setChildElement(packet.getChildElement().createCopy());
reply.setError(new PacketError(PacketError.Condition.item_not_found));
sendPacket(reply);
return;
}
long updatedTime = clientFile.lastModified();
sparkElement.addElement("updatedTime").setText(Long.toString(updatedTime));
// Add download url
String downloadURL = JiveGlobals.getProperty("spark.client.downloadURL");
String server = XMPPServer.getInstance().getServerInfo().getXMPPDomain();
downloadURL = downloadURL.replace("127.0.0.1", server);
sparkElement.addElement("downloadURL").setText(downloadURL + "?client=" + client);
String displayMessage = JiveGlobals.getProperty("spark.client.displayMessage");
if (displayMessage != null && displayMessage.trim().length() > 0) {
sparkElement.addElement("displayMessage").setText(displayMessage);
}
}
else {
reply.setChildElement(packet.getChildElement().createCopy());
reply.setError(new PacketError(PacketError.Condition.item_not_found));
sendPacket(reply);
return;
}
sendPacket(reply);
}
private void handleDiscoItems(IQ packet) {
IQ replyPacket = IQ.createResultIQ(packet);
replyPacket.setChildElement("query", "http://jabber.org/protocol/disco#items");
sendPacket(replyPacket);
}
private void handleDiscoInfo(IQ packet) {
IQ replyPacket = IQ.createResultIQ(packet);
Element responseElement =
replyPacket.setChildElement("query", "http://jabber.org/protocol/disco#info");
Element identity = responseElement.addElement("identity");
identity.addAttribute("category", "updater");
identity.addAttribute("type", "text");
identity.addAttribute("name", "Spark Updater");
responseElement.addElement("feature").addAttribute("var", "jabber:iq:updater");
sendPacket(replyPacket);
}
public void initialize(JID jid, ComponentManager componentManager) throws ComponentException {
// Do nothing.
}
public void start() {
// Do nothing
}
public void shutdown() {
// Do nothing.
}
private void sendPacket(Packet packet) {
try {
componentManager.sendPacket(this, packet);
}
catch (ComponentException e) {
Log.error(e.getMessage(), e);
}
}
}