Commit a1ba1cfe authored by Matt Tucker's avatar Matt Tucker Committed by matt

Setup tool now uses sitemesh, restart no longer required after end of setup...

Setup tool now uses sitemesh, restart no longer required after end of setup (JM-444), cleaned up some UI and text in setup tool, cleaned up setup of admin user (JM-322).

git-svn-id: http://svn.igniterealtime.org/svn/repos/messenger/trunk@3001 b35dd754-fafc-0310-a699-88a17e54d16e
parent 0714df19
......@@ -143,6 +143,7 @@
## Added key: 'timezone.choose'
## Added key: 'plugin.admin.click_reload'
## Added key: 'plugin.admin.reload_success'
## Added key: 'admin.console.restarting'
## Modified key: 'sidebar.server-locale'
## Modified key: 'sidebar.server-locale.descr'
## Modified key: 'locale.title'
......@@ -159,6 +160,13 @@
## Modified key: 'sidebar.server-audit-policy.descr'
## Modified key: 'sidebar.server-data-settings.descr'
## Modified key: 'sidebar.server-ssl.descr'
## Modified key: 'setup.index.title'
## Modified key: 'setup.index.info'
## Modified key: 'setup.datasource.settings.title'
## Modified key: 'setup.datasource.settings.embedded_info'
## Modified key: 'setup.datasource.standard.title'
## Modified key: 'setup.sidebar.datasource'
## Modified key: 'setup.host.settings.invalid_port'
## Removed key: 'license.details.info'
## Removed key: 'license.details.info1'
## Removed key: 'license.details.details'
......@@ -184,6 +192,8 @@
## Removed key: 'user.browser.add_user'
## Removed key: 'user.browser.browse_users'
## Removed key: 'user.browser.browse_users_desc'
## Removed key: 'setup.finished.restart'
## Removed key: 'setup.finished.restart2'
# Messenger
......@@ -339,6 +349,7 @@ admin.authenticated={0} authenticated on connection {1}
admin.warn.license=License limit exceeded, refusing user connection
admin.error.license=Could not license plugin {0}
admin.console.warning=Warning: admin console not started due to configuration settings.
admin.console.restarting=Restarting admin console...
admin.console.listening=Admin console listening at
# Server messages (to users)
......@@ -1284,7 +1295,7 @@ setup.datasource.jndi.note=Note, it might take between 30-60 seconds to connect
# Setup datasource settings Page
setup.datasource.settings.title=Datasource Settings
setup.datasource.settings.title=Database Settings
setup.datasource.settings.info=Choose how you would like to connect to the {0} database.
setup.datasource.settings.connect=Standard Database Connection
setup.datasource.settings.connect_info=Use an external database with the built-in connection pool.
......@@ -1292,12 +1303,12 @@ setup.datasource.settings.jndi=JNDI Datasource
setup.datasource.settings.jndi_info=Use a datasource defined by your application server via JNDI.
setup.datasource.settings.embedded=Embedded Database
setup.datasource.settings.embedded_info=Use an embedded database, powered by HSQLDB. This option \
requires no external database configuration and is an easy way to get running quickly. However, \
this is not recommended for large installations.
requires no external database configuration and is an easy way to get up and running quickly. \
However, is does not offer the same level of performance as an external database.
# Setup datasource standard Page
setup.datasource.standard.title=Datasource Settings - Standard Connection
setup.datasource.standard.title=Database Settings - Standard Connection
setup.datasource.standard.label=Database Driver Presets
setup.datasource.standard.info=Specify a JDBC driver and connection properties to connect to your \
database. If you need more information about this process please see the database documentation \
......@@ -1332,8 +1343,6 @@ setup.datasource.standard.note=Note, it might take between 30-60 seconds to conn
setup.finished.title=Setup Complete!
setup.finished.info=This installation of {0} is now complete. To continue:
setup.finished.restart=Please
setup.finished.restart2=the server.
setup.finished.login=Login to the admin console
# Setup host settings Page
......@@ -1346,7 +1355,7 @@ setup.host.settings.invalid_domain=Invalid domain.
setup.host.settings.hostname=Hostname or IP address of this server.
setup.host.settings.port=Admin Console Port:
setup.host.settings.secure_port=Secure Admin Console Port:
setup.host.settings.invalid_port=Invalid port number.
setup.host.settings.invalid_port=Invalid port number
setup.host.settings.port_number=Port number for the web-based admin console (default is 9090).
setup.host.settings.secure_port_number=Port number for the web-based admin console through SSL (default is 9091).
setup.host.settings.ssl=SSL Connections Enabled:
......@@ -1356,10 +1365,10 @@ setup.host.settings.secure=Enables or disables secure XMPP connections.
# Setup index Page
setup.index.title=Language Selection
setup.index.title=Welcome to Setup
setup.index.choose_lang=Choose Language
setup.index.info=Welcome to {0} Setup. This tool will lead you through the initial setup or \
upgrade process. Before you continue, choose a language for the system or use the default of English.
setup.index.info=Welcome to {0} Setup. This tool will lead you through the initial setup \
of the server. Before you continue, choose your preferred language.
setup.index.success=Success
setup.index.error=Error
setup.index.vm=Java VM Support
......@@ -1387,7 +1396,7 @@ setup.pause.close=Close Window
setup.sidebar.title=Setup Progress
setup.sidebar.language=Language Selection
setup.sidebar.settings=Server Settings
setup.sidebar.datasource=Datasource Settings
setup.sidebar.datasource=Database Settings
setup.sidebar.admin=Admin Account
# SSL settings Page
......
......@@ -24,7 +24,7 @@ import java.io.InputStream;
import java.net.URL;
/**
* A model for admin tab and sidebar info. This class loads in xml definitions of the
* A model for admin tab and sidebar info. This class loads in XML definitions of the
* data and produces an in-memory model.<p>
*
* This class loads its data from the <tt>admin-sidebar.xml</tt> file which is assumed
......@@ -40,10 +40,6 @@ public class AdminConsole {
private static Element generatedModel;
static {
init();
}
private static void init() {
overrideModels = new LinkedHashMap<String,Element>();
load();
}
......
......@@ -49,7 +49,7 @@ public class DbConnectionManager {
private static final int CURRENT_MINOR_VERSION = 2;
private static ConnectionProvider connectionProvider;
private static Object providerLock = new Object();
private static final Object providerLock = new Object();
// True if connection profiling is turned on. Always false by default.
private static boolean profilingEnabled = false;
......@@ -356,6 +356,21 @@ public class DbConnectionManager {
JiveGlobals.setXMLProperty("connectionProvider.className", provider.getClass().getName());
}
/**
* Destroys the currennt connection provider. Future calls to
* {@link #getConnectionProvider()} will return <tt>null</tt> until a new
* ConnectionProvider is set, or one is automatically loaded by a call to
* {@link #getConnection()}.
*/
public static void destroyConnectionProvider() {
synchronized (providerLock) {
if (connectionProvider != null) {
connectionProvider.destroy();
connectionProvider = null;
}
}
}
/**
* Retrives a large text column from a result set, automatically performing
* streaming if the JDBC driver requires it. This is necessary because
......
......@@ -226,6 +226,11 @@ public class XMPPServer {
initialized = true;
}
/**
* Finish the setup process. Because this method is meant to be called from inside
* the Admin console plugin, it spawns its own thread to do the work so that the
* class loader is correct.
*/
public void finishSetup() {
if (!setupMode) {
return;
......@@ -235,9 +240,20 @@ public class XMPPServer {
setupMode = false;
}
if (!setupMode) {
Thread finishSetup = new Thread() {
public void run() {
try {
// Workaround while admin is a plugin.
// If the user selected different ports for the admin console to run on,
// we need to restart the embedded Jetty instance to listen on the
// new ports.
if (!JiveGlobals.getXMLProperty("adminConsole.port").equals("9090") ||
!JiveGlobals.getXMLProperty("adminConsole.securePort").equals("9091"))
{
// Wait a short period before shutting down the admin console. Otherwise,
// the page that requested the setup finish won't render properly!
Thread.sleep(1000);
((AdminConsolePlugin)pluginManager.getPlugin("admin")).restartListeners();
}
verifyDataSource();
// First load all the modules so that modules may access other modules while
......@@ -247,18 +263,18 @@ public class XMPPServer {
initModules();
// Start all the modules
startModules();
startDate = new Date();
stopDate = null;
}
catch (Exception e) {
e.printStackTrace();
Log.error(e);
System.out.println(LocaleUtils.getLocalizedString("startup.error"));
shutdownServer();
}
}
};
// Use the correct class loader.
finishSetup.setContextClassLoader(loader);
finishSetup.start();
}
}
public void start() {
......@@ -350,10 +366,9 @@ public class XMPPServer {
* @param module the name of the class that implements the Module interface.
*/
private void loadModule(String module) {
Module mod = null;
try {
Class modClass = loader.loadClass(module);
mod = (Module)modClass.newInstance();
Module mod = (Module)modClass.newInstance();
this.modules.put(modClass, mod);
}
catch (Exception e) {
......@@ -557,7 +572,7 @@ public class XMPPServer {
}
}
catch (FileNotFoundException fe) {
// Ignore.
}
}
......@@ -569,8 +584,10 @@ public class XMPPServer {
messengerHome = verifyHome("..", jiveConfigName).getCanonicalFile();
}
catch (FileNotFoundException fe) {
// Ignore.
}
catch (IOException ie) {
// Ignore.
}
}
......@@ -656,6 +673,7 @@ public class XMPPServer {
System.exit(0);
}
catch (InterruptedException e) {
// Ignore.
}
}
......
......@@ -26,8 +26,8 @@ import org.jivesoftware.util.LocaleUtils;
import org.jivesoftware.util.Log;
import org.mortbay.http.SunJsseListener;
import org.mortbay.http.HttpListener;
import org.mortbay.http.HttpContext;
import org.mortbay.jetty.Server;
import org.mortbay.jetty.servlet.WebApplicationContext;
import org.mortbay.log.Factory;
import org.mortbay.log.LogImpl;
import org.mortbay.log.OutputStreamLogSink;
......@@ -44,10 +44,11 @@ import java.io.File;
public class AdminConsolePlugin implements Plugin {
private static Server jetty = null;
private String interfaceName;
private int port;
private int securePort;
private File pluginDir;
private HttpContext context = null;
private HttpListener plainListener = null;
private HttpListener secureListener = null;
......@@ -59,15 +60,30 @@ public class AdminConsolePlugin implements Plugin {
public void restartListeners() {
try {
String restarting = LocaleUtils.getLocalizedString("admin.console.restarting");
System.out.println(restarting);
Log.info(restarting);
jetty.stop();
if (plainListener != null) {
jetty.removeListener(plainListener);
plainListener = null;
}
if (secureListener != null) {
jetty.removeListener(secureListener);
secureListener = null;
}
jetty.removeContext(context);
loadListeners();
// Add web-app
context = jetty.addWebApplication("/",
pluginDir.getAbsoluteFile() + File.separator + "webapp");
context.setWelcomeFiles(new String[]{"index.jsp"});
jetty.start();
printListenerMessages();
}
catch (Exception e) {
Log.error(e);
......@@ -75,10 +91,10 @@ public class AdminConsolePlugin implements Plugin {
}
private void loadListeners() throws Exception {
// Configure HTTP socket listener
// Setting this property to a not null value will imply that the Jetty server will only
// accept connect requests to that IP address
interfaceName = JiveGlobals.getXMLProperty("adminConsole.interface");
// Configure HTTP socket listener. Setting the interface property to a
// non null value will imply that the Jetty server will only
// accept connect requests to that IP address.
String interfaceName = JiveGlobals.getXMLProperty("adminConsole.interface");
port = JiveGlobals.getXMLProperty("adminConsole.port", 9090);
InetAddrPort address = new InetAddrPort(interfaceName, port);
if (port > 0) {
......@@ -92,22 +108,13 @@ public class AdminConsolePlugin implements Plugin {
// Get the keystore location. The default location is security/keystore
String keyStoreLocation = JiveGlobals.getProperty("xmpp.socket.ssl.keystore",
"resources" + File.separator + "security" + File.separator + "keystore");
// The location is relative to the home directory of the application.
keyStoreLocation = JiveGlobals.getHomeDirectory() + File.separator + keyStoreLocation;
// Get the keystore password. The default password is "changeit".
String keypass = JiveGlobals.getProperty("xmpp.socket.ssl.keypass", "changeit");
keypass = keypass.trim();
// Get the truststore location; default at security/truststore
String trustStoreLocation = JiveGlobals.getProperty("xmpp.socket.ssl.truststore",
"resources" + File.separator + "security" + File.separator + "truststore");
trustStoreLocation = JiveGlobals.getHomeDirectory() + File.separator +
trustStoreLocation;
// Get the truststore passwprd; default is "changeit".
String trustpass = JiveGlobals.getProperty("xmpp.socket.ssl.trustpass", "changeit");
trustpass = trustpass.trim();
listener.setKeystore(keyStoreLocation);
listener.setKeyPassword(keypass);
listener.setPassword(keypass);
......@@ -124,6 +131,7 @@ public class AdminConsolePlugin implements Plugin {
}
public void initializePlugin(PluginManager manager, File pluginDir) {
this.pluginDir = pluginDir;
try {
// Configure logging to a file, creating log dir if needed
System.setProperty("org.apache.commons.logging.LogFactory", "org.mortbay.log.Factory");
......@@ -144,40 +152,13 @@ public class AdminConsolePlugin implements Plugin {
loadListeners();
// Add web-app
WebApplicationContext webAppContext = jetty.addWebApplication("/",
context = jetty.addWebApplication("/",
pluginDir.getAbsoluteFile() + File.separator + "webapp");
webAppContext.setWelcomeFiles(new String[]{"index.jsp"});
context.setWelcomeFiles(new String[]{"index.jsp"});
jetty.start();
String warning = LocaleUtils.getLocalizedString("admin.console.warning");
String listening = LocaleUtils.getLocalizedString("admin.console.listening");
if (plainListener == null && secureListener == null) {
Log.info(warning);
System.out.println(warning);
}
else if (plainListener == null && secureListener != null) {
Log.info(listening + " https://" +
XMPPServer.getInstance().getServerInfo().getName() + ":" + securePort);
System.out.println(listening + " https://" +
XMPPServer.getInstance().getServerInfo().getName() + ":" + securePort);
}
else if (secureListener == null && plainListener != null) {
Log.info(listening + " http://" +
XMPPServer.getInstance().getServerInfo().getName() + ":" + port);
System.out.println(listening + " http://" +
XMPPServer.getInstance().getServerInfo().getName() + ":" + port);
}
else {
String msg = listening + ":\n" +
" http://" + XMPPServer.getInstance().getServerInfo().getName() + ":" +
port + "\n" +
" https://" + XMPPServer.getInstance().getServerInfo().getName() + ":" +
securePort;
Log.info(msg);
System.out.println(msg);
}
printListenerMessages();
}
catch (Exception e) {
System.err.println("Error starting admin console: " + e.getMessage());
......@@ -207,4 +188,38 @@ public class AdminConsolePlugin implements Plugin {
public static Server getJettyServer() {
return jetty;
}
/**
* Writes out startup messages for the listeners.
*/
private void printListenerMessages() {
String warning = LocaleUtils.getLocalizedString("admin.console.warning");
String listening = LocaleUtils.getLocalizedString("admin.console.listening");
if (plainListener == null && secureListener == null) {
Log.info(warning);
System.out.println(warning);
}
else if (plainListener == null && secureListener != null) {
Log.info(listening + " https://" +
XMPPServer.getInstance().getServerInfo().getName() + ":" + securePort);
System.out.println(listening + " https://" +
XMPPServer.getInstance().getServerInfo().getName() + ":" + securePort);
}
else if (secureListener == null && plainListener != null) {
Log.info(listening + " http://" +
XMPPServer.getInstance().getServerInfo().getName() + ":" + port);
System.out.println(listening + " http://" +
XMPPServer.getInstance().getServerInfo().getName() + ":" + port);
}
else {
String msg = listening + ":\n" +
" http://" + XMPPServer.getInstance().getServerInfo().getName() + ":" +
port + "\n" +
" https://" + XMPPServer.getInstance().getServerInfo().getName() + ":" +
securePort;
Log.info(msg);
System.out.println(msg);
}
}
}
\ No newline at end of file
......@@ -52,7 +52,6 @@ public class PluginManager {
private Map<String, Plugin> plugins;
private Map<Plugin, PluginClassLoader> classloaders;
private Map<Plugin, File> pluginDirs;
private boolean setupMode = !(Boolean.valueOf(JiveGlobals.getXMLProperty("setup")).booleanValue());
private ScheduledExecutorService executor = null;
private Map<Plugin, PluginDevEnvironment> pluginDevelopment;
private Map<Plugin, List<String>> parentPluginMap;
......@@ -148,7 +147,7 @@ public class PluginManager {
*/
private void loadPlugin(File pluginDir) {
// Only load the admin plugin during setup mode.
if (setupMode && !(pluginDir.getName().equals("admin"))) {
if (XMPPServer.getInstance().isSetupMode() && !(pluginDir.getName().equals("admin"))) {
return;
}
Log.debug("Loading plugin " + pluginDir.getName());
......
......@@ -62,7 +62,7 @@ public class JiveGlobals {
if (locale == null) {
if (xmlProperties != null) {
String [] localeArray;
String localeProperty = (String) xmlProperties.getProperty("locale");
String localeProperty = xmlProperties.getProperty("locale");
if (localeProperty != null) {
localeArray = localeProperty.split("_");
}
......@@ -106,13 +106,9 @@ public class JiveGlobals {
setXMLProperty("locale", locale.toString());
// Reset the date formatter objects
timeFormat = DateFormat.getTimeInstance(DateFormat.SHORT, locale);
dateFormat = DateFormat.getDateInstance(DateFormat.MEDIUM, locale);
dateTimeFormat = DateFormat.getDateTimeInstance(DateFormat.MEDIUM,
DateFormat.MEDIUM, locale);
timeFormat.setTimeZone(timeZone);
dateFormat.setTimeZone(timeZone);
dateTimeFormat.setTimeZone(timeZone);
timeFormat = null;
dateFormat = null;
dateTimeFormat = null;
}
/**
......@@ -343,7 +339,9 @@ public class JiveGlobals {
try {
return Integer.parseInt(value);
}
catch (NumberFormatException nfe) { }
catch (NumberFormatException nfe) {
// Ignore.
}
}
return defaultValue;
}
......@@ -436,8 +434,7 @@ public class JiveGlobals {
String[] propNames = xmlProperties.getChildrenProperties(parent);
List<String> values = new ArrayList<String>();
for (int i = 0; i < propNames.length; i++) {
String propName = propNames[i];
for (String propName : propNames) {
String value = getProperty(parent + "." + propName);
if (value != null) {
values.add(value);
......@@ -515,7 +512,9 @@ public class JiveGlobals {
try {
return Integer.parseInt(value);
}
catch (NumberFormatException nfe) { }
catch (NumberFormatException nfe) {
// Ignore.
}
}
return defaultValue;
}
......@@ -528,7 +527,7 @@ public class JiveGlobals {
* Otherwise <tt>false</tt> is returned.
*/
public static boolean getBooleanProperty(String name) {
return Boolean.valueOf(getProperty(name)).booleanValue();
return Boolean.valueOf(getProperty(name));
}
/**
......@@ -546,7 +545,7 @@ public class JiveGlobals {
public static boolean getBooleanProperty(String name, boolean defaultValue) {
String value = getProperty(name);
if (value != null) {
return Boolean.valueOf(getProperty(name)).booleanValue();
return Boolean.valueOf(getProperty(name));
}
else {
return defaultValue;
......@@ -592,9 +591,8 @@ public class JiveGlobals {
Collection<String> propertyNames = properties.getChildrenNames(parent);
List<String> values = new ArrayList<String>();
for (Iterator i=propertyNames.iterator(); i.hasNext(); ) {
String propName = (String)i.next();
String value = getProperty(propName);
for (String propertyName : propertyNames) {
String value = getProperty(propertyName);
if (value != null) {
values.add(value);
}
......@@ -663,7 +661,7 @@ public class JiveGlobals {
if (isSetupMode()) {
return;
}
properties = JiveProperties.getInstance();;
properties = JiveProperties.getInstance();
}
properties.remove(name);
}
......@@ -693,7 +691,7 @@ public class JiveGlobals {
* @return true if in setup mode.
*/
private static boolean isSetupMode() {
return !(Boolean.valueOf(JiveGlobals.getXMLProperty("setup")).booleanValue());
return !Boolean.valueOf(JiveGlobals.getXMLProperty("setup"));
}
/**
......@@ -709,7 +707,6 @@ public class JiveGlobals {
msg.append("Critical Error! The home directory has not been configured, \n");
msg.append("which will prevent the application from working correctly.\n\n");
System.err.println(msg.toString());
return;
}
// Create a manager with the full path to the xml config file.
else {
......@@ -719,7 +716,6 @@ public class JiveGlobals {
catch (IOException ioe) {
Log.error(ioe);
failedLoading = true;
return;
}
}
}
......
......@@ -46,7 +46,7 @@ public class XMLProperties {
* Parsing the XML file every time we need a property is slow. Therefore,
* we use a Map to cache property values that are accessed more than once.
*/
private Map propertyCache = new HashMap();
private Map<String, String> propertyCache = new HashMap<String, String>();
/**
* Creates a new XMLPropertiesTest object.
......
<decorators defaultdir="/decorators">
<decorator name="setup" page="setup.jsp">
<pattern>/setup/*.jsp</pattern>
</decorator>
<decorator name="main" page="main.jsp">
<pattern>/*.jsp</pattern>
<pattern>/plugins</pattern>
</decorator>
<decorator name="none"/>
<excludes>
<pattern>/setup/*</pattern>
<pattern>/setup/setup-completed.jsp*</pattern>
<pattern>/login.jsp*</pattern>
<pattern>/plugin-icon.jsp*</pattern>
</excludes>
......
......@@ -23,7 +23,7 @@
<filter-class>org.jivesoftware.admin.AuthCheckFilter</filter-class>
<init-param>
<param-name>excludes</param-name>
<param-value>login.jsp,index.jsp?logout=true,setup-,.gif,.png,error-serverdown.jsp</param-value>
<param-value>login.jsp,index.jsp?logout=true,setup/index.jsp,setup/setup-,.gif,.png,error-serverdown.jsp</param-value>
</init-param>
</filter>
......
......@@ -2,7 +2,7 @@
- $Revision: 2701 $
- $Date: 2005-08-19 16:48:22 -0700 (Fri, 19 Aug 2005) $
-
- Copyright (C) 2004 Jive Software. All rights reserved.
- Copyright (C) 2004-2005 Jive Software. All rights reserved.
-
- This software is published under the terms of the GNU Public License (GPL),
- a copy of which is included in this distribution.
......
<%--
- $Revision: 2701 $
- $Date: 2005-08-19 16:48:22 -0700 (Fri, 19 Aug 2005) $
-
- Copyright (C) 2004-2005 Jive Software. All rights reserved.
-
- This software is published under the terms of the GNU Public License (GPL),
- a copy of which is included in this distribution.
--%>
<%@ page import="org.jivesoftware.util.LocaleUtils"%>
<%@ page import="org.jivesoftware.util.ClassUtils"%>
<%@ page import="java.beans.PropertyDescriptor"%>
<%@ page import="java.io.File"%>
<%@ page import="org.jivesoftware.database.DbConnectionManager"%>
<%@ page import="java.sql.Connection"%>
<%@ page import="java.util.Map"%>
<%@ page import="java.sql.Statement"%>
<%@ page import="java.sql.SQLException"%>
<%@ page import="org.jivesoftware.messenger.XMPPServer"%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib uri="http://java.sun.com/jstl/fmt_rt" prefix="fmt" %>
<%@ taglib uri="http://www.opensymphony.com/sitemesh/decorator" prefix="decorator" %>
<%@ taglib uri="http://www.opensymphony.com/sitemesh/page" prefix="page" %>
<decorator:usePage id="decoratedPage" />
<%
// Check to see if the sidebar should be shown; default to true unless the page specifies
// that it shouldn't be.
String sidebar = decoratedPage.getProperty("meta.showSidebar");
if (sidebar == null) {
sidebar = "true";
}
boolean showSidebar = Boolean.parseBoolean(sidebar);
%>
<%!
final PropertyDescriptor getPropertyDescriptor(PropertyDescriptor[] pd, String name) {
for (int i=0; i<pd.length; i++) {
if (name.equals(pd[i].getName())) {
return pd[i];
}
}
return null;
}
boolean testConnection(Map<String,String> errors) {
boolean success = true;
Connection con = null;
try {
con = DbConnectionManager.getConnection();
if (con == null) {
success = false;
errors.put("general","A connection to the database could not be "
+ "made. View the error message by opening the "
+ "\"" + File.separator + "logs" + File.separator + "error.log\" log "
+ "file, then go back to fix the problem.");
}
else {
// See if the Jive db schema is installed.
try {
Statement stmt = con.createStatement();
// Pick an arbitrary table to see if it's there.
stmt.executeQuery("SELECT * FROM jiveID");
stmt.close();
}
catch (SQLException sqle) {
success = false;
sqle.printStackTrace();
errors.put("general","The Jive Messenger database schema does not "
+ "appear to be installed. Follow the installation guide to "
+ "fix this error.");
}
}
}
catch (Exception ignored) {}
finally {
try {
con.close();
} catch (Exception ignored) {}
}
return success;
}
%>
<html>
<head>
<title><fmt:message key="title" /> <fmt:message key="setup.title" />: <decorator:title /></title>
<link rel="stylesheet" type="text/css" href="setup-style.css">
</head>
<body>
<span class="jive-setup-header">
<table cellpadding="8" cellspacing="0" border="0" width="100%">
<tr>
<td>
<fmt:message key="title" /> <fmt:message key="setup.title" />
</td>
</tr>
</table>
</span>
<table bgcolor="#bbbbbb" cellpadding="0" cellspacing="0" border="0" width="100%">
<tr><td><img src="../images/blank.gif" width="1" height="1" border="0" alt=""></td></tr>
</table>
<table bgcolor="#dddddd" cellpadding="0" cellspacing="0" border="0" width="100%">
<tr><td><img src="../images/blank.gif" width="1" height="1" border="0" alt=""></td></tr>
</table>
<table bgcolor="#eeeeee" cellpadding="0" cellspacing="0" border="0" width="100%">
<tr><td><img src="../images/blank.gif" width="1" height="1" border="0" alt=""></td></tr>
</table>
<br>
<table cellpadding="0" cellspacing="0" border="0" width="100%">
<tr valign="top">
<% if (showSidebar) { %>
<td width="1%" nowrap>
<%!
final String INCOMPLETE = "incomplete";
final String IN_PROGRESS = "in_progress";
final String DONE = "done";
%>
<% // Get sidebar values from the session:
String step1 = (String)session.getAttribute("jive.setup.sidebar.1");
String step2 = (String)session.getAttribute("jive.setup.sidebar.2");
String step3 = (String)session.getAttribute("jive.setup.sidebar.3");
String step4 = (String)session.getAttribute("jive.setup.sidebar.4");
if (step1 == null) { step1 = IN_PROGRESS; }
if (step2 == null) { step2 = INCOMPLETE; }
if (step3 == null) { step3 = INCOMPLETE; }
if (step4 == null) { step4 = INCOMPLETE; }
String[] items = {step1, step2, step3, step4};
String[] names = {
LocaleUtils.getLocalizedString("setup.sidebar.language"),
LocaleUtils.getLocalizedString("setup.sidebar.settings"),
LocaleUtils.getLocalizedString("setup.sidebar.datasource"),
LocaleUtils.getLocalizedString("setup.sidebar.admin")
};
String[] links = {
"index.jsp",
"setup-host-settings.jsp",
"setup-datasource-settings.jsp",
"setup-admin-settings.jsp"
};
%>
<table bgcolor="#cccccc" cellpadding="0" cellspacing="0" border="0" width="200">
<tr><td>
<table bgcolor="#cccccc" cellpadding="3" cellspacing="1" border="0" width="200">
<tr bgcolor="#eeeeee">
<td align="center">
<span style="padding:6px">
<b><fmt:message key="setup.sidebar.title" /></b>
</span>
</td>
</tr>
<tr bgcolor="#ffffff">
<td>
<table cellpadding="5" cellspacing="0" border="0" width="100%">
<% for (int i=0; i<items.length; i++) { %>
<tr>
<% if (INCOMPLETE.equals(items[i])) { %>
<td width="1%"><img src="../images/bullet-red-14x14.gif" width="14" height="14" border="0" alt="*"></td>
<td width="99%">
<%= names[i] %>
</td>
<% } else if (IN_PROGRESS.equals(items[i])) { %>
<td width="1%"><img src="../images/bullet-yellow-14x14.gif" width="14" height="14" border="0" alt="*"></td>
<td width="99%">
<a href="<%= links[i] %>"><%= names[i] %></a>
</td>
<% } else { %>
<td width="1%"><img src="../images/bullet-green-14x14.gif" width="14" height="14" border="0" alt="*"></td>
<td width="99%">
<a href="<%= links[i] %>"><%= names[i] %></a>
</td>
<% } %>
</tr>
<% } %>
<tr><td colspan="2"><br><br><br><br></td></tr>
</table>
</td>
</tr>
</table>
</td></tr>
</table>
</td>
<td width="1%" nowrap><img src="../images/blank.gif" width="15" height="1" border="0" alt=""></td>
<% } %>
<td width="98%">
<decorator:body/>
</td></tr>
</table>
</body>
</html>
\ No newline at end of file
......@@ -48,7 +48,7 @@
<%-- Check if in setup mode --%>
<c:if test="${admin.setupMode}">
<c:redirect url="setup/setup-index.jsp" />
<c:redirect url="setup/index.jsp" />
</c:if>
<% // get parameters
......
......@@ -10,6 +10,9 @@
<%@ page import="org.jivesoftware.util.ParamUtils,
org.jivesoftware.util.JiveGlobals,
java.util.*" %>
<%@ page import="org.jivesoftware.messenger.XMPPServer"%>
<%@ taglib uri="http://java.sun.com/jstl/fmt_rt" prefix="fmt" %>
<%! // Global vars, methods, etc
......@@ -20,7 +23,13 @@
static final String JIVE_CONFIG_FILE = "jive_config_file";
%>
<%@ include file="setup-global.jspf" %>
<%
// Redirect if we've already run setup:
if (!XMPPServer.getInstance().isSetupMode()) {
response.sendRedirect("setup-completed.jsp");
return;
}
%>
<%@ include file="setup-env-check.jspf" %>
......@@ -52,7 +61,12 @@
Locale locale = JiveGlobals.getLocale();
%>
<%@ include file="setup-header.jspf" %>
<html>
<head>
<title><fmt:message key="setup.index.title" /></title>
</head>
<body>
<p class="jive-setup-page-header">
<fmt:message key="setup.index.title" />
......@@ -60,7 +74,6 @@
<p>
<fmt:message key="setup.index.info">
<fmt:param value="<%= LocaleUtils.getLocalizedString("title") %>" />
</fmt:message>
......@@ -168,4 +181,5 @@
</div>
</form>
<%@ include file="setup-footer.jsp" %>
\ No newline at end of file
</body>
</html>
\ No newline at end of file
......@@ -10,28 +10,29 @@
java.util.Date,
org.jivesoftware.messenger.user.User,
org.jivesoftware.messenger.user.UserManager,
org.jivesoftware.messenger.auth.UnauthorizedException,
org.jivesoftware.messenger.auth.AuthFactory,
org.jivesoftware.messenger.auth.AuthToken,
org.jivesoftware.util.JiveGlobals,
org.jivesoftware.messenger.auth.DefaultAuthProvider" %>
org.jivesoftware.util.JiveGlobals" %>
<%@ page import="org.jivesoftware.messenger.XMPPServer"%>
<%@ page import="org.jivesoftware.messenger.auth.AuthFactory"%>
<%@ taglib uri="http://java.sun.com/jstl/core_rt" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jstl/fmt_rt" prefix="fmt" %>
<%
// Redirect if we've already run setup:
if (!XMPPServer.getInstance().isSetupMode()) {
response.sendRedirect("setup-completed.jsp");
return;
}
%>
<%! // Global vars, methods, etc
void setSetupFinished(HttpSession session) {
JiveGlobals.setXMLProperty("setup","true");
// update the sidebar status
session.setAttribute("jive.setup.sidebar.4","done");
// Indicate a server is required:
session.setAttribute("jive.setup.requireRestart","true");
}
%>
<%@ include file="setup-global.jspf" %>
<jsp:useBean id="adminManager" class="org.jivesoftware.util.WebManager" />
<% // Get parameters
String password = ParamUtils.getParameter(request,"password");
String email = ParamUtils.getParameter(request,"email");
......@@ -51,7 +52,7 @@
}
// Error checks
Map errors = new HashMap();
Map<String,String> errors = new HashMap<String,String>();
if (doContinue) {
if (password == null) {
errors.put("password","password");
......@@ -86,8 +87,6 @@
adminUser.setCreationDate(now);
adminUser.setModificationDate(now);
// TODO: Check for Plugin
// setup is finished, indicate so:
setSetupFinished(session);
// All good so redirect
......@@ -103,8 +102,11 @@
}
}
%>
<%@ include file="setup-header.jspf" %>
<html>
<head>
<title><fmt:message key="setup.admin.settings.account" /></title>
</head>
<body>
<p class="jive-setup-page-header">
<fmt:message key="setup.admin.settings.account" />
......@@ -144,6 +146,25 @@ function checkClick() {
<form action="setup-admin-settings.jsp" name="acctform" method="post" onsubmit="return checkClick();">
<table cellpadding="3" cellspacing="2" border="0">
<%
// If the current password is "admin", don't show the text box for them to type
// the current password. This makes setup simpler for first-time users.
String currentPass = null;
try {
currentPass = AuthFactory.getPassword("admin");
}
catch (Exception e) {
// Ignore.
}
if ("admin".equals(currentPass)) {
%>
<input type="hidden" name="password" value="admin">
<%
}
else {
%>
<tr valign="top">
<td class="jive-label">
<fmt:message key="setup.admin.settings.current_password" />
......@@ -163,6 +184,9 @@ function checkClick() {
<% } %>
</td>
</tr>
<% } %>
<tr valign="top">
<td class="jive-label">
<fmt:message key="setup.admin.settings.email" />
......@@ -234,4 +258,5 @@ document.acctform.password.focus();
//-->
</script>
<%@ include file="setup-footer.jsp" %>
\ No newline at end of file
</body>
</html>
<%@ taglib uri="http://java.sun.com/jstl/core_rt" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jstl/fmt_rt" prefix="fmt" %>
<%--
- $RCSfile$
- $Revision: 985 $
- $Date: 2005-02-18 10:35:44 -0800 (Fri, 18 Feb 2005) $
--%>
<%@ page import="org.jivesoftware.util.*" %>
<%@ taglib uri="http://java.sun.com/jstl/core_rt" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jstl/fmt_rt" prefix="fmt" %>
<html>
<head>
......@@ -34,14 +32,14 @@
</table>
</span>
<table bgcolor="#bbbbbb" cellpadding="0" cellspacing="0" border="0" width="100%">
<tr><td><img src="../images/blank.gif" width="1" height="1" border="0"></td></tr>
<tr><td><img src="../images/blank.gif" width="1" height="1" border="0" alt=""></td></tr>
</table>
<table bgcolor="#dddddd" cellpadding="0" cellspacing="0" border="0" width="100%">
<tr><td><img src="../images/blank.gif" width="1" height="1" border="0"></td></tr>
<tr><td><img src="../images/blank.gif" width="1" height="1" border="0" alt=""></td></tr>
</table>
<table bgcolor="#eeeeee" cellpadding="0" cellspacing="0" border="0" width="100%">
<tr><td><img src="../images/blank.gif" width="1" height="1" border="0"></td></tr>
<tr><td><img src="../images/blank.gif" width="1" height="1" border="0" alt=""></td></tr>
</table>
<br>
......@@ -75,5 +73,5 @@
</tr>
</table>
<%@ include file="setup-footer.jsp"%>
</body>
</html>
\ No newline at end of file
......@@ -16,10 +16,71 @@
org.jivesoftware.database.JNDIDataSourceProvider,
org.jivesoftware.database.DbConnectionManager,
org.jivesoftware.database.JNDIDataSourceProvider" %>
<%@ page import="org.jivesoftware.util.ClassUtils"%>
<%@ page import="java.util.Map"%>
<%@ page import="java.sql.Connection"%>
<%@ page import="java.io.File"%>
<%@ page import="java.sql.Statement"%>
<%@ page import="java.sql.SQLException"%>
<%@ page import="org.jivesoftware.util.LocaleUtils"%>
<%@ page import="org.jivesoftware.messenger.XMPPServer"%>
<%
// Redirect if we've already run setup:
if (!XMPPServer.getInstance().isSetupMode()) {
response.sendRedirect("setup-completed.jsp");
return;
}
%>
<%@ include file="setup-global.jspf" %>
<%!
boolean testConnection(Map<String,String> errors) {
boolean success = true;
Connection con = null;
try {
con = DbConnectionManager.getConnection();
if (con == null) {
success = false;
errors.put("general","A connection to the database could not be "
+ "made. View the error message by opening the "
+ "\"" + File.separator + "logs" + File.separator + "error.log\" log "
+ "file, then go back to fix the problem.");
}
else {
// See if the Jive db schema is installed.
try {
Statement stmt = con.createStatement();
// Pick an arbitrary table to see if it's there.
stmt.executeQuery("SELECT * FROM jiveID");
stmt.close();
}
catch (SQLException sqle) {
success = false;
sqle.printStackTrace();
errors.put("general","The Jive Messenger database schema does not "
+ "appear to be installed. Follow the installation guide to "
+ "fix this error.");
}
}
}
catch (Exception ignored) {}
finally {
try {
con.close();
} catch (Exception ignored) {}
}
return success;
}
%>
<% // check for embedded mode:
<%
boolean embeddedMode = false;
try {
ClassUtils.forName("org.jivesoftware.messenger.starter.ServerStarter");
embeddedMode = true;
}
catch (Exception ignored) {}
// check for embedded mode:
if (embeddedMode) {
// disallow jndi, redirect back to main db page:
response.sendRedirect("setup-datasource-settings.jsp");
......@@ -32,7 +93,7 @@
String jndiNameMode = ParamUtils.getParameter(request,"jndiNameMode");
// Handle a continue request:
Map errors = new HashMap();
Map<String,String> errors = new HashMap<String,String>();
if (request.getParameter("continue") != null) {
String lookupName = null;
// Validate the fields:
......@@ -70,7 +131,12 @@
}
%>
<%@ include file="setup-header.jspf" %>
<html>
<head>
<title><fmt:message key="setup.datasource.jndi.setting" /></title>
</head>
<body>
<p class="jive-setup-page-header">
<fmt:message key="setup.datasource.jndi.setting" />
......@@ -169,4 +235,5 @@ document.jndiform.jndiName.focus();
//-->
</script>
<%@ include file="setup-footer.jsp" %>
\ No newline at end of file
</body>
</html>
\ No newline at end of file
......@@ -14,22 +14,81 @@
org.jivesoftware.database.ConnectionProvider,
org.jivesoftware.database.DbConnectionManager,
java.util.*" %>
<%@ page import="java.io.File"%>
<%@ page import="java.sql.Connection"%>
<%@ page import="java.sql.Statement"%>
<%@ page import="java.sql.SQLException"%>
<%@ page import="org.jivesoftware.util.LocaleUtils"%>
<%@ page import="org.jivesoftware.util.ClassUtils"%>
<%@ page import="org.jivesoftware.messenger.XMPPServer"%>
<%
// Redirect if we've already run setup:
if (!XMPPServer.getInstance().isSetupMode()) {
response.sendRedirect("setup-completed.jsp");
return;
}
%>
<%! // Global vars
static final String STANDARD = "standard";
static final String JNDI = "jndi";
static final String EMBEDDED = "embedded";
boolean testConnection(Map<String,String> errors) {
boolean success = true;
Connection con = null;
try {
con = DbConnectionManager.getConnection();
if (con == null) {
success = false;
errors.put("general","A connection to the database could not be "
+ "made. View the error message by opening the "
+ "\"" + File.separator + "logs" + File.separator + "error.log\" log "
+ "file, then go back to fix the problem.");
}
else {
// See if the Jive db schema is installed.
try {
Statement stmt = con.createStatement();
// Pick an arbitrary table to see if it's there.
stmt.executeQuery("SELECT * FROM jiveID");
stmt.close();
}
catch (SQLException sqle) {
success = false;
sqle.printStackTrace();
errors.put("general","The Jive Messenger database schema does not "
+ "appear to be installed. Follow the installation guide to "
+ "fix this error.");
}
}
}
catch (Exception ignored) {}
finally {
try {
con.close();
} catch (Exception ignored) {}
}
return success;
}
%>
<%@ include file="setup-global.jspf" %>
<%
boolean embeddedMode = false;
try {
ClassUtils.forName("org.jivesoftware.messenger.starter.ServerStarter");
embeddedMode = true;
}
catch (Exception ignored) {}
<% // Get parameters
// Get parameters
String mode = ParamUtils.getParameter(request,"mode");
boolean next = ParamUtils.getBooleanParameter(request,"next");
// handle a mode redirect
Map errors = new HashMap();
Map<String,String> errors = new HashMap<String,String>();
if (next) {
if (STANDARD.equals(mode)) {
response.sendRedirect("setup-datasource-standard.jsp");
......@@ -71,7 +130,11 @@
}
%>
<%@ include file="setup-header.jspf" %>
<html>
<head>
<title><fmt:message key="setup.datasource.settings.title" /></title>
</head>
<body>
<p class="jive-setup-page-header">
<fmt:message key="setup.datasource.settings.title" />
......@@ -101,8 +164,8 @@
<%= ((STANDARD.equals(mode)) ? "checked" : "") %>>
</td>
<td>
<label for="rb02"><b><fmt:message key="setup.datasource.settings.connect" /></b></label> -
<fmt:message key="setup.datasource.settings.connect_info" />
<label for="rb02"><b><fmt:message key="setup.datasource.settings.connect" /></b></label>
<br><fmt:message key="setup.datasource.settings.connect_info" />
</td>
</tr>
......@@ -114,8 +177,8 @@
<%= ((JNDI.equals(mode)) ? "checked" : "") %>>
</td>
<td>
<label for="rb03"><b><fmt:message key="setup.datasource.settings.jndi" /></b></label> -
<fmt:message key="setup.datasource.settings.jndi_info" />
<label for="rb03"><b><fmt:message key="setup.datasource.settings.jndi" /></b></label>
<br><fmt:message key="setup.datasource.settings.jndi_info" />
</td>
</tr>
......@@ -127,8 +190,8 @@
<%= ((EMBEDDED.equals(mode)) ? "checked" : "") %>>
</td>
<td>
<label for="rb01"><b><fmt:message key="setup.datasource.settings.embedded" /></b></label> -
<fmt:message key="setup.datasource.settings.embedded_info" />
<label for="rb01"><b><fmt:message key="setup.datasource.settings.embedded" /></b></label>
<br><fmt:message key="setup.datasource.settings.embedded_info" />
</td>
</tr>
</table>
......@@ -141,4 +204,5 @@
</form>
<%@ include file="setup-footer.jsp" %>
\ No newline at end of file
</body>
</html>
\ No newline at end of file
......@@ -8,23 +8,70 @@
<%@ page import="org.jivesoftware.util.ParamUtils,
java.util.*,
java.beans.BeanInfo,
java.beans.Introspector,
java.beans.PropertyDescriptor,
org.jivesoftware.util.JiveGlobals,
java.sql.Connection,
java.io.File,
java.sql.Statement,
java.sql.SQLException,
org.jivesoftware.database.DbConnectionManager,
org.jivesoftware.database.DefaultConnectionProvider,
org.jivesoftware.util.ClassUtils,
org.jivesoftware.util.Log,
org.jivesoftware.database.DefaultConnectionProvider"
%>
<%@ page import="org.jivesoftware.messenger.XMPPServer"%>
<%@ include file="setup-global.jspf" %>
<%@ taglib uri="http://java.sun.com/jstl/fmt_rt" prefix="fmt" %>
<%
// Redirect if we've already run setup:
if (!XMPPServer.getInstance().isSetupMode()) {
response.sendRedirect("setup-completed.jsp");
return;
}
%>
<%!
boolean testConnection(Map<String,String> errors) {
boolean success = true;
Connection con = null;
try {
con = DbConnectionManager.getConnection();
if (con == null) {
success = false;
errors.put("general","A connection to the database could not be "
+ "made. View the error message by opening the "
+ "\"" + File.separator + "logs" + File.separator + "error.log\" log "
+ "file, then go back to fix the problem.");
}
else {
// See if the Jive db schema is installed.
try {
Statement stmt = con.createStatement();
// Pick an arbitrary table to see if it's there.
stmt.executeQuery("SELECT * FROM jiveID");
stmt.close();
}
catch (SQLException sqle) {
success = false;
sqle.printStackTrace();
errors.put("general","The Jive Messenger database schema does not "
+ "appear to be installed. Follow the installation guide to "
+ "fix this error.");
}
}
}
catch (Exception ignored) {}
finally {
try {
con.close();
} catch (Exception ignored) {}
}
return success;
}
%>
<% // Get parameters
String driver = ParamUtils.getParameter(request,"driver");
String serverURL = ParamUtils.getParameter(request,"serverURL");
......@@ -37,7 +84,7 @@
boolean doContinue = request.getParameter("continue") != null;
// handle a continue request
Map errors = new HashMap();
Map<String,String> errors = new HashMap<String,String>();
if (doContinue) {
// Error check
if (driver == null || "sun.jdbc.odbc.JdbcOdbcDriver".equals(driver)
......@@ -47,7 +94,7 @@
}
else {
try {
loadClass(driver);
ClassUtils.forName(driver);
}
catch (Throwable t) {
errors.put("driver","Unable to load the specified JDBC driver. Please verify the " +
......@@ -146,7 +193,11 @@
}
%>
<%@ include file="setup-header.jspf" %>
<html>
<head>
<title><fmt:message key="setup.datasource.standard.title" /></title>
</head>
<body>
<p class="jive-setup-page-header">
<fmt:message key="setup.datasource.standard.title" />
......@@ -177,7 +228,7 @@
<% } %>
<% // DB preset data
List presets = new ArrayList();
List<String[]> presets = new ArrayList<String []>();
presets.add(new String[]{"MySQL","com.mysql.jdbc.Driver","jdbc:mysql://[host-name]:3306/[database-name]"});
presets.add(new String[]{"Oracle","oracle.jdbc.driver.OracleDriver","jdbc:oracle:thin:@[host-name]:1521:[SID]"});
presets.add(new String[]{"MS SQLServer 2000","com.microsoft.jdbc.sqlserver.SQLServerDriver","jdbc:microsoft:sqlserver://[host-name]:1433;databasename=[database-name]"});
......@@ -188,7 +239,7 @@
<script language="JavaScript" type="text/javascript">
var data = new Array();
<% for (int i=0; i<presets.size(); i++) {
String[] data = (String[])presets.get(i);
String[] data = presets.get(i);
%>
data[<%= i %>] = new Array('<%= data[0] %>','<%= data[1] %>','<%= data[2] %>');
<% } %>
......@@ -216,7 +267,7 @@ function checkSubmit() {
<select size="1" name="presets" onchange="populate(this.options[this.selectedIndex].value)">
<option value=""><fmt:message key="setup.datasource.standard.pick_database" />
<% for (int i=0; i<presets.size(); i++) {
String[] data = (String[])presets.get(i);
String[] data = presets.get(i);
%>
<option value="<%= i %>"> &#149; <%= data[0] %>
<% } %>
......@@ -380,4 +431,5 @@ function checkSubmit() {
</form>
<%@ include file="setup-footer.jsp" %>
\ No newline at end of file
</body>
</html>
\ No newline at end of file
......@@ -7,8 +7,7 @@
<%@ page import="java.lang.reflect.Method,
java.io.File,
org.jivesoftware.util.LocaleUtils" %>
<%-- note, the loadClass method is defined in setup-global.jspf --%>
<%@ page import="org.jivesoftware.util.ClassUtils"%>
<% // Check the user's environment for minimum requirements.
......@@ -21,33 +20,33 @@
// Check for JDK 1.5
try {
loadClass("java.util.concurrent.ConcurrentHashMap");
ClassUtils.forName("java.util.concurrent.ConcurrentHashMap");
jdk13Installed = true;
}
catch (ClassNotFoundException cnfe) {}
// Check for Servlet 2.3:
try {
Class c = loadClass("javax.servlet.http.HttpSession");
Class c = ClassUtils.forName("javax.servlet.http.HttpSession");
Method m = c.getMethod("getAttribute",new Class[]{String.class});
servlet22Installed = true;
}
catch (ClassNotFoundException cnfe) {}
// Check for JSP 1.1:
try {
loadClass("javax.servlet.jsp.tagext.Tag");
ClassUtils.forName("javax.servlet.jsp.tagext.Tag");
jsp11Installed = true;
}
catch (ClassNotFoundException cnfe) {}
// Check that the Messenger jar are installed:
try {
loadClass("org.jivesoftware.messenger.XMPPServer");
ClassUtils.forName("org.jivesoftware.messenger.XMPPServer");
jiveJarsInstalled = true;
}
catch (ClassNotFoundException cnfe) {}
// Try to determine what the jiveHome directory is:
try {
Class jiveGlobalsClass = loadClass("org.jivesoftware.util.JiveGlobals");
Class jiveGlobalsClass = ClassUtils.forName("org.jivesoftware.util.JiveGlobals");
Method getMessengerHomeMethod = jiveGlobalsClass.getMethod("getHomeDirectory", (Class[])null);
String messengerHomeProp = (String)getMessengerHomeMethod.invoke(jiveGlobalsClass, (Object[])null);
if (messengerHomeProp != null) {
......
<%@ taglib uri="http://java.sun.com/jstl/core_rt" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jstl/fmt_rt" prefix="fmt" %>
<%--
- $RCSfile$
- $Revision: 1644 $
- $Date: 2005-07-19 09:05:10 -0700 (Tue, 19 Jul 2005) $
--%>
<%@ page import="org.jivesoftware.util.ParamUtils,
org.jivesoftware.messenger.auth.UnauthorizedException,
org.jivesoftware.util.JiveGlobals,
<%@ taglib uri="http://java.sun.com/jstl/core_rt" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jstl/fmt_rt" prefix="fmt" %>
<%@ page import="org.jivesoftware.util.JiveGlobals,
java.util.Map,
java.util.Iterator,
org.jivesoftware.messenger.ConnectionManager,
org.jivesoftware.database.DbConnectionManager,
org.jivesoftware.messenger.XMPPServer"
%>
<%@ page import="org.jivesoftware.util.LocaleUtils"%>
<%
// Redirect if we've already run setup:
if (!XMPPServer.getInstance().isSetupMode()) {
response.sendRedirect("setup-completed.jsp");
return;
}
%>
<%
boolean showSidebar = false;
// First, update with XMPPSettings
Map xmppSettings = (Map)session.getAttribute("xmppSettings");
Iterator iter = xmppSettings.keySet().iterator();
while(iter.hasNext()){
String name = (String)iter.next();
String value = (String)xmppSettings.get(name);
Map<String,String> xmppSettings = (Map<String,String>)session.getAttribute("xmppSettings");
for (String name : xmppSettings.keySet()) {
String value = xmppSettings.get(name);
JiveGlobals.setProperty(name, value);
}
Map xmlSettings = (Map)session.getAttribute("xmlSettings");
iter = xmlSettings.keySet().iterator();
while(iter.hasNext()){
String name = (String)iter.next();
String value = (String)xmlSettings.get(name);
Map<String,String> xmlSettings = (Map<String,String>)session.getAttribute("xmlSettings");
for (String name : xmlSettings.keySet()) {
String value = xmlSettings.get(name);
JiveGlobals.setXMLProperty(name, value);
}
Runnable restart = new Runnable() {
public void run() {
// Shut down connection provider. Some connection providers (such as the
// embedded provider) require a clean shut-down.
DbConnectionManager.getConnectionProvider().destroy();
// Notify that the XMPP server that setup is finished.
XMPPServer.getInstance().finishSetup();
}
};
new Thread(restart).start();
%>
<%@ include file="setup-header.jspf" %>
<html>
<head>
<title><fmt:message key="setup.finished.title" /></title>
<meta name="showSidebar" content="false"/>
</head>
<body>
<p class="jive-setup-page-header">
<fmt:message key="title" /> <fmt:message key="setup.finished.title" />
<fmt:message key="setup.finished.title" />
</p>
<p>
......@@ -56,26 +53,30 @@
</fmt:message>
</p>
<ol>
<li>
<fmt:message key="setup.finished.restart" /> <b style="font-size:1.2em;"><fmt:message key="global.restart" /></b> <fmt:message key="setup.finished.restart2" />
</li>
<li>
<%
String url = null;
<%
// Figure out the URL that the user can use to login to the admin console.
String url;
if (XMPPServer.getInstance().isStandAlone()) {
String server = request.getServerName();
String port = JiveGlobals.getXMLProperty("adminConsole.port");
url = "http://" + server + ":" + port + "/login.jsp?username=admin";
int plainPort = JiveGlobals.getXMLProperty("adminConsole.port", 9090);
int securePort = JiveGlobals.getXMLProperty("adminConsole.securePort", 9091);
// Use secure login if we're currently secure (and the secure port isn't disabled)
// or if the user disabled the plain port.
if ((request.isSecure() && securePort > 0) || plainPort < 0) {
url = "https://" + server + ":" + securePort + "/login.jsp?username=admin";
}
else {
url = "http://" + server + ":" + plainPort + "/login.jsp?username=admin";
}
}
else {
url = request.getRequestURL().toString();
url = url.replace("setup-finished.jsp", "login.jsp?username=admin");
url = url.replace("setup/setup-finished.jsp", "login.jsp?username=admin");
}
%>
<a href="<%= url %>"><fmt:message key="setup.finished.login" /></a>.
</li>
</ol>
<%@ include file="setup-footer.jsp" %>
%>
<ul>
<a href="<%= url %>"><fmt:message key="setup.finished.login" /></a>
</ul>
</body>
</html>
\ No newline at end of file
<%--
- $RCSfile$
- $Revision: 1080 $
- $Date: 2005-03-05 22:58:01 -0800 (Sat, 05 Mar 2005) $
--%>
<%@ page import="java.util.Calendar" %>
</td></tr>
</table>
<br><br>
<table cellpadding="0" cellspacing="0" border="0" width="75%" align="center"
style="border-bottom:1px #ccc solid;">
<tr><td>&nbsp;</td></tr>
</table><br>
<div class="jive-setup-footer">
&copy; <a href="http://www.jivesoftware.org" target="_blank">Jive Software</a>, 2005
</div>
</body>
</html>
\ No newline at end of file
<%--
- $RCSfile$
- $Revision: 1147 $
- $Date: 2005-03-18 09:05:48 -0800 (Fri, 18 Mar 2005) $
--%>
<%@ page import="java.lang.reflect.Method,
java.beans.PropertyDescriptor,
java.sql.Connection,
org.jivesoftware.database.DbConnectionManager,
java.io.File,
java.sql.Statement,
java.sql.SQLException,
java.util.Map,
org.jivesoftware.util.ClassUtils" %>
<% // Figure out if we've already run setup:
boolean doSetup = false;
if (!doSetup) {
response.sendRedirect("setup-completed.jsp");
return;
}
// embedded mode?
boolean embeddedMode = false;
try {
ClassUtils.forName("org.jivesoftware.messenger.starter.ServerStarter");
embeddedMode = true;
}
catch (Exception ignored) {}
// sidebar var for sidebar page - it has to be global.
boolean showSidebar = true;
%>
<%! // Trys to load a class 3 different ways.
Class loadClass(String className) throws ClassNotFoundException {
Class theClass = null;
try {
theClass = Class.forName(className);
}
catch (ClassNotFoundException e1) {
try {
theClass = Thread.currentThread().getContextClassLoader().loadClass(className);
}
catch (ClassNotFoundException e2) {
theClass = getClass().getClassLoader().loadClass(className);
}
}
return theClass;
}
final PropertyDescriptor getPropertyDescriptor(PropertyDescriptor[] pd, String name) {
for (int i=0; i<pd.length; i++) {
if (name.equals(pd[i].getName())) {
return pd[i];
}
}
return null;
}
boolean testConnection(Map errors) {
boolean success = true;
Connection con = null;
try {
con = DbConnectionManager.getConnection();
if (con == null) {
success = false;
errors.put("general","A connection to the database could not be "
+ "made. View the error message by opening the "
+ "\"" + File.separator + "logs" + File.separator + "error.log\" log "
+ "file, then go back to fix the problem.");
}
else {
// See if the Jive db schema is installed.
try {
Statement stmt = con.createStatement();
// Pick an arbitrary table to see if it's there.
stmt.executeQuery("SELECT * FROM jiveID");
stmt.close();
}
catch (SQLException sqle) {
success = false;
sqle.printStackTrace();
errors.put("general","The Jive Messenger database schema does not "
+ "appear to be installed. Follow the installation guide to "
+ "fix this error.");
}
}
}
catch (Exception ignored) {}
finally {
try {
con.close();
} catch (Exception ignored) {}
}
return success;
}
%>
\ No newline at end of file
<%--
- $RCSfile$
- $Revision: 1147 $
- $Date: 2005-03-18 09:05:48 -0800 (Fri, 18 Mar 2005) $
--%>
<%@ page import="java.lang.reflect.Method,
java.beans.PropertyDescriptor,
java.sql.Connection,
org.jivesoftware.database.DbConnectionManager,
java.io.File,
java.sql.Statement,
java.sql.SQLException,
java.util.Map,
org.jivesoftware.util.ClassUtils"
%>
<jsp:useBean id="admin" class="org.jivesoftware.util.WebManager" />
<% admin.init(request, response, session, application, out ); %>
<% // Figure out if we've already run setup:
if (!admin.isSetupMode()) {
response.sendRedirect("setup-completed.jsp");
return;
}
// Is a restart required?
if ("true".equals(session.getAttribute("jive.setup.requireRestart"))) {
response.sendRedirect("setup-completed.jsp");
return;
}
// embedded mode?
boolean embeddedMode = false;
try {
ClassUtils.forName("org.jivesoftware.messenger.starter.ServerStarter");
embeddedMode = true;
}
catch (Exception ignored) {}
// sidebar var for sidebar page - it has to be global.
boolean showSidebar = true;
%>
<%! // Trys to load a class 3 different ways.
Class loadClass(String className) throws ClassNotFoundException {
Class theClass = null;
try {
theClass = Class.forName(className);
}
catch (ClassNotFoundException e1) {
try {
theClass = Thread.currentThread().getContextClassLoader().loadClass(className);
}
catch (ClassNotFoundException e2) {
theClass = getClass().getClassLoader().loadClass(className);
}
}
return theClass;
}
final PropertyDescriptor getPropertyDescriptor(PropertyDescriptor[] pd, String name) {
for (int i=0; i<pd.length; i++) {
if (name.equals(pd[i].getName())) {
return pd[i];
}
}
return null;
}
boolean testConnection(Map errors) {
boolean success = true;
Connection con = null;
try {
con = DbConnectionManager.getConnection();
if (con == null) {
success = false;
errors.put("general","A connection to the database could not be "
+ "made. View the error message by opening the "
+ "\"" + File.separator + "logs" + File.separator + "error.log\" log "
+ "file, then go back to fix the problem.");
}
else {
// See if the Jive db schema is installed.
try {
Statement stmt = con.createStatement();
// Pick an arbitrary table to see if it's there.
stmt.executeQuery("SELECT * FROM jiveID");
stmt.close();
}
catch (SQLException sqle) {
success = false;
sqle.printStackTrace();
errors.put("general","The Jive Messenger database schema does not "
+ "appear to be installed. Follow the installation guide to "
+ "fix this error.");
}
}
}
catch (Exception ignored) {}
finally {
try {
con.close();
} catch (Exception ignored) {}
}
return success;
}
%>
\ No newline at end of file
<%--
- $RCSfile$
- $Revision: 1090 $
- $Date: 2005-03-06 23:10:21 -0800 (Sun, 06 Mar 2005) $
--%>
<%@ page import="org.jivesoftware.util.*" %>
<html>
<head>
<title><fmt:message key="title" /> <fmt:message key="setup.title" /></title>
<link rel="stylesheet" type="text/css" href="setup-style.css">
</head>
<body>
<span class="jive-setup-header">
<table cellpadding="8" cellspacing="0" border="0" width="100%">
<tr>
<td>
<fmt:message key="title" /> <fmt:message key="setup.title" />
</td>
</tr>
</table>
</span>
<table bgcolor="#bbbbbb" cellpadding="0" cellspacing="0" border="0" width="100%">
<tr><td><img src="../images/blank.gif" width="1" height="1" border="0"></td></tr>
</table>
<table bgcolor="#dddddd" cellpadding="0" cellspacing="0" border="0" width="100%">
<tr><td><img src="../images/blank.gif" width="1" height="1" border="0"></td></tr>
</table>
<table bgcolor="#eeeeee" cellpadding="0" cellspacing="0" border="0" width="100%">
<tr><td><img src="../images/blank.gif" width="1" height="1" border="0"></td></tr>
</table>
<br>
<table cellpadding="0" cellspacing="0" border="0" width="100%">
<tr valign="top">
<% if (showSidebar) { %>
<td width="1%" nowrap>
<jsp:include page="setup-sidebar.jsp" flush="true" />
</td>
<td width="1%" nowrap><img src="../images/blank.gif" width="15" height="1" border="0"></td>
<% } %>
<td width="98%">
......@@ -15,27 +15,45 @@
<%@ taglib uri="http://java.sun.com/jstl/core_rt" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jstl/fmt_rt" prefix="fmt" %>
<%@ include file="setup-global.jspf" %>
<%
// Redirect if we've already run setup:
if (!XMPPServer.getInstance().isSetupMode()) {
response.sendRedirect("setup-completed.jsp");
return;
}
%>
<% // Get parameters
String domain = ParamUtils.getParameter(request,"domain");
int embeddedPort = ParamUtils.getIntParameter(request, "embeddedPort", -1);
int securePort = ParamUtils.getIntParameter(request, "securePort", -1);
int embeddedPort = ParamUtils.getIntParameter(request, "embeddedPort", Integer.MIN_VALUE);
int securePort = ParamUtils.getIntParameter(request, "securePort", Integer.MIN_VALUE);
boolean sslEnabled = ParamUtils.getBooleanParameter(request, "sslEnabled", true);
boolean doContinue = request.getParameter("continue") != null;
// handle a continue request:
Map errors = new HashMap();
Map<String,String> errors = new HashMap<String,String>();
if (doContinue) {
// Validate parameters
if (domain == null) {
errors.put("domain","domain");
}
if (XMPPServer.getInstance().isStandAlone()) {
if (embeddedPort < 0) {
if (embeddedPort == Integer.MIN_VALUE) {
errors.put("embeddedPort","embeddedPort");
}
// Force any negative value to -1.
else if (embeddedPort < 0) {
embeddedPort = -1;
}
if (securePort == Integer.MIN_VALUE) {
errors.put("securePort","securePort");
}
// Force any negative value to -1.
else if (securePort < 0) {
securePort = -1;
}
}
else {
embeddedPort = -1;
......@@ -43,14 +61,14 @@
}
// Continue if there were no errors
if (errors.size() == 0) {
Map xmppSettings = new HashMap();
Map<String,String> xmppSettings = new HashMap<String,String>();
xmppSettings.put("xmpp.domain",domain);
xmppSettings.put("xmpp.socket.ssl.active",""+sslEnabled);
xmppSettings.put("xmpp.auth.anonymous", "true" );
session.setAttribute("xmppSettings", xmppSettings);
Map xmlSettings = new HashMap();
Map<String,String> xmlSettings = new HashMap<String,String>();
xmlSettings.put("adminConsole.port",Integer.toString(embeddedPort));
xmlSettings.put("adminConsole.securePort",Integer.toString(securePort));
session.setAttribute("xmlSettings", xmlSettings);
......@@ -79,7 +97,11 @@
}
%>
<%@ include file="setup-header.jspf" %>
<html>
<head>
<title><fmt:message key="setup.host.settings.title" /></title>
</head>
<body>
<style type="text/css">
LABEL { font-weight : normal; }
......@@ -130,7 +152,7 @@ LABEL { font-weight : normal; }
</td>
<td width="99%">
<input type="text" size="6" maxlength="6" name="embeddedPort"
value="<%= ((embeddedPort != -1) ? ""+embeddedPort : "9090") %>">
value="<%= ((embeddedPort != Integer.MIN_VALUE) ? ""+embeddedPort : "9090") %>">
<span class="jive-description">
<br>
<fmt:message key="setup.host.settings.port_number" />
......@@ -150,7 +172,7 @@ LABEL { font-weight : normal; }
</td>
<td width="99%">
<input type="text" size="6" maxlength="6" name="securePort"
value="<%= ((securePort != -1) ? ""+securePort : "9091") %>">
value="<%= ((securePort != Integer.MIN_VALUE) ? ""+securePort : "9091") %>">
<span class="jive-description">
<br>
<fmt:message key="setup.host.settings.secure_port_number" />
......@@ -192,4 +214,5 @@ LABEL { font-weight : normal; }
document.f.domain.focus();
</script>
<%@ include file="setup-footer.jsp" %>
\ No newline at end of file
</body>
</html>
\ No newline at end of file
<%@ taglib uri="http://java.sun.com/jstl/core_rt" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jstl/fmt_rt" prefix="fmt" %>
<%--
- $RCSfile$
- $Revision: 2873 $
- $Date: 2005-09-23 10:54:57 -0700 (Fri, 23 Sep 2005) $
--%>
<%@ page import="org.jivesoftware.util.ParamUtils,
org.jivesoftware.util.JiveGlobals,
java.util.*" %>
<%! // Global vars, methods, etc
static final String JIVE_HOME = "jive_home";
static final String JIVE_LICENSE = "jive_license_file";
static final String JIVE_LICENSE_TEXT = "jive_license_text";
static final String JIVE_DEPENDENCY = "jive_dependency";
static final String JIVE_CONFIG_FILE = "jive_config_file";
%>
<%@ include file="setup-global.jspf" %>
<%@ include file="setup-env-check.jspf" %>
<% // Get parameters
String localeCode = ParamUtils.getParameter(request,"localeCode");
boolean save = request.getParameter("save") != null;
Map errors = new HashMap();
if (save) {
Locale newLocale = null;
if (localeCode != null) {
newLocale = LocaleUtils.localeCodeToLocale(localeCode.trim());
if (newLocale == null) {
errors.put("localeCode","");
}
else {
JiveGlobals.setLocale(newLocale);
// update the sidebar status
session.setAttribute("jive.setup.sidebar.1","done");
session.setAttribute("jive.setup.sidebar.2","in_progress");
// redirect
response.sendRedirect("setup-host-settings.jsp");
return;
}
}
}
Locale locale = JiveGlobals.getLocale();
%>
<%@ include file="setup-header.jspf" %>
<p class="jive-setup-page-header">
<fmt:message key="setup.index.title" />
</p>
<p>
<fmt:message key="setup.index.info">
<fmt:param value="<%= LocaleUtils.getLocalizedString("title") %>" />
</fmt:message>
</p>
<form action="setup-index.jsp" name="sform">
<b><fmt:message key="setup.index.choose_lang" /></b>
<% boolean usingPreset = false;
Locale[] locales = Locale.getAvailableLocales();
for (int i=0; i<locales.length; i++) {
usingPreset = locales[i].equals(locale);
if (usingPreset) { break; }
}
%>
<ul>
<table cellpadding="4" cellspacing="0" border="0">
<tbody>
<tr>
<td>
<input type="radio" name="localeCode" value="cs_CZ" <%= ("cs_CZ".equals(locale.toString()) ? "checked" : "") %>
id="loc01" />
</td>
<td colspan="2">
<label for="loc01">Czech</label> (cs_CZ)
</td>
</tr>
<tr>
<td>
<input type="radio" name="localeCode" value="de" <%= ("de".equals(locale.toString()) ? "checked" : "") %>
id="loc02" />
</td>
<td colspan="2">
<label for="loc02">Deutsch</label> (de)
</td>
</tr>
<tr>
<td>
<input type="radio" name="localeCode" value="en" <%= ("en".equals(locale.toString()) ? "checked" : "") %>
id="loc03" />
</td>
<td colspan="2">
<label for="loc03">English</label> (en)
</td>
</tr>
<tr>
<td>
<input type="radio" name="localeCode" value="es" <%= ("es".equals(locale.toString()) ? "checked" : "") %>
id="loc04" />
</td>
<td colspan="2">
<label for="loc04">Espa&ntilde;ol</label> (es)
</td>
</tr>
<tr>
<td>
<input type="radio" name="localeCode" value="fr" <%= ("fr".equals(locale.toString()) ? "checked" : "") %>
id="loc05" />
</td>
<td colspan="2">
<label for="loc05">Fran&ccedil;ais</label> (fr)
</td>
</tr>
<tr>
<td>
<input type="radio" name="localeCode" value="nl" <%= ("nl".equals(locale.toString()) ? "checked" : "") %>
id="loc06" />
</td>
<td colspan="2">
<label for="loc06">Nederlands</label> (nl)
</td>
</tr>
<tr>
<td>
<input type="radio" name="localeCode" value="pt_BR" <%= ("pt_BR".equals(locale.toString()) ? "checked" : "") %>
id="loc07" />
</td>
<td colspan="2">
<label for="loc07">Portugu&ecirc;s Brasileiro</label> (pt_BR)
</td>
</tr>
<tr>
<td>
<input type="radio" name="localeCode" value="zh_CN" <%= ("zh_CN".equals(locale.toString()) ? "checked" : "") %>
id="loc08" />
</td>
<td>
<a href="#" onclick="document.sform.localeCode[1].checked=true; return false;"><img src="../images/language_zh_CN.gif" border="0" /></a>
</td>
<td>
<label for="loc08">Simplified Chinese</label> (zh_CN)
</td>
</tr>
</tbody>
</table>
</ul>
<br/>
<hr size="0">
<div align="right">
<input type="submit" name="save" value=" <fmt:message key="global.continue" /> ">
</div>
</form>
<%@ include file="setup-footer.jsp" %>
\ No newline at end of file
<%@ taglib uri="http://java.sun.com/jstl/fmt_rt" prefix="fmt" %>
<%--
- $RCSfile$
- $Revision: 985 $
- $Date: 2005-02-18 10:35:44 -0800 (Fri, 18 Feb 2005) $
--%>
<%@ page import="org.jivesoftware.util.ParamUtils,
org.jivesoftware.messenger.auth.UnauthorizedException" %>
<%-- Define Administration Bean --%>
<jsp:useBean id="admin" class="org.jivesoftware.util.WebManager" />
<% admin.init(request, response, session, application, out ); %>
<% boolean showSidebar = false; %>
<%@ include file="setup-header.jspf" %>
<div align=center>
<p>
<fmt:message key="setup.pause.title" />
</p>
<a href="javascript:window.close();"><fmt:message key="setup.pause.close" /></a>
</div>
<%@ include file="setup-footer.jsp" %>
<%--
- $RCSfile$
- $Revision: 1354 $
- $Date: 2005-05-16 17:50:50 -0700 (Mon, 16 May 2005) $
--%>
<%@ page import="org.jivesoftware.util.*" %>
<%@ taglib uri="http://java.sun.com/jstl/fmt_rt" prefix="fmt" %>
<%!
final String INCOMPLETE = "incomplete";
final String IN_PROGRESS = "in_progress";
final String DONE = "done";
%>
<% // Get sidebar values from the session:
String step1 = (String)session.getAttribute("jive.setup.sidebar.1");
String step2 = (String)session.getAttribute("jive.setup.sidebar.2");
String step3 = (String)session.getAttribute("jive.setup.sidebar.3");
String step4 = (String)session.getAttribute("jive.setup.sidebar.4");
if (step1 == null) { step1 = IN_PROGRESS; }
if (step2 == null) { step2 = INCOMPLETE; }
if (step3 == null) { step3 = INCOMPLETE; }
if (step4 == null) { step4 = INCOMPLETE; }
String[] items = {step1, step2, step3, step4};
String[] names = {
LocaleUtils.getLocalizedString("setup.sidebar.language"),
LocaleUtils.getLocalizedString("setup.sidebar.settings"),
LocaleUtils.getLocalizedString("setup.sidebar.datasource"),
LocaleUtils.getLocalizedString("setup.sidebar.admin")
};
String[] links = {
"setup-index.jsp",
"setup-host-settings.jsp",
"setup-datasource-settings.jsp",
"setup-admin-settings.jsp"
};
%>
<table bgcolor="#cccccc" cellpadding="0" cellspacing="0" border="0" width="200">
<tr><td>
<table bgcolor="#cccccc" cellpadding="3" cellspacing="1" border="0" width="200">
<tr bgcolor="#eeeeee">
<td align="center">
<span style="padding:6px">
<b><fmt:message key="setup.sidebar.title" /></b>
</span>
</td>
</tr>
<tr bgcolor="#ffffff">
<td>
<table cellpadding="5" cellspacing="0" border="0" width="100%">
<% for (int i=0; i<items.length; i++) { %>
<tr>
<% if (INCOMPLETE.equals(items[i])) { %>
<td width="1%"><img src="../images/bullet-red-14x14.gif" width="14" height="14" border="0"></td>
<td width="99%">
<%= names[i] %>
</td>
<% } else if (IN_PROGRESS.equals(items[i])) { %>
<td width="1%"><img src="../images/bullet-yellow-14x14.gif" width="14" height="14" border="0"></td>
<td width="99%">
<a href="<%= links[i] %>"><%= names[i] %></a>
</td>
<% } else { %>
<td width="1%"><img src="../images/bullet-green-14x14.gif" width="14" height="14" border="0"></td>
<td width="99%">
<a href="<%= links[i] %>"><%= names[i] %></a>
</td>
<% } %>
</tr>
<% } %>
<tr><td colspan="2"><br><br><br><br></td></tr>
</table>
</td>
</tr>
</table>
</td></tr>
</table>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment