qpid-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From oru...@apache.org
Subject svn commit: r1509778 [1/2] - in /qpid/trunk/qpid/java: broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/ broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/log/ broker-plugins/mana...
Date Fri, 02 Aug 2013 17:03:35 GMT
Author: orudyy
Date: Fri Aug  2 17:03:34 2013
New Revision: 1509778

URL: http://svn.apache.org/r1509778
Log:
QPID-5037: Move log viewer into a separate tab and add abilities to download logs and filter log entries in the logs table

Added:
    qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/log/
    qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/log/LogFileDetails.java
    qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/log/LogFileHelper.java
    qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/LogFileServlet.java
    qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/LogFileListingServlet.java
      - copied, changed from r1509428, qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/LogRecordsServlet.java
    qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/resources/grid/
    qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/resources/grid/showColumnDefDialog.html
    qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/resources/grid/showRowNumberLimitDialog.html
    qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/resources/images/auto-refresh.png
    qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/resources/images/download.png
    qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/resources/images/log-viewer.png
    qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/resources/images/refresh.png
    qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/common/grid/
    qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/common/grid/ColumnDefDialog.js
    qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/common/grid/EnhancedFilter.js
    qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/common/grid/EnhancedFilterTools.js
    qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/common/grid/FilterSummary.js
    qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/common/grid/GridUpdater.js
    qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/common/grid/RowNumberLimitDialog.js
    qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/logs/
    qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/logs/LogFileDownloadDialog.js
    qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/logs/LogViewer.js
    qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/resources/logs/
    qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/resources/logs/showLogFileDownloadDialog.html
    qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/resources/logs/showLogViewer.html
    qpid/trunk/qpid/java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/log/
    qpid/trunk/qpid/java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/log/LogFileHelperTest.java
    qpid/trunk/qpid/java/systests/src/main/java/org/apache/qpid/systest/rest/LogViewerTest.java
    qpid/trunk/qpid/java/systests/src/main/java/org/apache/qpid/systest/rest/acl/LogViewerACLTest.java
Modified:
    qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagement.java
    qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/LogRecordsServlet.java
    qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/resources/css/common.css
    qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/common/UpdatableStore.js
    qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/common/util.js
    qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/Broker.js
    qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/controller.js
    qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/resources/showBroker.html
    qpid/trunk/qpid/java/broker/etc/broker_example.acl
    qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/BrokerProperties.java
    qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/LogRecorder.java
    qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/SecurityManager.java
    qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/ObjectType.java
    qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/Operation.java
    qpid/trunk/qpid/java/systests/src/main/java/org/apache/qpid/systest/rest/LogRecordsRestTest.java
    qpid/trunk/qpid/java/systests/src/main/java/org/apache/qpid/systest/rest/RestTestHelper.java

Modified: qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagement.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagement.java?rev=1509778&r1=1509777&r2=1509778&view=diff
==============================================================================
--- qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagement.java (original)
+++ qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagement.java Fri Aug  2 17:03:34 2013
@@ -20,7 +20,6 @@
  */
 package org.apache.qpid.server.management.plugin;
 
-import java.io.File;
 import java.lang.reflect.Type;
 import java.net.SocketAddress;
 import java.util.Collection;
@@ -39,7 +38,9 @@ import org.apache.qpid.server.management
 import org.apache.qpid.server.management.plugin.filter.RedirectingAuthorisationFilter;
 import org.apache.qpid.server.management.plugin.servlet.DefinedFileServlet;
 import org.apache.qpid.server.management.plugin.servlet.FileServlet;
+import org.apache.qpid.server.management.plugin.servlet.LogFileServlet;
 import org.apache.qpid.server.management.plugin.servlet.rest.HelperServlet;
+import org.apache.qpid.server.management.plugin.servlet.rest.LogFileListingServlet;
 import org.apache.qpid.server.management.plugin.servlet.rest.LogRecordsServlet;
 import org.apache.qpid.server.management.plugin.servlet.rest.LogoutServlet;
 import org.apache.qpid.server.management.plugin.servlet.rest.MessageContentServlet;
@@ -312,6 +313,8 @@ public class HttpManagement extends Abst
         root.addServlet(new ServletHolder(FileServlet.INSTANCE), "*.txt");
         root.addServlet(new ServletHolder(FileServlet.INSTANCE), "*.xsl");
         root.addServlet(new ServletHolder(new HelperServlet()), "/rest/helper");
+        root.addServlet(new ServletHolder(new LogFileListingServlet()), "/rest/logfiles");
+        root.addServlet(new ServletHolder(new LogFileServlet()), "/rest/logfile");
 
         final SessionManager sessionManager = root.getSessionHandler().getSessionManager();
         sessionManager.setSessionCookie(JSESSIONID_COOKIE_PREFIX + lastPort);

Added: qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/log/LogFileDetails.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/log/LogFileDetails.java?rev=1509778&view=auto
==============================================================================
--- qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/log/LogFileDetails.java (added)
+++ qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/log/LogFileDetails.java Fri Aug  2 17:03:34 2013
@@ -0,0 +1,78 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.qpid.server.management.plugin.log;
+
+import java.io.File;
+
+public class LogFileDetails
+{
+    private String _name;
+    private File _location;
+    private String _mimeType;
+    private long _size;
+    private long _lastModified;
+    private String _appenderName;
+
+    public LogFileDetails(String name, String appenderName, File location, String mimeType, long fileSize, long lastUpdateTime)
+    {
+        super();
+        _name = name;
+        _location = location;
+        _mimeType = mimeType;
+        _size = fileSize;
+        _lastModified = lastUpdateTime;
+        _appenderName = appenderName;
+    }
+
+    public String getName()
+    {
+        return _name;
+    }
+
+    public File getLocation()
+    {
+        return _location;
+    }
+
+    public String getMimeType()
+    {
+        return _mimeType;
+    }
+
+    public long getSize()
+    {
+        return _size;
+    }
+
+    public long getLastModified()
+    {
+        return _lastModified;
+    }
+
+    public String getAppenderName()
+    {
+        return _appenderName;
+    }
+
+    @Override
+    public String toString()
+    {
+        return "LogFileDetails [name=" + _name + "]";
+    }
+
+}

Added: qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/log/LogFileHelper.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/log/LogFileHelper.java?rev=1509778&view=auto
==============================================================================
--- qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/log/LogFileHelper.java (added)
+++ qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/log/LogFileHelper.java Fri Aug  2 17:03:34 2013
@@ -0,0 +1,228 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.qpid.server.management.plugin.log;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipOutputStream;
+
+import org.apache.log4j.Appender;
+import org.apache.log4j.FileAppender;
+import org.apache.log4j.QpidCompositeRollingAppender;
+
+public class LogFileHelper
+{
+    public static final String GZIP_MIME_TYPE = "application/x-gzip";
+    public static final String TEXT_MIME_TYPE = "text/plain";
+    public static final String ZIP_MIME_TYPE = "application/zip";
+    public static final String GZIP_EXTENSION = ".gz";
+    private static final int BUFFER_LENGTH = 1024 * 4;
+    private Collection<Appender> _appenders;
+
+    public LogFileHelper(Collection<Appender> appenders)
+    {
+        super();
+        _appenders = appenders;
+    }
+
+    public List<LogFileDetails> findLogFileDetails(String[] requestedFiles)
+    {
+        List<LogFileDetails> logFiles = new ArrayList<LogFileDetails>();
+        Map<String, List<LogFileDetails>> cache = new HashMap<String, List<LogFileDetails>>();
+        for (int i = 0; i < requestedFiles.length; i++)
+        {
+            String[] paths = requestedFiles[i].split("/");
+            if (paths.length != 2)
+            {
+                throw new IllegalArgumentException("Log file name '" + requestedFiles[i] + "' does not include an appender name");
+            }
+
+            String appenderName = paths[0];
+            String fileName = paths[1];
+
+            List<LogFileDetails> appenderFiles = cache.get(appenderName);
+            if (appenderFiles == null)
+            {
+                Appender fileAppender = null;
+                for (Appender appender : _appenders)
+                {
+                    if (appenderName.equals(appender.getName()))
+                    {
+                        fileAppender = appender;
+                        break;
+                    }
+                }
+                if (fileAppender == null)
+                {
+                    continue;
+                }
+                appenderFiles = getAppenderFiles(fileAppender, true);
+                if (appenderFiles == null)
+                {
+                    continue;
+                }
+                cache.put(appenderName, appenderFiles);
+            }
+            for (LogFileDetails logFileDetails : appenderFiles)
+            {
+                if (logFileDetails.getName().equals(fileName))
+                {
+                    logFiles.add(logFileDetails);
+                }
+            }
+        }
+        return logFiles;
+    }
+
+    public List<LogFileDetails> getLogFileDetails(boolean includeLogFileLocation)
+    {
+        List<LogFileDetails> results = new ArrayList<LogFileDetails>();
+        for (Appender appender : _appenders)
+        {
+            List<LogFileDetails> appenderFiles = getAppenderFiles(appender, includeLogFileLocation);
+            if (appenderFiles != null)
+            {
+                results.addAll(appenderFiles);
+            }
+        }
+        return results;
+    }
+
+    public void writeLogFiles(List<LogFileDetails> logFiles, OutputStream os) throws IOException
+    {
+        ZipOutputStream out = new ZipOutputStream(os);
+        try
+        {
+            addLogFileEntries(logFiles, out);
+        }
+        finally
+        {
+            out.close();
+        }
+    }
+
+    public void writeLogFile(File file, OutputStream os) throws IOException
+    {
+        FileInputStream fis = new FileInputStream(file);
+        try
+        {
+            byte[] bytes = new byte[BUFFER_LENGTH];
+            int length = 1;
+            while ((length = fis.read(bytes)) != -1)
+            {
+                os.write(bytes, 0, length);
+            }
+        }
+        finally
+        {
+            fis.close();
+        }
+    }
+
+    private List<LogFileDetails> getAppenderFiles(Appender appender, boolean includeLogFileLocation)
+    {
+        if (appender instanceof QpidCompositeRollingAppender)
+        {
+            return listAppenderFiles((QpidCompositeRollingAppender) appender, includeLogFileLocation);
+        }
+        else if (appender instanceof FileAppender)
+        {
+            return listAppenderFiles((FileAppender) appender, includeLogFileLocation);
+        }
+        return null;
+    }
+
+    private List<LogFileDetails> listAppenderFiles(FileAppender appender, boolean includeLogFileLocation)
+    {
+        String appenderFilePath = appender.getFile();
+        File appenderFile = new File(appenderFilePath);
+        if (appenderFile.exists())
+        {
+            return listLogFiles(appenderFile.getParentFile(), appenderFile.getName(), appender.getName(), "", includeLogFileLocation);
+        }
+        return Collections.emptyList();
+    }
+
+    private List<LogFileDetails> listAppenderFiles(QpidCompositeRollingAppender appender, boolean includeLogFileLocation)
+    {
+        List<LogFileDetails> files = listAppenderFiles((FileAppender) appender, includeLogFileLocation);
+        String appenderFilePath = appender.getFile();
+        File appenderFile = new File(appenderFilePath);
+        File backupFolder = new File(appender.getBackupFilesToPath());
+        if (backupFolder.exists())
+        {
+            String backFolderName = backupFolder.getName() + "/";
+            List<LogFileDetails> backedUpFiles = listLogFiles(backupFolder, appenderFile.getName(), appender.getName(),
+                    backFolderName, includeLogFileLocation);
+            files.addAll(backedUpFiles);
+        }
+        return files;
+    }
+
+    private List<LogFileDetails> listLogFiles(File parent, String baseFileName, String appenderName, String relativePath,
+            boolean includeLogFileLocation)
+    {
+        List<LogFileDetails> files = new ArrayList<LogFileDetails>();
+        for (File file : parent.listFiles())
+        {
+            String name = file.getName();
+            if (name.startsWith(baseFileName))
+            {
+                files.add(new LogFileDetails(name, appenderName, includeLogFileLocation ? file : null, getMimeType(name), file.length(),
+                        file.lastModified()));
+            }
+        }
+        return files;
+    }
+
+    private String getMimeType(String fileName)
+    {
+        if (fileName.endsWith(GZIP_EXTENSION))
+        {
+            return GZIP_MIME_TYPE;
+        }
+        return TEXT_MIME_TYPE;
+    }
+
+    private void addLogFileEntries(List<LogFileDetails> files, ZipOutputStream out) throws IOException
+    {
+        for (LogFileDetails logFileDetails : files)
+        {
+            File file = logFileDetails.getLocation();
+            if (file.exists())
+            {
+                ZipEntry entry = new ZipEntry(logFileDetails.getAppenderName() + "/" + logFileDetails.getName());
+                entry.setSize(file.length());
+                out.putNextEntry(entry);
+                writeLogFile(file, out);
+                out.closeEntry();
+            }
+            out.flush();
+        }
+    }
+
+}

Added: qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/LogFileServlet.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/LogFileServlet.java?rev=1509778&view=auto
==============================================================================
--- qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/LogFileServlet.java (added)
+++ qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/LogFileServlet.java Fri Aug  2 17:03:34 2013
@@ -0,0 +1,105 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.qpid.server.management.plugin.servlet;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.text.SimpleDateFormat;
+import java.util.Collections;
+import java.util.Date;
+import java.util.List;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.log4j.LogManager;
+import org.apache.qpid.server.management.plugin.log.LogFileDetails;
+import org.apache.qpid.server.management.plugin.log.LogFileHelper;
+import org.apache.qpid.server.management.plugin.servlet.rest.AbstractServlet;
+
+public class LogFileServlet extends AbstractServlet
+{
+    private static final long serialVersionUID = 1L;
+
+    public static final String LOGS_FILE_NAME = "qpid-logs-%s.zip";
+    public static final String DATE_FORMAT = "yyyy-MM-dd-mmHHss";
+
+    @SuppressWarnings("unchecked")
+    private LogFileHelper _helper = new LogFileHelper(Collections.list(LogManager.getRootLogger().getAllAppenders()));
+
+    @Override
+    protected void doGetWithSubjectAndActor(HttpServletRequest request, HttpServletResponse response) throws IOException,
+            ServletException
+    {
+        response.setHeader("Cache-Control", "no-cache");
+        response.setHeader("Pragma", "no-cache");
+        response.setDateHeader("Expires", 0);
+
+        if (!getBroker().getSecurityManager().authoriseLogsAccess())
+        {
+            response.sendError(HttpServletResponse.SC_FORBIDDEN, "Log files download is denied");
+            return;
+        }
+
+        String[] requestedFiles = request.getParameterValues("l");
+
+        if (requestedFiles == null || requestedFiles.length == 0)
+        {
+            response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
+            return;
+        }
+
+        List<LogFileDetails> logFiles = null;
+
+        try
+        {
+            logFiles = _helper.findLogFileDetails(requestedFiles);
+        }
+        catch(IllegalArgumentException e)
+        {
+            response.sendError(HttpServletResponse.SC_BAD_REQUEST);
+            return;
+        }
+
+        if (logFiles.size() == 0)
+        {
+            response.sendError(HttpServletResponse.SC_NOT_FOUND);
+            return;
+        }
+
+        String fileName = String.format(LOGS_FILE_NAME, new SimpleDateFormat(DATE_FORMAT).format(new Date()));
+        response.setStatus(HttpServletResponse.SC_OK);
+        response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
+        response.setContentType(LogFileHelper.ZIP_MIME_TYPE);
+
+        OutputStream os = response.getOutputStream();
+        try
+        {
+            _helper.writeLogFiles(logFiles, os);
+        }
+        finally
+        {
+            if (os != null)
+            {
+                os.close();
+            }
+        }
+    }
+
+}

Copied: qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/LogFileListingServlet.java (from r1509428, qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/LogRecordsServlet.java)
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/LogFileListingServlet.java?p2=qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/LogFileListingServlet.java&p1=qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/LogRecordsServlet.java&r1=1509428&r2=1509778&rev=1509778&view=diff
==============================================================================
--- qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/LogRecordsServlet.java (original)
+++ qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/LogFileListingServlet.java Fri Aug  2 17:03:34 2013
@@ -14,65 +14,55 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package org.apache.qpid.server.management.plugin.servlet.rest;
 
 import java.io.IOException;
 import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.LinkedHashMap;
+import java.util.Collections;
 import java.util.List;
-import java.util.Map;
+
 import javax.servlet.ServletException;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
-import org.apache.qpid.server.logging.LogRecorder;
+
+import org.apache.log4j.LogManager;
+import org.apache.qpid.server.management.plugin.log.LogFileDetails;
+import org.apache.qpid.server.management.plugin.log.LogFileHelper;
 import org.codehaus.jackson.map.ObjectMapper;
 import org.codehaus.jackson.map.SerializationConfig;
 
-public class LogRecordsServlet extends AbstractServlet
+public class LogFileListingServlet extends AbstractServlet
 {
-    public LogRecordsServlet()
-    {
-        super();
-    }
+    private static final long serialVersionUID = 1L;
+
+    @SuppressWarnings("unchecked")
+    private LogFileHelper _helper = new LogFileHelper(Collections.list(LogManager.getRootLogger().getAllAppenders()));
 
     @Override
-    protected void doGetWithSubjectAndActor(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
+    protected void doGetWithSubjectAndActor(HttpServletRequest request, HttpServletResponse response) throws IOException,
+            ServletException
     {
-        response.setContentType("application/json");
-        response.setStatus(HttpServletResponse.SC_OK);
-
-        response.setHeader("Cache-Control","no-cache");
-        response.setHeader("Pragma","no-cache");
-        response.setDateHeader ("Expires", 0);
+        response.setHeader("Cache-Control", "no-cache");
+        response.setHeader("Pragma", "no-cache");
+        response.setDateHeader("Expires", 0);
 
-        List<Map<String,Object>> logRecords = new ArrayList<Map<String, Object>>();
-
-        LogRecorder logRecorder = getBroker().getLogRecorder();
-        for(LogRecorder.Record record : logRecorder)
+        if (!getBroker().getSecurityManager().authoriseLogsAccess())
         {
-            logRecords.add(logRecordToObject(record));
+            response.sendError(HttpServletResponse.SC_FORBIDDEN, "Log files download is denied");
+            return;
         }
 
+        List<LogFileDetails> logFiles = _helper.getLogFileDetails(false);
+        response.setContentType("application/json");
+        response.setStatus(HttpServletResponse.SC_OK);
+
         final PrintWriter writer = response.getWriter();
         ObjectMapper mapper = new ObjectMapper();
         mapper.configure(SerializationConfig.Feature.INDENT_OUTPUT, true);
-        mapper.writeValue(writer, logRecords);
+        mapper.writeValue(writer, logFiles);
 
         response.setStatus(HttpServletResponse.SC_OK);
-
-    }
-
-    private Map<String, Object> logRecordToObject(LogRecorder.Record record)
-    {
-        Map<String, Object> recordMap = new LinkedHashMap<String, Object>();
-        recordMap.put("id",record.getId());
-        recordMap.put("timestamp", record.getTimestamp());
-        recordMap.put("level", record.getLevel());
-        recordMap.put("thread", record.getThreadName());
-        recordMap.put("logger", record.getLogger());
-        recordMap.put("message", record.getMessage());
-        return recordMap;
     }
 
 }

Modified: qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/LogRecordsServlet.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/LogRecordsServlet.java?rev=1509778&r1=1509777&r2=1509778&view=diff
==============================================================================
--- qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/LogRecordsServlet.java (original)
+++ qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/LogRecordsServlet.java Fri Aug  2 17:03:34 2013
@@ -31,6 +31,10 @@ import org.codehaus.jackson.map.Serializ
 
 public class LogRecordsServlet extends AbstractServlet
 {
+    private static final long serialVersionUID = 2L;
+
+    public static final String PARAM_LAST_LOG_ID = "lastLogId";
+
     public LogRecordsServlet()
     {
         super();
@@ -46,12 +50,31 @@ public class LogRecordsServlet extends A
         response.setHeader("Pragma","no-cache");
         response.setDateHeader ("Expires", 0);
 
+        if (!getBroker().getSecurityManager().authoriseLogsAccess())
+        {
+            response.sendError(HttpServletResponse.SC_FORBIDDEN, "Broker logs access is denied");
+            return;
+        }
+
+        long lastLogId = 0;
+        try
+        {
+            lastLogId = Long.parseLong(request.getParameter(PARAM_LAST_LOG_ID));
+        }
+        catch(Exception e)
+        {
+            // ignore null and incorrect parameter values
+        }
+
         List<Map<String,Object>> logRecords = new ArrayList<Map<String, Object>>();
 
         LogRecorder logRecorder = getBroker().getLogRecorder();
         for(LogRecorder.Record record : logRecorder)
         {
-            logRecords.add(logRecordToObject(record));
+            if (record.getId() > lastLogId)
+            {
+                logRecords.add(logRecordToObject(record));
+            }
         }
 
         final PrintWriter writer = response.getWriter();

Modified: qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/resources/css/common.css
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/resources/css/common.css?rev=1509778&r1=1509777&r2=1509778&view=diff
==============================================================================
--- qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/resources/css/common.css (original)
+++ qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/resources/css/common.css Fri Aug  2 17:03:34 2013
@@ -92,4 +92,60 @@ div .messages {
 
 .formLabel-labelCell {
   font-weight: bold;
-}
\ No newline at end of file
+}
+
+.columnDefDialogButtonIcon {
+  background: url("../dojo/dojox/grid/enhanced/resources/images/sprite_icons.png") no-repeat;
+    background-position: -260px 2px;
+    width: 14px;
+    height: 14px;
+}
+
+.logViewerIcon {
+  background: url("../images/log-viewer.png") no-repeat;
+    width: 14px;
+    height: 16px;
+}
+
+.downloadLogsIcon {
+  background: url("../images/download.png") no-repeat;
+    width: 14px;
+    height: 14px;
+}
+
+.dojoxGridFBarClearFilterButtontnIcon
+{
+    background: url("../dojo/dojox/grid/enhanced/resources/images/sprite_icons.png") no-repeat;
+    background-position: -120px -18px;
+    width: 14px;
+    height: 14px;
+}
+
+.rowNumberLimitIcon
+{
+    background: url("../dojo/dojox/grid/enhanced/resources/images/sprite_icons.png") no-repeat;
+    background-position: -240px -18px;
+    width: 14px;
+    height: 14px;
+}
+
+.gridRefreshIcon
+{
+    background: url("../images/refresh.png") no-repeat;
+    width: 16px;
+    height: 16px;
+}
+
+.gridAutoRefreshIcon
+{
+    background: url("../images/auto-refresh.png") no-repeat;
+    width: 16px;
+    height: 16px;
+}
+
+.redBackground tr{ background-color:#ffdcd7 !important; background-image: none !important;}
+.yellowBackground tr{background-color:#fbfddf !important; background-image: none !important;}
+.grayBackground tr{background-color:#eeeeee !important; background-image: none !important;}
+.dojoxGridRowOdd.grayBackground tr{ background-color:#e9e9e9 !important; background-image: none !important;}
+.dojoxGridRowOdd.yellowBackground tr{background-color:#fafdd5 !important; background-image: none !important;}
+.dojoxGridRowOdd.redBackground tr{background-color:#f4c1c1 !important; background-image: none !important;}
\ No newline at end of file

Added: qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/resources/grid/showColumnDefDialog.html
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/resources/grid/showColumnDefDialog.html?rev=1509778&view=auto
==============================================================================
--- qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/resources/grid/showColumnDefDialog.html (added)
+++ qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/resources/grid/showColumnDefDialog.html Fri Aug  2 17:03:34 2013
@@ -0,0 +1,32 @@
+<!--
+ -
+ - Licensed to the Apache Software Foundation (ASF) under one
+ - or more contributor license agreements.  See the NOTICE file
+ - distributed with this work for additional information
+ - regarding copyright ownership.  The ASF licenses this file
+ - to you 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.
+ -
+ -->
+<div>
+    <div>
+        <div>Select columns to display:</div>
+        <div class="columnList"></div>
+    </div>
+    <div class="dijitDialogPaneActionBar">
+        <button value="Display" data-dojo-type="dijit.form.Button"
+            class="displayButton" data-dojo-props="label: 'Display' "></button>
+        <button value="Cancel" data-dojo-type="dijit.form.Button" data-dojo-props="label: 'Cancel'"
+            class="cancelButton"></button>
+    </div>
+</div>

Added: qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/resources/grid/showRowNumberLimitDialog.html
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/resources/grid/showRowNumberLimitDialog.html?rev=1509778&view=auto
==============================================================================
--- qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/resources/grid/showRowNumberLimitDialog.html (added)
+++ qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/resources/grid/showRowNumberLimitDialog.html Fri Aug  2 17:03:34 2013
@@ -0,0 +1,33 @@
+<!--
+ -
+ - Licensed to the Apache Software Foundation (ASF) under one
+ - or more contributor license agreements.  See the NOTICE file
+ - distributed with this work for additional information
+ - regarding copyright ownership.  The ASF licenses this file
+ - to you 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.
+ -
+ -->
+<div>
+    <div>
+        <div>Set the maximum number of rows to cache and display:</div>
+        <input class="rowNumberLimit" data-dojo-type="dijit.form.NumberSpinner"
+        data-dojo-props="invalidMessage: 'Invalid value', required: true, smallDelta: 1,mconstraints: {min:1,max:65535,places:0, pattern: '#####'}, label: 'Maximum number of rows:', name: 'rowNumberLimit'"></input>
+    </div>
+    <div class="dijitDialogPaneActionBar">
+        <button value="Submit" data-dojo-type="dijit.form.Button"
+            class="submitButton" data-dojo-props="label: 'Submit' "></button>
+        <button value="Cancel" data-dojo-type="dijit.form.Button" data-dojo-props="label: 'Cancel'"
+            class="cancelButton"></button>
+    </div>
+</div>

Added: qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/resources/images/auto-refresh.png
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/resources/images/auto-refresh.png?rev=1509778&view=auto
==============================================================================
Files qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/resources/images/auto-refresh.png (added) and qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/resources/images/auto-refresh.png Fri Aug  2 17:03:34 2013 differ

Added: qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/resources/images/download.png
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/resources/images/download.png?rev=1509778&view=auto
==============================================================================
Files qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/resources/images/download.png (added) and qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/resources/images/download.png Fri Aug  2 17:03:34 2013 differ

Added: qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/resources/images/log-viewer.png
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/resources/images/log-viewer.png?rev=1509778&view=auto
==============================================================================
Files qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/resources/images/log-viewer.png (added) and qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/resources/images/log-viewer.png Fri Aug  2 17:03:34 2013 differ

Added: qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/resources/images/refresh.png
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/resources/images/refresh.png?rev=1509778&view=auto
==============================================================================
Files qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/resources/images/refresh.png (added) and qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/resources/images/refresh.png Fri Aug  2 17:03:34 2013 differ

Modified: qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/common/UpdatableStore.js
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/common/UpdatableStore.js?rev=1509778&r1=1509777&r2=1509778&view=diff
==============================================================================
--- qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/common/UpdatableStore.js (original)
+++ qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/common/UpdatableStore.js Fri Aug  2 17:03:34 2013
@@ -23,12 +23,13 @@ define(["dojo/store/Memory",
 				"dojo/data/ObjectStore",
 				"dojo/store/Observable"], function (Memory, DataGrid, ObjectStore, Observable) {
 
-    function UpdatableStore( data, divName, structure, func, props, Grid ) {
+    function UpdatableStore( data, divName, structure, func, props, Grid, notObservable ) {
 
         var that = this;
         var GridType = DataGrid;
 
-        that.store = Observable(Memory({data: data, idProperty: "id"}));
+        that.memoryStore = new Memory({data: data, idProperty: "id"});
+        that.store = notObservable? that.memoryStore : new Observable(that.memoryStore);
         that.dataStore = ObjectStore({objectStore: that.store});
 
         var gridProperties = {  store: that.dataStore,
@@ -63,7 +64,7 @@ define(["dojo/store/Memory",
 
     UpdatableStore.prototype.update = function(data)
     {
-
+        var changed = false;
         var store = this.store;
         var theItem;
 
@@ -78,7 +79,7 @@ define(["dojo/store/Memory",
                                          }
                                      }
                                      store.remove(object.id);
-
+                                     changed = true;
                                  });
 
         // iterate over data...
@@ -91,20 +92,84 @@ define(["dojo/store/Memory",
                             if(theItem[ propName ] != data[i][ propName ]) {
                                 theItem[ propName ] = data[i][ propName ];
                                 modified = true;
+                                changed = true;
                             }
                         }
                     }
                     if(modified) {
                         // ... check attributes for updates
                         store.notify(theItem, data[i].id);
+                        changed = true;
                     }
                 } else {
                     // ,,, if not in the store then add
                     store.put(data[i]);
+                    changed = true;
                 }
             }
         }
 
+        return changed;
+    };
+
+    function removeItemsFromArray(items, numberToRemove)
+    {
+      if (items)
+      {
+        if (numberToRemove > 0 && items.length > 0)
+        {
+          if (numberToRemove >= items.length)
+          {
+            numberToRemove = numberToRemove - items.length;
+            items.length = 0
+          }
+          else
+          {
+            items.splice(0, numberToRemove);
+            numberToRemove = 0;
+          }
+        }
+      }
+      return numberToRemove;
+    };
+
+    UpdatableStore.prototype.append = function(data, limit)
+    {
+        var changed = false;
+        var items = this.memoryStore.data;
+
+        if (limit)
+        {
+          var totalSize = items.length + (data ? data.length : 0);
+          var numberToRemove = totalSize - limit;
+
+          if (numberToRemove > 0)
+          {
+            changed = true;
+            numberToRemove = removeItemsFromArray(items, numberToRemove);
+            if (numberToRemove > 0)
+            {
+              removeItemsFromArray(data, numberToRemove);
+            }
+          }
+        }
+
+        if (data && data.length > 0)
+        {
+          changed = true;
+          items.push.apply(items, data);
+        }
+
+        this.memoryStore.setData(items);
+        return changed;
+    };
+
+    UpdatableStore.prototype.close = function()
+    {
+        this.dataStore.close();
+        this.dataStore = null;
+        this.store = null;
+        this.memoryStore = null;
     };
     return UpdatableStore;
 });

Added: qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/common/grid/ColumnDefDialog.js
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/common/grid/ColumnDefDialog.js?rev=1509778&view=auto
==============================================================================
--- qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/common/grid/ColumnDefDialog.js (added)
+++ qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/common/grid/ColumnDefDialog.js Fri Aug  2 17:03:34 2013
@@ -0,0 +1,140 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ *
+ */
+
+define([
+  "dojo/_base/declare",
+  "dojo/_base/event",
+  "dojo/_base/array",
+  "dojo/_base/lang",
+  "dojo/parser",
+  "dojo/dom-construct",
+  "dojo/query",
+  "dijit/registry",
+  "dijit/form/Button",
+  "dijit/form/CheckBox",
+  "dojox/grid/enhanced/plugins/Dialog",
+  "dojo/text!../../../grid/showColumnDefDialog.html",
+  "dojo/domReady!"
+], function(declare, event, array, lang, parser, dom, query, registry, Button, CheckBox, Dialog, template ){
+
+
+return declare("qpid.common.grid.ColumnDefDialog", null, {
+
+  grid: null,
+  containerNode: null,
+  _columns: [],
+  _dialog: null,
+
+  constructor: function(args){
+      var grid = this.grid = args.grid;
+
+      this.containerNode = dom.create("div", {innerHTML: template});
+      parser.parse(this.containerNode);
+
+      var submitButton = registry.byNode(query(".displayButton", this.containerNode)[0]);
+      this.closeButton = registry.byNode(query(".cancelButton", this.containerNode)[0]);
+      var columnsContainer = query(".columnList", this.containerNode)[0];
+
+      this._buildColumnWidgets(columnsContainer);
+
+      this._dialog = new Dialog({
+        "refNode": this.grid.domNode,
+        "title": "Grid Columns",
+        "content": this.containerNode
+      });
+
+      var self = this;
+      submitButton.on("click", function(e){self._onColumnsSelect(e); });
+      this.closeButton.on("click", function(e){self._dialog.hide(); });
+
+      this._dialog.startup();
+    },
+
+    destroy: function(){
+      this._dialog.destroyRecursive();
+      this._dialog = null;
+      this.grid = null;
+      this.containerNode = null;
+      this._columns = null;
+    },
+
+    showDialog: function(){
+      this._initColumnWidgets();
+      this._dialog.show();
+    },
+
+    _initColumnWidgets: function()
+    {
+      var cells = this.grid.layout.cells;
+      for(var i in cells)
+      {
+        var cell = cells[i];
+        this._columns[cell.name].checked = !cell.hidden;
+      }
+    },
+
+    _onColumnsSelect: function(evt){
+      event.stop(evt);
+      var grid = this.grid;
+      grid.beginUpdate();
+      var cells = grid.layout.cells;
+      try
+      {
+        for(var i in cells)
+        {
+          var cell = cells[i];
+          var widget = this._columns[cell.name];
+          grid.layout.setColumnVisibility(i, widget.checked);
+        }
+      }
+      finally
+      {
+        grid.endUpdate();
+        this._dialog.hide();
+      }
+    },
+
+    _buildColumnWidgets: function(columnsContainer)
+    {
+      var cells = this.grid.layout.cells;
+      for(var i in cells)
+      {
+        var cell = cells[i];
+        var widget = new dijit.form.CheckBox({
+          required: false,
+          checked: !cell.hidden,
+          label: cell.name,
+          name: this.grid.id + "_cchb_ " + i
+        });
+
+        this._columns[cell.name] = widget;
+
+        var div = dom.create("div");
+        div.appendChild(widget.domNode);
+        div.appendChild(dom.create("span", {innerHTML: cell.name}));
+
+        columnsContainer.appendChild(div);
+      }
+    }
+
+  });
+
+});

Added: qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/common/grid/EnhancedFilter.js
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/common/grid/EnhancedFilter.js?rev=1509778&view=auto
==============================================================================
--- qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/common/grid/EnhancedFilter.js (added)
+++ qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/common/grid/EnhancedFilter.js Fri Aug  2 17:03:34 2013
@@ -0,0 +1,229 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ *
+ */
+
+define([
+  "dojo/_base/declare",
+  "dojo/_base/lang",
+  "dojo/_base/array",
+  "dijit/Toolbar",
+  "dojox/grid/enhanced/_Plugin",
+  "dojox/grid/enhanced/plugins/Dialog",
+  "dojox/grid/enhanced/plugins/filter/FilterLayer",
+  "dojox/grid/enhanced/plugins/filter/FilterDefDialog",
+  "dojox/grid/enhanced/plugins/filter/FilterStatusTip",
+  "dojox/grid/enhanced/plugins/filter/ClearFilterConfirm",
+  "dojox/grid/EnhancedGrid",
+  "dojo/i18n!dojox/grid/enhanced/nls/Filter",
+  "qpid/common/grid/EnhancedFilterTools"
+], function(declare, lang, array, Toolbar, _Plugin,
+    Dialog, FilterLayer, FilterDefDialog, FilterStatusTip, ClearFilterConfirm, EnhancedGrid, nls, EnhancedFilterTools){
+
+  // override CriteriaBox#_getColumnOptions to show criteria for hidden columns with EnhancedFilter
+  dojo.extend(dojox.grid.enhanced.plugins.filter.CriteriaBox, {
+          _getColumnOptions: function(){
+                  var colIdx = this.dlg.curColIdx >= 0 ? String(this.dlg.curColIdx) : "anycolumn";
+                  var filterHidden = this.plugin.filterHidden;
+                  return array.map(array.filter(this.plugin.grid.layout.cells, function(cell){
+                          return !(cell.filterable === false || (!filterHidden && cell.hidden));
+                  }), function(cell){
+                          return {
+                                  label: cell.name || cell.field,
+                                  value: String(cell.index),
+                                  selected: colIdx == String(cell.index)
+                          };
+                  });
+          }
+  });
+
+  // Enhanced filter has extra functionality for refreshing, limiting rows, displaying/hiding columns in the grid
+  var EnhancedFilter = declare("qpid.common.grid.EnhancedFilter", _Plugin, {
+    // summary:
+    //    Accept the same plugin parameters as dojox.grid.enhanced.plugins.Filter and the following:
+    //
+    //    filterHidden: boolean:
+    //    Whether to display filtering criteria for hidden columns. Default to true.
+    //
+    //    defaulGridRowLimit: int:
+    //    Default limit for numbers of items to cache in the gris dtore
+    //
+    //    disableFiltering: boolean:
+    //    Whether to disable a filtering including filter button, clear filter button and filter summary.
+    //
+    //    toolbar: dijit.Toolbar:
+    //    An instance of toolbar to add the enhanced filter widgets.
+
+
+    // name: String
+    //    plugin name
+    name: "enhancedFilter",
+
+    // filterHidden: Boolean
+    //    whether to filter hidden columns
+    filterHidden: true,
+
+    constructor: function(grid, args){
+      // summary:
+      //    See constructor of dojox.grid.enhanced._Plugin.
+      this.grid = grid;
+      this.nls = nls;
+
+      args = this.args = lang.isObject(args) ? args : {};
+      if(typeof args.ruleCount != 'number' || args.ruleCount < 0){
+        args.ruleCount = 0;
+      }
+      var rc = this.ruleCountToConfirmClearFilter = args.ruleCountToConfirmClearFilter;
+      if(rc === undefined){
+        this.ruleCountToConfirmClearFilter = 5;
+      }
+
+      if (args.filterHidden){
+          this.filterHidden = args.filterHidden;
+      }
+      this.defaulGridRowLimit = args.defaulGridRowLimit;
+      this.disableFiltering = args.disableFiltering;
+
+      //Install UI components
+      var obj = { "plugin": this };
+
+      this.filterBar = ( args.toolbar && args.toolbar instanceof dijit.Toolbar) ? args.toolbar: new Toolbar();
+
+      if (!this.disableFiltering)
+      {
+          //Install filter layer
+          this._wrapStore();
+
+          this.clearFilterDialog = new Dialog({
+            refNode: this.grid.domNode,
+            title: this.nls["clearFilterDialogTitle"],
+            content: new ClearFilterConfirm(obj)
+          });
+
+          this.filterDefDialog = new FilterDefDialog(obj);
+
+          nls["statusTipTitleNoFilter"] = "Filter is not set";
+          nls["statusTipMsg"] = "Click on 'Set Filter' button to specify filtering conditions";
+          this.filterStatusTip = new FilterStatusTip(obj);
+
+          var self = this;
+          var toggleClearFilterBtn = function (arg){ self.enhancedFilterTools.toggleClearFilterBtn(arg); };
+
+          this.filterBar.toggleClearFilterBtn = toggleClearFilterBtn;
+
+          this.grid.isFilterBarShown = function (){return true};
+
+          this.connect(this.grid.layer("filter"), "onFilterDefined", function(filter){
+            toggleClearFilterBtn(true);
+          });
+
+          //Expose the layer event to grid.
+          grid.onFilterDefined = function(){};
+          this.connect(grid.layer("filter"), "onFilterDefined", function(filter){
+              grid.onFilterDefined(grid.getFilter(), grid.getFilterRelation());
+          });
+      }
+
+      // add extra buttons into toolbar
+      this.enhancedFilterTools = new EnhancedFilterTools({
+          grid: grid,
+          toolbar: this.filterBar,
+          filterStatusTip: this.filterStatusTip,
+          clearFilterDialog: this.clearFilterDialog,
+          filterDefDialog: this.filterDefDialog,
+          defaulGridRowLimit: this.defaulGridRowLimit,
+          disableFiltering: this.disableFiltering,
+          nls: nls
+        });
+
+      this.filterBar.placeAt(this.grid.viewsHeaderNode, "before");
+      this.filterBar.startup();
+
+    },
+
+    destroy: function(){
+      this.inherited(arguments);
+      try
+      {
+        if (this.grid)
+        {
+          this.grid.unwrap("filter");
+          this.grid = null;
+        }
+        if (this.filterBar)
+        {
+          this.filterBar.destroyRecursive();
+          this.filterBar = null;
+        }
+        if (this.enhancedFilterTools)
+        {
+          this.enhancedFilterTools.destroy();
+          this.enhancedFilterTools = null;
+        }
+        if (this.clearFilterDialog)
+        {
+          this.clearFilterDialog.destroyRecursive();
+          this.clearFilterDialog = null;
+        }
+        if (this.filterStatusTip)
+        {
+          this.filterStatusTip.destroy();
+          this.filterStatusTip = null;
+        }
+        if (this.filterDefDialog)
+        {
+          this.filterDefDialog.destroy();
+          this.filterDefDialog = null;
+        }
+        this.args = null;
+
+      }catch(e){
+        console.warn("Filter.destroy() error:",e);
+      }
+    },
+
+    _wrapStore: function(){
+      var g = this.grid;
+      var args = this.args;
+      var filterLayer = args.isServerSide ? new FilterLayer.ServerSideFilterLayer(args) :
+        new FilterLayer.ClientSideFilterLayer({
+          cacheSize: args.filterCacheSize,
+          fetchAll: args.fetchAllOnFirstFilter,
+          getter: this._clientFilterGetter
+        });
+      FilterLayer.wrap(g, "_storeLayerFetch", filterLayer);
+
+      this.connect(g, "_onDelete", lang.hitch(filterLayer, "invalidate"));
+    },
+
+    onSetStore: function(store){
+      this.filterDefDialog.clearFilter(true);
+    },
+
+    _clientFilterGetter: function(/* data item */ datarow,/* cell */cell, /* int */rowIndex){
+      return cell.get(rowIndex, datarow);
+    }
+
+  });
+
+  EnhancedGrid.registerPlugin(EnhancedFilter);
+
+  return EnhancedFilter;
+
+});

Added: qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/common/grid/EnhancedFilterTools.js
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/common/grid/EnhancedFilterTools.js?rev=1509778&view=auto
==============================================================================
--- qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/common/grid/EnhancedFilterTools.js (added)
+++ qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/common/grid/EnhancedFilterTools.js Fri Aug  2 17:03:34 2013
@@ -0,0 +1,270 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ *
+ */
+
+define([
+  "dojo/_base/declare",
+  "dojo/_base/event",
+  "dijit/form/Button",
+  "dijit/form/ToggleButton",
+  "qpid/common/grid/RowNumberLimitDialog",
+  "qpid/common/grid/ColumnDefDialog",
+  "qpid/common/grid/FilterSummary"
+], function(declare, event, Button, ToggleButton, RowNumberLimitDialog, ColumnDefDialog, FilterSummary){
+
+  var _stopEvent = function (evt){
+    try{
+      if(evt && evt.preventDefault){
+        event.stop(evt);
+      }
+      }catch(e){}
+  };
+
+  return declare("qpid.common.grid.EnhancedFilterTools", null, {
+
+    grid: null,
+    filterBar: null,
+    filterStatusTip: null,
+    clearFilterDialog: null,
+    filterDefDialog: null,
+
+    columnDefDialog: null,
+    columnDefButton: null,
+    filterDefButton: null,
+    clearFilterButton: null,
+    filterSummary: null,
+    setRowNumberLimitButton: null,
+    setRowNumberLimitDialog: null,
+    refreshButton: null,
+    autoRefreshButton: null,
+
+    constructor: function(params)
+    {
+      this.inherited(arguments);
+
+      this.filterBar = params.toolbar;
+      this.grid = params.grid;
+      this.filterStatusTip= params.filterStatusTip;
+      this.clearFilterDialog = params.clearFilterDialog;
+      this.filterDefDialog = params.filterDefDialog;
+
+      this._addRefreshButtons();
+      this._addRowLimitButton(params.defaulGridRowLimit);
+      this._addColumnsButton();
+
+      if (!params.disableFiltering)
+      {
+          this._addFilteringTools(params.nls);
+      }
+    },
+
+    toggleClearFilterBtn: function(clearFlag)
+    {
+      var filterLayer = this.grid.layer("filter");
+      var filterSet = filterLayer && filterLayer.filterDef && filterLayer.filterDef();
+      this.clearFilterButton.set("disabled", !filterSet);
+    },
+
+    destroy: function()
+    {
+      this.inherited(arguments);
+
+      if (this.columnDefDialog)
+      {
+        this.columnDefDialog.destroy();
+        this.columnDefDialog = null;
+      }
+      if (this.columnDefButton)
+      {
+        this.columnDefButton.destroy();
+        this.columnDefButton = null;
+      }
+      if (this.filterDefButton)
+      {
+        this.filterDefButton.destroy();
+        this.filterDefButton = null;
+      }
+      if (this.clearFilterButton)
+      {
+        this.clearFilterButton.destroy();
+        this.clearFilterButton = null;
+      }
+      if (this.filterSummary)
+      {
+        this.filterSummary.destroy();
+        this.filterSummary = null;
+      }
+      if (this.setRowNumberLimitButton)
+      {
+        this.setRowNumberLimitButton.destroy();
+        this.setRowNumberLimitButton = null;
+      }
+      if (this.setRowNumberLimitDialog)
+      {
+        this.setRowNumberLimitDialog.destroy();
+        this.setRowNumberLimitDialog = null;
+      }
+      if (this.refreshButton)
+      {
+        this.refreshButton.destroy();
+        this.refreshButton = null;
+      }
+      if (this.autoRefreshButton)
+      {
+        this.autoRefreshButton.destroy();
+        this.autoRefreshButton = null;
+      }
+
+      this.grid = null;
+      this.filterBar = null;
+      this.filterStatusTip = null;
+      this.clearFilterDialog = null;
+      this.filterDefDialog = null;
+    },
+
+    _addRefreshButtons: function()
+    {
+      var self = this;
+      this.refreshButton = new dijit.form.Button({
+        label: "Refresh",
+        type: "button",
+        iconClass: "gridRefreshIcon",
+        title: "Manual Refresh"
+      });
+
+      this.autoRefreshButton = new dijit.form.ToggleButton({
+        label: "Auto Refresh",
+        type: "button",
+        iconClass: "gridAutoRefreshIcon",
+        title: "Auto Refresh"
+      });
+
+      this.autoRefreshButton.on("change", function(value){
+          self.grid.updater.updatable=value;
+          self.refreshButton.set("disabled", value);
+      });
+
+      this.refreshButton.on("click", function(value){
+          self.grid.updater.performUpdate();
+      });
+
+      this.filterBar.addChild(this.autoRefreshButton);
+      this.filterBar.addChild(this.refreshButton);
+    },
+
+    _addRowLimitButton: function(defaulGridRowLimit)
+    {
+      var self = this;
+      this.setRowNumberLimitButton = new dijit.form.Button({
+        label: "Set Row Limit",
+        type: "button",
+        iconClass: "rowNumberLimitIcon",
+        title: "Set Row Number Limit"
+      });
+      this.setRowNumberLimitButton.set("title", "Set Row Number Limit (Current: " + defaulGridRowLimit +")");
+
+      this.setRowNumberLimitDialog = new RowNumberLimitDialog(this.grid.domNode, function(newLimit){
+        if (newLimit > 0 && self.grid.updater.appendLimit != newLimit )
+        {
+          self.grid.updater.appendLimit = newLimit;
+          self.grid.updater.performRefresh([]);
+          self.setRowNumberLimitButton.set("title", "Set Row Number Limit (Current: " + newLimit +")");
+        }
+      });
+
+      this.setRowNumberLimitButton.on("click", function(evt){
+        self.setRowNumberLimitDialog.showDialog(self.grid.updater.appendLimit);
+      });
+
+      this.filterBar.addChild(this.setRowNumberLimitButton);
+    },
+
+    _addColumnsButton: function()
+    {
+      var self = this;
+      this.columnDefDialog = new ColumnDefDialog({grid: this.grid});
+
+      this.columnDefButton = new dijit.form.Button({
+        label: "Display Columns",
+        type: "button",
+        iconClass: "columnDefDialogButtonIcon",
+        title: "Show/Hide Columns"
+      });
+
+      this.columnDefButton.on("click", function(e){
+        _stopEvent(e);
+        self.columnDefDialog.showDialog();
+      });
+
+      this.filterBar.addChild(this.columnDefButton);
+    },
+
+    _addFilteringTools: function(nls)
+    {
+      var self = this;
+
+      this.filterDefButton = new dijit.form.Button({
+        "class": "dojoxGridFBarBtn",
+        label: "Set Filter",
+        iconClass: "dojoxGridFBarDefFilterBtnIcon",
+        showLabel: "true",
+        title: "Define filter"
+      });
+
+      this.clearFilterButton = new dijit.form.Button({
+        "class": "dojoxGridFBarBtn",
+        label: "Clear filter",
+        iconClass: "dojoxGridFBarClearFilterButtontnIcon",
+        showLabel: "true",
+        title: "Clear filter",
+        disabled: true
+      });
+
+
+      this.filterDefButton.on("click", function(e){
+        _stopEvent(e);
+        self.filterDefDialog.showDialog();
+      });
+
+      this.clearFilterButton.on("click", function(e){
+        _stopEvent(e);
+        if (self.ruleCountToConfirmClearFilter && self.filterDefDialog.getCriteria() >= self.ruleCountToConfirmClearFilter)
+        {
+          self.clearFilterDialog.show();
+        }
+        else
+        {
+          self.grid.layer("filter").filterDef(null);
+          self.toggleClearFilterBtn(true)
+        }
+      });
+
+      this.filterSummary = new FilterSummary({grid: this.grid, filterStatusTip: this.filterStatusTip, nls: nls});
+
+      this.filterBar.addChild(this.filterDefButton);
+      this.filterBar.addChild(this.clearFilterButton);
+
+      this.filterBar.addChild(new dijit.ToolbarSeparator());
+      this.filterBar.addChild(this.filterSummary, "last");
+      this.filterBar.getColumnIdx = function(coordX){return self.filterSummary._getColumnIdx(coordX);};
+
+    }
+  });
+});
\ No newline at end of file

Added: qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/common/grid/FilterSummary.js
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/common/grid/FilterSummary.js?rev=1509778&view=auto
==============================================================================
--- qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/common/grid/FilterSummary.js (added)
+++ qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/common/grid/FilterSummary.js Fri Aug  2 17:03:34 2013
@@ -0,0 +1,173 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ *
+ */
+
+define([
+  "dojo/_base/declare",
+  "dojo/_base/lang",
+  "dojo/_base/html",
+  "dojo/query",
+  "dojo/dom-construct",
+  "dojo/string",
+  "dojo/on",
+  "dijit/_WidgetBase"
+], function(declare, lang, html, query, domConstruct, string, on, _WidgetBase){
+
+return declare("qpid.common.grid.FilterSummary", [_WidgetBase], {
+
+    domNode: null,
+    itemName: null,
+    filterStatusTip: null,
+    grid: null,
+    _handle_statusTooltip: null,
+    _timeout_statusTooltip: 300,
+    _nls: null,
+
+    constructor: function(params)
+    {
+      this.inherited(arguments);
+      this.itemName = params.itemsName;
+      this.initialize(params.filterStatusTip, params.grid);
+      this._nls = params.nls;
+    },
+
+    buildRendering: function(){
+      this.inherited(arguments);
+      var itemsName = this.itemName || this._nls["defaultItemsName"];
+      var message = string.substitute(this._nls["filterBarMsgNoFilterTemplate"], [0, itemsName ]);
+      this.domNode = domConstruct.create("span", {innerHTML: message, "class": "dijit dijitReset dijitInline dijitButtonInline", role: "presentation" });
+    },
+
+    postCreate: function(){
+      this.inherited(arguments);
+      on(this.domNode, "mouseenter", lang.hitch(this, this._onMouseEnter));
+      on(this.domNode, "mouseleave", lang.hitch(this, this._onMouseLeave));
+      on(this.domNode, "mousemove", lang.hitch(this, this._onMouseMove));
+    },
+
+    destroy: function()
+    {
+      this.inherited(arguments);
+      this.itemName = null;
+      this.filterStatusTip = null;
+      this.grid = null;
+      this._handle_statusTooltip = null;
+      this._filteredClass = null;
+      this._nls = null;
+    },
+
+    initialize: function(filterStatusTip, grid)
+    {
+      this.filterStatusTip = filterStatusTip;
+      this.grid = grid;
+      if (this.grid)
+      {
+        var filterLayer = grid.layer("filter");
+        this.connect(filterLayer, "onFiltered", this.onFiltered);
+      }
+    },
+
+    onFiltered: function(filteredSize, originSize)
+    {
+      try
+      {
+        var itemsName = this.itemName || this._nls["defaultItemsName"],
+          msg = "", g = this.grid,
+          filterLayer = g.layer("filter");
+        if(filterLayer.filterDef()){
+          msg = string.substitute(this._nls["filterBarMsgHasFilterTemplate"], [filteredSize, originSize, itemsName]);
+        }else{
+          msg = string.substitute(this._nls["filterBarMsgNoFilterTemplate"], [originSize, itemsName]);
+        }
+        this.domNode.innerHTML = msg;
+      }
+      catch(e)
+      {
+        // swallow and log exception
+        // otherwise grid rendering is screwed
+        console.error(e);
+      }
+    },
+
+    _getColumnIdx: function(coordX){
+      var headers = query("[role='columnheader']", this.grid.viewsHeaderNode);
+      var idx = -1;
+      for(var i = headers.length - 1; i >= 0; --i){
+        var coord = html.position(headers[i]);
+        if(coordX >= coord.x && coordX < coord.x + coord.w){
+          idx = i;
+          break;
+        }
+      }
+      if(idx >= 0 && this.grid.layout.cells[idx].filterable !== false){
+        return idx;
+      }else{
+        return -1;
+      }
+    },
+
+    _setStatusTipTimeout: function(){
+        this._clearStatusTipTimeout();
+        this._handle_statusTooltip = setTimeout(lang.hitch(this,this._showStatusTooltip),this._timeout_statusTooltip);
+    },
+
+    _clearStatusTipTimeout: function(){
+      if (this._handle_statusTooltip){
+        clearTimeout(this._handle_statusTooltip);
+      }
+      this._handle_statusTooltip = null;
+    },
+
+    _showStatusTooltip: function(){
+        this._handle_statusTooltip = null;
+        if(this.filterStatusTip){
+            this.filterStatusTip.showDialog(this._tippos.x, this._tippos.y, this._getColumnIdx(this._tippos.x));
+        }
+    },
+
+    _updateTipPosition: function(evt){
+        this._tippos = {
+            x: evt.pageX,
+            y: evt.pageY
+        };
+     },
+
+     _onMouseEnter: function(e){
+         this._updateTipPosition(e);
+         if(this.filterStatusTip){
+           this._setStatusTipTimeout();
+         }
+     },
+
+     _onMouseMove: function(e){
+       if(this.filterStatusTip){
+         this._setStatusTipTimeout();
+         if(this._handle_statusTooltip){
+             this._updateTipPosition(e);
+         }
+       }
+    },
+
+    _onMouseLeave: function(e){
+        this._clearStatusTipTimeout();
+    },
+  });
+
+});
\ No newline at end of file

Added: qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/common/grid/GridUpdater.js
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/common/grid/GridUpdater.js?rev=1509778&view=auto
==============================================================================
--- qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/common/grid/GridUpdater.js (added)
+++ qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/common/grid/GridUpdater.js Fri Aug  2 17:03:34 2013
@@ -0,0 +1,244 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ *
+ */
+
+
+define(["dojo/_base/xhr",
+        "dojo/parser",
+        "dojo/_base/array",
+        "dojo/_base/lang",
+        "qpid/common/properties",
+        "qpid/common/updater",
+        "qpid/common/UpdatableStore",
+        "qpid/common/util",
+        "dojox/grid/EnhancedGrid",
+        "qpid/common/grid/EnhancedFilter",
+        "dojox/grid/enhanced/plugins/NestedSorting",
+        "dojo/domReady!"],
+       function (xhr, parser, array, lang, properties, updater, UpdatableStore, util, EnhancedGrid, EnhancedFilter, NestedSorting) {
+
+          /*
+           * Construct GridUpdater from the following arguments:
+           * serviceUrl - service URL to fetch data for the grid. Optional, if data is specified
+           * data - array containing data for the grid. Optional, if serviceUrl is specified
+           * node - dom node or dom node id to
+           * structure,
+           * funct,
+           * gridProperties,
+           * gridConstructor
+           */
+           function GridUpdater(args) {
+
+             var self = this;
+
+             // GridUpdater fields
+             this.updatable = args.hasOwnProperty("updatable") ? args.updatable : true ;
+             this.serviceUrl = args.serviceUrl;
+             this.updatableStore = null;
+             this.grid = null;
+             this.onUpdate = args.onUpdate;
+             this._args = args;
+             this.appendData = args.append;
+             this.appendLimit = args.appendLimit;
+
+             // default grid properties
+             var gridProperties = {
+                 autoHeight: true,
+                 updateDelay: 0, // no delay updates when receiving notifications from a datastore
+                 plugins: {
+                   pagination: {
+                     defaultPageSize: 25,
+                     pageSizes: [10, 25, 50, 100],
+                     description: true,
+                     sizeSwitch: true,
+                     pageStepper: true,
+                     gotoButton: true,
+                     maxPageStep: 4,
+                     position: "bottom"
+                 },
+                 enhancedFilter: {}
+                }
+             };
+
+             var filterPluginFound = false;
+
+             // merge args grid properties with default grid properties
+             if(args && args.gridProperties)
+             {
+               var argProperties = args.gridProperties;
+               for(var argProperty in argProperties)
+               {
+                   if(argProperties.hasOwnProperty(argProperty))
+                   {
+                       if (argProperty == "plugins")
+                       {
+                         var argPlugins = argProperties[ argProperty ];
+                         for(var argPlugin in argPlugins)
+                         {
+                           if (argPlugin == "filter")
+                           {
+                               // we need to switch off filtering in EnhancedFilter
+                               filterPluginFound = true;
+                           }
+                           if(argPlugins.hasOwnProperty(argPlugin))
+                           {
+                             var argPluginProperties = argPlugins[ argPlugin ];
+                             if (argPluginProperties && gridProperties.plugins.hasOwnProperty(argPlugin))
+                             {
+                               var gridPlugin = gridProperties.plugins[ argPlugin ];
+                               for(var pluginProperty in argPluginProperties)
+                               {
+                                 if(argPluginProperties.hasOwnProperty(pluginProperty))
+                                 {
+                                   gridPlugin[pluginProperty] = argPluginProperties[pluginProperty];
+                                 }
+                               }
+                             }
+                             else
+                             {
+                               gridProperties.plugins[ argPlugin ] = argPlugins[ argPlugin ];
+                             }
+                           }
+                         }
+                       }
+                       else
+                       {
+                         gridProperties[ argProperty ] = argProperties[ argProperty ];
+                       }
+                   }
+               }
+             }
+
+             if (filterPluginFound)
+             {
+                 gridProperties.plugins.enhancedFilter.disableFiltering = true;
+             }
+
+             var updatableStoreFactory = function(data)
+             {
+               try
+               {
+                 self.updatableStore = new UpdatableStore(data, self._args.node, self._args.structure,
+                     self._args.funct, gridProperties, self._args.GridConstructor || EnhancedGrid, self.appendData);
+               }
+               catch(e)
+               {
+                 console.error(e);
+                 throw e;
+               }
+               self.grid = self.updatableStore.grid;
+               self.grid.updater = self;
+               if (self.onUpdate)
+               {
+                 self.onUpdate(data);
+               }
+               if (self.serviceUrl)
+               {
+                 updater.add(self);
+               }
+             };
+
+             if (args && args.serviceUrl)
+             {
+               var requestUrl = lang.isFunction(this.serviceUrl) ? this.serviceUrl() : this.serviceUrl;
+               xhr.get({url: requestUrl, sync: properties.useSyncGet, handleAs: "json"}).then(updatableStoreFactory, util.errorHandler);
+             }
+             else if (args && args.data)
+             {
+               updatableStoreFactory(args.data);
+             }
+           }
+
+           GridUpdater.prototype.destroy = function()
+           {
+             updater.remove(this);
+             if (this.updatableStore)
+             {
+                 this.updatableStore.close();
+                 this.updatableStore = null;
+             }
+             if (this.grid)
+             {
+                 this.grid.destroy();
+                 this.grid = null;
+             }
+           };
+
+           GridUpdater.prototype.refresh = function(data)
+           {
+               this.updating = true;
+               try
+               {
+                   if (this.appendData ? this.updatableStore.append(data, this.appendLimit): this.updatableStore.update(data))
+                   {
+                     // EnhancedGrid with Filter plugin has "filter" layer.
+                     // The filter expression needs to be re-applied after the data update
+                     var filterLayer = this.grid.layer("filter");
+                     if ( filterLayer && filterLayer.filterDef)
+                     {
+                         var currentFilter = filterLayer.filterDef();
+
+                         if (currentFilter)
+                         {
+                             // re-apply filter in the filter layer
+                             filterLayer.filterDef(currentFilter);
+                         }
+                     }
+
+                     // refresh grid to render updates
+                     this.grid._refresh();
+                   }
+               }
+               finally
+               {
+                   this.updating = false;
+                   if (this.onUpdate)
+                   {
+                     this.onUpdate(data);
+                   }
+               }
+           }
+
+           GridUpdater.prototype.update = function()
+           {
+             if (this.updatable)
+             {
+                 this.performUpdate();
+             }
+           };
+
+           GridUpdater.prototype.performUpdate = function()
+           {
+                 var self = this;
+                 var requestUrl = lang.isFunction(this.serviceUrl) ? this.serviceUrl() : this.serviceUrl;
+                 var requestArguments = {url: requestUrl, sync: properties.useSyncGet, handleAs: "json"};
+                 xhr.get(requestArguments).then(function(data){self.refresh(data);});
+           };
+
+           GridUpdater.prototype.performRefresh = function(data)
+           {
+               if (!this.updating)
+               {
+                   this.refresh(data);
+               }
+           };
+
+           return GridUpdater;
+       });

Added: qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/common/grid/RowNumberLimitDialog.js
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/common/grid/RowNumberLimitDialog.js?rev=1509778&view=auto
==============================================================================
--- qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/common/grid/RowNumberLimitDialog.js (added)
+++ qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/common/grid/RowNumberLimitDialog.js Fri Aug  2 17:03:34 2013
@@ -0,0 +1,96 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ *
+ */
+
+define([
+  "dojo/_base/declare",
+  "dojo/_base/event",
+  "dojo/_base/array",
+  "dojo/_base/lang",
+  "dojo/parser",
+  "dojo/dom-construct",
+  "dojo/query",
+  "dijit/registry",
+  "dijit/form/Button",
+  "dijit/form/CheckBox",
+  "dojox/grid/enhanced/plugins/Dialog",
+  "dojo/text!../../../grid/showRowNumberLimitDialog.html",
+  "dojo/domReady!"
+], function(declare, event, array, lang, parser, dom, query, registry, Button, CheckBox, Dialog, template ){
+
+
+return declare("qpid.management.logs.RowNumberLimitDialog", null, {
+
+  grid: null,
+  dialog: null,
+
+  constructor: function(domNode, limitChangedCallback){
+
+      this.containerNode = dom.create("div", {innerHTML: template});
+      parser.parse(this.containerNode);
+
+      this.rowNumberLimit = registry.byNode(query(".rowNumberLimit", this.containerNode)[0])
+      this.submitButton = registry.byNode(query(".submitButton", this.containerNode)[0]);
+      this.closeButton = registry.byNode(query(".cancelButton", this.containerNode)[0]);
+
+      this.dialog = new Dialog({
+        "refNode": domNode,
+        "title": "Grid Rows Number",
+        "content": this.containerNode
+      });
+
+      var self = this;
+      this.submitButton.on("click", function(e){
+          if (self.rowNumberLimit.value > 0)
+          {
+              try
+              {
+                  limitChangedCallback(self.rowNumberLimit.value);
+              }
+              catch(e)
+              {
+                  console.error(e);
+              }
+              finally
+              {
+                  self.dialog.hide();
+              }
+          }
+      });
+
+      this.closeButton.on("click", function(e){self.dialog.hide(); });
+      this.dialog.startup();
+    },
+
+    destroy: function(){
+      this.submitButton.destroy();
+      this.closeButton.destroy();
+      this.dialog.destroy();
+      this.dialog = null;
+    },
+
+    showDialog: function(currentLimit){
+      this.rowNumberLimit.set("value", currentLimit);
+      this.dialog.show();
+    }
+
+  });
+
+});

Modified: qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/common/util.js
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/common/util.js?rev=1509778&r1=1509777&r2=1509778&view=diff
==============================================================================
--- qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/common/util.js (original)
+++ qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/common/util.js Fri Aug  2 17:03:34 2013
@@ -353,5 +353,21 @@ define(["dojo/_base/xhr",
              }
            };
 
+           util.errorHandler = function errorHandler(error)
+           {
+               if(error.status == 401)
+               {
+                   alert("Authentication Failed");
+               }
+               else if(error.status == 403)
+               {
+                   alert("Access Denied");
+               }
+               else
+               {
+                   alert(error);
+               }
+           }
+
            return util;
        });
\ No newline at end of file



---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org


Mime
View raw message