[rhq] modules/enterprise
by Simeon Pinder
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/groups/GroupAlertsPortlet.java | 5 -
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/groups/GroupBundleDeploymentsPortlet.java | 5 -
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/groups/GroupEventsPortlet.java | 5 -
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/groups/GroupMetricsPortlet.java | 8 +-
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/groups/GroupOobsPortlet.java | 5 -
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/groups/GroupOperationsPortlet.java | 34 +++++++--
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/groups/GroupPkgHistoryPortlet.java | 5 -
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/detail/summary/AbstractActivityView.java | 35 ++++++++++
8 files changed, 77 insertions(+), 25 deletions(-)
New commits:
commit d1c21307bc3239d442473ed23ed26c6c65d0fb9f
Author: Simeon Pinder <spinder(a)redhat.com>
Date: Tue Mar 22 12:01:38 2011 -0400
i)fix portlets autogroup issue
ii)make empty measurements and operations display more consistent.
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/groups/GroupAlertsPortlet.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/groups/GroupAlertsPortlet.java
index 4fa8807..cc14736 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/groups/GroupAlertsPortlet.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/groups/GroupAlertsPortlet.java
@@ -108,8 +108,9 @@ public class GroupAlertsPortlet extends AlertHistoryView implements CustomSettin
//override the shared datasource
//figure out which page we're loading
String currentPage = History.getToken();
- String[] elements = currentPage.split("/");
- this.groupId = Integer.valueOf(elements[1]);
+ //get groupId
+ int groupId = AbstractActivityView.groupIdLookup(currentPage);
+ this.groupId = groupId;
setShowFilterForm(false); //disable filter form for portlet
setOverflow(Overflow.VISIBLE);
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/groups/GroupBundleDeploymentsPortlet.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/groups/GroupBundleDeploymentsPortlet.java
index 4f50f15..2c4fdc1 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/groups/GroupBundleDeploymentsPortlet.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/groups/GroupBundleDeploymentsPortlet.java
@@ -95,9 +95,8 @@ public class GroupBundleDeploymentsPortlet extends LocatableVLayout implements C
super(locatorId);
//figure out which page we're loading
String currentPage = History.getToken();
- String[] elements = currentPage.split("/");
- int currentGroupIdentifier = Integer.valueOf(elements[1]);
- this.groupId = currentGroupIdentifier;
+ int groupId = AbstractActivityView.groupIdLookup(currentPage);
+ this.groupId = groupId;
}
@Override
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/groups/GroupEventsPortlet.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/groups/GroupEventsPortlet.java
index 9978a6a..ec4dae7 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/groups/GroupEventsPortlet.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/groups/GroupEventsPortlet.java
@@ -96,9 +96,8 @@ public class GroupEventsPortlet extends LocatableVLayout implements CustomSettin
super(locatorId);
//figure out which page we're loading
String currentPage = History.getToken();
- String[] elements = currentPage.split("/");
- int currentGroupIdentifier = Integer.valueOf(elements[1]);
- this.groupId = currentGroupIdentifier;
+ int groupId = AbstractActivityView.groupIdLookup(currentPage);
+ this.groupId = groupId;
}
@Override
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/groups/GroupMetricsPortlet.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/groups/GroupMetricsPortlet.java
index d0a4f84..5cf7b36 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/groups/GroupMetricsPortlet.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/groups/GroupMetricsPortlet.java
@@ -113,8 +113,8 @@ public class GroupMetricsPortlet extends LocatableVLayout implements CustomSetti
//figure out which page we're loading
String currentPage = History.getToken();
String[] elements = currentPage.split("/");
- int currentGroupIdentifier = Integer.valueOf(elements[1]);
- this.groupId = currentGroupIdentifier;
+ int groupId = AbstractActivityView.groupIdLookup(currentPage);
+ this.groupId = groupId;
baseViewPath = elements[0];
}
@@ -438,6 +438,10 @@ public class GroupMetricsPortlet extends LocatableVLayout implements CustomSetti
}
});
}
+ } else {
+ LocatableDynamicForm row = AbstractActivityView.createEmptyDisplayRow(recentMeasurementsContent
+ .extendLocatorId("None"), AbstractActivityView.RECENT_MEASUREMENTS_NONE);
+ column.addMember(row);
}
}
});
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/groups/GroupOobsPortlet.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/groups/GroupOobsPortlet.java
index 206be22..ed3fb42 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/groups/GroupOobsPortlet.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/groups/GroupOobsPortlet.java
@@ -90,9 +90,8 @@ public class GroupOobsPortlet extends LocatableVLayout implements CustomSettings
super(locatorId);
//figure out which page we're loading
String currentPage = History.getToken();
- String[] elements = currentPage.split("/");
- int currentGroupIdentifier = Integer.valueOf(elements[1]);
- this.groupId = currentGroupIdentifier;
+ int groupId = AbstractActivityView.groupIdLookup(currentPage);
+ this.groupId = groupId;
}
@Override
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/groups/GroupOperationsPortlet.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/groups/GroupOperationsPortlet.java
index f2322b0..9c2be45 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/groups/GroupOperationsPortlet.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/groups/GroupOperationsPortlet.java
@@ -43,6 +43,7 @@ import org.rhq.core.domain.criteria.ResourceGroupCriteria;
import org.rhq.core.domain.dashboard.DashboardPortlet;
import org.rhq.core.domain.operation.GroupOperationHistory;
import org.rhq.core.domain.operation.OperationRequestStatus;
+import org.rhq.core.domain.resource.group.ResourceGroup;
import org.rhq.core.domain.resource.group.composite.ResourceGroupComposite;
import org.rhq.core.domain.util.PageControl;
import org.rhq.core.domain.util.PageList;
@@ -116,10 +117,10 @@ public class GroupOperationsPortlet extends LocatableVLayout implements CustomSe
//figure out which page we're loading
String currentPage = History.getToken();
String[] elements = currentPage.split("/");
- int currentGroupIdentifier = Integer.valueOf(elements[1]);
- this.groupId = currentGroupIdentifier;
+ int groupId = AbstractActivityView.groupIdLookup(currentPage);
+ this.groupId = groupId;
//populate basepath
- baseViewPath = elements[0];
+ baseViewPath = AbstractActivityView.groupPathLookup(currentPage);
}
@Override
@@ -169,14 +170,22 @@ public class GroupOperationsPortlet extends LocatableVLayout implements CustomSe
groupOperations = new GroupOperationsCriteriaHistoryListView(locatorId,
new GroupOperationsCriteriaDataSource(portletConfig), null, criteria, groupComposite);
+ } else {
+ Criteria criteria = new Criteria();
+ ResourceGroup emptyGroup = new ResourceGroup("");
+ emptyGroup.setId(-1);
+ Long zero = new Long(0);
+ groupComposite = new ResourceGroupComposite(zero, zero, zero, zero, emptyGroup);
+ groupOperations = new GroupOperationsCriteriaHistoryListView(locatorId,
+ new GroupOperationsCriteriaDataSource(portletConfig), null, criteria, groupComposite);
+ }
- //cleanup
- for (Canvas child : recentOperationsContent.getChildren()) {
- child.destroy();
- }
- recentOperationsContent.addChild(groupOperations);
- recentOperationsContent.markForRedraw();
+ //cleanup
+ for (Canvas child : recentOperationsContent.getChildren()) {
+ child.destroy();
}
+ recentOperationsContent.addChild(groupOperations);
+ recentOperationsContent.markForRedraw();
}
});
}
@@ -188,6 +197,7 @@ public class GroupOperationsPortlet extends LocatableVLayout implements CustomSe
setMembersMargin(5);
setHeight("*");
setWidth100();
+
//tell canvas to fill it's component
recentOperationsContent.setHeight100();
addMember(recentOperationsContent);
@@ -371,6 +381,12 @@ class GroupOperationsCriteriaHistoryListView extends GroupOperationHistoryListVi
protected String getBasePath() {
return "ResourceGroup/" + composite.getResourceGroup().getId() + "/Operations/History";
}
+
+ @Override
+ protected void onInit() {
+ super.onInit();
+ getListGrid().setEmptyMessage(MSG.view_portlet_results_empty());
+ }
}
/** Provide implementation of GroupOperationHistoryDataSource that dynamically
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/groups/GroupPkgHistoryPortlet.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/groups/GroupPkgHistoryPortlet.java
index b7dbf69..30c21a7 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/groups/GroupPkgHistoryPortlet.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/groups/GroupPkgHistoryPortlet.java
@@ -93,9 +93,8 @@ public class GroupPkgHistoryPortlet extends LocatableVLayout implements CustomSe
super(locatorId);
//figure out which page we're loading
String currentPage = History.getToken();
- String[] elements = currentPage.split("/");
- int currentGroupIdentifier = Integer.valueOf(elements[1]);
- this.groupId = currentGroupIdentifier;
+ int groupId = AbstractActivityView.groupIdLookup(currentPage);
+ this.groupId = groupId;
}
@Override
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/detail/summary/AbstractActivityView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/detail/summary/AbstractActivityView.java
index 2da6e15..82ac645 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/detail/summary/AbstractActivityView.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/detail/summary/AbstractActivityView.java
@@ -594,4 +594,39 @@ public abstract class AbstractActivityView extends LocatableVLayout implements R
return ((groupCategory == GroupCategory.MIXED) || (groupCategory == GroupCategory.COMPATIBLE && facets
.contains(ResourceTypeFacet.EVENT)));
}
+
+ /* Utility method to extract groupId from
+ *
+ */
+ public static int groupIdLookup(String currentPage) {
+ int groupId = -1;
+ if ((currentPage != null) && (!currentPage.trim().isEmpty())) {
+ String[] elements = currentPage.split("/");
+ //process for groups and auto groups Ex. ResourceGroup/10111 or ResourceGroup/AutoCluster/10321
+ try {
+ groupId = Integer.valueOf(elements[1]);
+ } catch (NumberFormatException nfe) {
+ groupId = Integer.valueOf(elements[2]);
+ }
+ }
+ return groupId;
+ }
+
+ /* Utility method to extract groupId from
+ *
+ */
+ public static String groupPathLookup(String currentPage) {
+ String groupBasePath = "";
+ if ((currentPage != null) && (!currentPage.trim().isEmpty())) {
+ String[] elements = currentPage.split("/");
+ //process for groups and auto groups Ex. ResourceGroup/10111 or ResourceGroup/AutoCluster/10321
+ try {
+ Integer.valueOf(elements[1]);
+ groupBasePath = elements[0];
+ } catch (NumberFormatException nfe) {
+ groupBasePath = elements[1] + "/" + elements[1];
+ }
+ }
+ return groupBasePath;
+ }
}
13 years, 3 months
[rhq] modules/plugins
by lkrejci
modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheVirtualHostServiceComponent.java | 6
modules/plugins/apache/src/main/java/org/rhq/plugins/apache/util/HttpdAddressUtility.java | 77 ++++++----
2 files changed, 51 insertions(+), 32 deletions(-)
New commits:
commit b6e71a4f58ac52de47215a0bd0595d4689b14836
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Tue Mar 22 17:15:17 2011 +0100
BZ 689833 - be able to match the main server with snmp index even in the case of multiple listen addresses.
diff --git a/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheVirtualHostServiceComponent.java b/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheVirtualHostServiceComponent.java
index a1365da..ee3e2ea 100644
--- a/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheVirtualHostServiceComponent.java
+++ b/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheVirtualHostServiceComponent.java
@@ -502,9 +502,9 @@ public class ApacheVirtualHostServiceComponent implements ResourceComponent<Apac
vhostAddressStrings.length);
if (vhostAddressStrings.length == 1 && MAIN_SERVER_RESOURCE_KEY.equals(vhostAddressStrings[0])) {
- HttpdAddressUtility.Address serverAddr = parent.getAddressUtility().getMainServerSampleAddress(tree, null, 0);
- if (serverAddr != null) {
- vhostAddresses.add(serverAddr);
+ List<HttpdAddressUtility.Address> serverAddrs = parent.getAddressUtility().getAllMainServerAddresses(tree);
+ if (serverAddrs != null) {
+ vhostAddresses.addAll(serverAddrs);
}
} else {
for (int i = 0; i < vhostAddressStrings.length; ++i) {
diff --git a/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/util/HttpdAddressUtility.java b/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/util/HttpdAddressUtility.java
index 0710178..8ecdb7b 100644
--- a/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/util/HttpdAddressUtility.java
+++ b/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/util/HttpdAddressUtility.java
@@ -41,7 +41,8 @@ import org.rhq.plugins.apache.parser.ApacheDirectiveTree;
public enum HttpdAddressUtility {
APACHE_1_3 {
- public Address getMainServerSampleAddress(ApacheDirectiveTree ag, String limitToHost, int limitToPort) {
+
+ public List<Address> getAllMainServerAddresses(ApacheDirectiveTree ag) {
try {
List<ApacheDirective> ports = ag.search("/Port");
List<ApacheDirective> bindAddresses = ag.search("/BindAddress");
@@ -50,7 +51,7 @@ public enum HttpdAddressUtility {
String port = "80"; //this is the default in apache 1.3
String bindAddress = null;
- List<Address> addressesToMatch = new ArrayList<Address>();
+ List<Address> addresses = new ArrayList<Address>();
if (ports.size() > 0) {
List<String>values = ports.get(0).getValues();
@@ -67,28 +68,24 @@ public enum HttpdAddressUtility {
//listen directives take precedence over port/bindaddress combo
if (listens.size() > 0) {
for(ApacheDirective l : listens) {
- addressesToMatch.add(parseListen(l.getValues().get(0)));
+ addresses.add(parseListen(l.getValues().get(0)));
}
} else {
- addressesToMatch.add(new Address(bindAddress, Integer.parseInt(port)));
+ addresses.add(new Address(bindAddress, Integer.parseInt(port)));
}
- for (Address address : addressesToMatch) {
- if (isAddressConforming(address, limitToHost, limitToPort, false)) {
- if (!address.isPortDefined() || address.isPortWildcard()) {
- address.port = 80;
- }
- if (address.host == null || address.isHostDefault() || address.isHostWildcard()) {
- address = getLocalhost(address.port);
- }
-
- updateWithServerName(address, ag);
-
- return address;
+ for (Address address : addresses) {
+ if (!address.isPortDefined() || address.isPortWildcard()) {
+ address.port = 80;
+ }
+ if (address.host == null || address.isHostDefault() || address.isHostWildcard()) {
+ address = getLocalhost(address.port);
}
+
+ updateWithServerName(address, ag);
}
- return null;
+ return addresses;
} catch (Exception e) {
log.warn("Failed to obtain main server address.", e);
@@ -97,23 +94,23 @@ public enum HttpdAddressUtility {
}
},
APACHE_2_x {
- public Address getMainServerSampleAddress(ApacheDirectiveTree ag, String limitToHost, int limitToPort) {
+
+ public List<Address> getAllMainServerAddresses(ApacheDirectiveTree ag) {
try {
+ List<Address> ret = new ArrayList<Address>();
+
for(ApacheDirective n : ag.search("/Listen")) {
Address addr = parseListen(n.getValues().get(0));
- if (isAddressConforming(addr, limitToHost, limitToPort, false)) {
- if (addr.host == null || addr.isHostDefault() || addr.isHostWildcard()) {
- addr = getLocalhost(addr.port);
- }
-
- updateWithServerName(addr, ag);
-
- return addr;
+ if (addr.host == null || addr.isHostDefault() || addr.isHostWildcard()) {
+ addr = getLocalhost(addr.port);
}
+
+ updateWithServerName(addr, ag);
+
+ ret.add(addr);
}
- //there has to be at least one Listen directive
- throw new IllegalStateException("Could find a listen address on port " + limitToPort);
+ return ret;
} catch (Exception e) {
log.warn("Failed to obtain main server address.", e);
@@ -283,6 +280,14 @@ public enum HttpdAddressUtility {
}
/**
+ * This returns all the addresses the server listens on.
+ *
+ * @param ag the tree of the httpd configuration
+ * @return the addresses or null on failure
+ */
+ public abstract List<Address> getAllMainServerAddresses(ApacheDirectiveTree ag);
+
+ /**
* This just constructs a first available address under which the server or one of its virtual hosts can be reached.
*
* @param ag the tree of the httpd configuration
@@ -291,7 +296,21 @@ public enum HttpdAddressUtility {
* @param limitToPort if > 0, the sample address is looked for only for the given port
* @return the address or null on failure
*/
- public abstract Address getMainServerSampleAddress(ApacheDirectiveTree ag, String limitToHost, int limitToPort);
+ public Address getMainServerSampleAddress(ApacheDirectiveTree ag, String limitToHost, int limitToPort) {
+ List<Address> addressesToMatch = getAllMainServerAddresses(ag);
+
+ if (addressesToMatch == null) {
+ return null;
+ }
+
+ for (Address address : addressesToMatch) {
+ if (isAddressConforming(address, limitToHost, limitToPort, false)) {
+ return address;
+ }
+ }
+
+ return null;
+ }
/**
* This constructs an address on which given virtual host can be accessed.
13 years, 3 months
[rhq] 2 commits - modules/enterprise
by Simeon Pinder
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/AlertDataSource.java | 8
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/AlertPortletConfigurationDataSource.java | 37 +++
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/groups/GroupEventsPortlet.java | 37 ++-
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/groups/GroupMetricsPortlet.java | 31 ++-
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/resource/ResourceEventsPortlet.java | 33 ++-
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/resource/ResourceMetricsPortlet.java | 33 ++-
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/resource/ResourcePkgHistoryPortlet.java | 1
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/summary/ActivityView.java | 103 ++++++++--
8 files changed, 232 insertions(+), 51 deletions(-)
New commits:
commit 4d60c27b2b60efed1ca0f4d2a4881fa05fd7ceca
Author: Simeon Pinder <spinder(a)redhat.com>
Date: Tue Mar 22 08:57:19 2011 -0400
i)removing D12N column from ResourceAlertsPortlet.
ii)added remaining asynch call to add bundledeployment portlet for groups.
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/AlertDataSource.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/AlertDataSource.java
index 4ef6e16..ddc343f 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/AlertDataSource.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/AlertDataSource.java
@@ -390,4 +390,12 @@ public class AlertDataSource extends RPCDataSource<Alert> {
public AlertGWTServiceAsync getAlertService() {
return alertService;
}
+
+ protected EntityContext getEntityContext() {
+ return entityContext;
+ }
+
+ protected void setEntityContext(EntityContext entityContext) {
+ this.entityContext = entityContext;
+ }
}
\ No newline at end of file
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/AlertPortletConfigurationDataSource.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/AlertPortletConfigurationDataSource.java
index 2c6621d..5396bc0 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/AlertPortletConfigurationDataSource.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/AlertPortletConfigurationDataSource.java
@@ -75,6 +75,7 @@ public class AlertPortletConfigurationDataSource extends AlertDataSource {
} else if ((resourceIds != null) && (resourceIds.length > 0)) {
entityContext = EntityContext.forResource(resourceIds[0]);
}
+ setEntityContext(entityContext);
}
/** Override the executeFetch for AlertPortlet to allow specifying smaller than total
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/summary/ActivityView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/summary/ActivityView.java
index 7ff4f7d..dc74fb6 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/summary/ActivityView.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/summary/ActivityView.java
@@ -22,6 +22,7 @@ import java.util.HashMap;
import java.util.Map;
import java.util.Set;
+import com.allen_sauer.gwt.log.client.Log;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.smartgwt.client.util.BooleanCallback;
import com.smartgwt.client.util.SC;
@@ -34,11 +35,16 @@ import org.rhq.core.domain.auth.Subject;
import org.rhq.core.domain.authz.Permission;
import org.rhq.core.domain.configuration.PropertySimple;
import org.rhq.core.domain.criteria.DashboardCriteria;
+import org.rhq.core.domain.criteria.ResourceGroupCriteria;
import org.rhq.core.domain.dashboard.Dashboard;
import org.rhq.core.domain.dashboard.DashboardCategory;
import org.rhq.core.domain.dashboard.DashboardPortlet;
+import org.rhq.core.domain.resource.Resource;
+import org.rhq.core.domain.resource.ResourceCategory;
+import org.rhq.core.domain.resource.group.GroupCategory;
import org.rhq.core.domain.resource.group.ResourceGroup;
import org.rhq.core.domain.resource.group.composite.ResourceGroupComposite;
+import org.rhq.core.domain.util.PageControl;
import org.rhq.core.domain.util.PageList;
import org.rhq.enterprise.gui.coregui.client.CoreGUI;
import org.rhq.enterprise.gui.coregui.client.InitializableView;
@@ -83,8 +89,13 @@ public class ActivityView extends LocatableVLayout implements DashboardContainer
private Set<Permission> globalPermissions;
private boolean editMode = false;
-
private boolean isInitialized = false;
+ //default portlet positioning parameters
+ private int colLeft = 0;
+ private int colRight = 1;
+ private int rowLeft = 0;
+ private int rowRight = 0;
+ private boolean displayLeft = false;
public ActivityView(String locatorId, ResourceGroupComposite groupComposite) {
super(locatorId);
@@ -177,9 +188,9 @@ public class ActivityView extends LocatableVLayout implements DashboardContainer
protected Dashboard getDefaultDashboard() {
Subject sessionSubject = UserSessionManager.getSessionSubject();
- ResourceGroup group = groupComposite.getResourceGroup();
+ final ResourceGroup group = groupComposite.getResourceGroup();
- Dashboard dashboard = new Dashboard();
+ final Dashboard dashboard = new Dashboard();
dashboard.setName(DASHBOARD_NAME_PREFIX + sessionSubject.getId() + "_" + group.getId());
dashboard.setCategory(DashboardCategory.GROUP);
@@ -196,12 +207,50 @@ public class ActivityView extends LocatableVLayout implements DashboardContainer
//remove BundleDeployment and add back later if relevant.
groupKeyNameMap.remove(GroupBundleDeploymentsPortlet.KEY);
groupKeyNameMap = DashboardView.processPortletNameMapForGroup(groupKeyNameMap, groupComposite);
- //TODO: spinder 3/21/11 need asynch call to execute and then update the menu for bundle
- int colLeft = 0;
- int colRight = 1;
- int rowLeft = 0;
- int rowRight = 0;
+ //initiate asynch call to execute and then update the dashboard with bundle deployment portlet if necessary
+ ResourceGroupCriteria criteria = new ResourceGroupCriteria();
+ criteria.addFilterId(group.getId());
+ criteria.fetchExplicitResources(true);
+ criteria.setPageControl(new PageControl(0, 1));
+ GWTServiceLookup.getResourceGroupService().findResourceGroupsByCriteria(criteria,
+ new AsyncCallback<PageList<ResourceGroup>>() {
+ @Override
+ public void onSuccess(PageList<ResourceGroup> results) {
+ if (!results.isEmpty()) {
+ ResourceGroup grp = results.get(0);
+ Set<Resource> explicitMembers = grp.getExplicitResources();
+ Resource[] currentResources = new Resource[explicitMembers.size()];
+ explicitMembers.toArray(currentResources);
+ Map<String, String> portletToAdd = new HashMap<String, String>();
+ //membership dynamically determined if all platforms then will be compatible.
+ if (group.getGroupCategory().equals(GroupCategory.COMPATIBLE)) {
+ if (currentResources[0].getResourceType().getCategory().equals(ResourceCategory.PLATFORM)) {
+ //this portlet allowed to add bundle portlet monitoring
+ portletToAdd.put(GroupBundleDeploymentsPortlet.KEY, GroupBundleDeploymentsPortlet.NAME);
+ }
+ if (!portletToAdd.isEmpty()) {
+ //update dashboard with that portlet and reload
+ updateDashboardWithPortlets(portletToAdd, dashboard, 100);
+ //request reload of dashboard widget
+ setDashboard(dashboard);
+ markForRedraw();
+ }
+ }
+ }
+ }
+
+ @Override
+ public void onFailure(Throwable caught) {
+ Log.debug("Error retrieving information for group [" + group.getId() + "]:" + caught.getMessage());
+ }
+ });
+
+ //reset positioning parameters
+ colLeft = 0;
+ colRight = 1;
+ rowLeft = 0;
+ rowRight = 0;
//Left Column
if (groupKeyNameMap.containsKey(GroupMetricsPortlet.KEY)) {//measurments top left if available
DashboardPortlet measurements = new DashboardPortlet(GroupMetricsPortlet.NAME, GroupMetricsPortlet.KEY, 220);
@@ -222,22 +271,36 @@ public class ActivityView extends LocatableVLayout implements DashboardContainer
}
//Fill out left column(typically smaller portlets) then alternate cols with remaining
- boolean displayLeft = false;
- for (String key : groupKeyNameMap.keySet()) {
- DashboardPortlet portlet = new DashboardPortlet(groupKeyNameMap.get(key), key, 100);
- if (rowLeft < 4) {
- dashboard.addPortlet(portlet, colLeft, rowLeft++);
- } else {//alternate
- if (!displayLeft) {
- dashboard.addPortlet(portlet, colRight, rowRight++);
- } else {
+ displayLeft = false;
+ updateDashboardWithPortlets(groupKeyNameMap, dashboard, 100);
+ return dashboard;
+ }
+
+ /**Iterates list of new portlets and updates the dashboard reference with these new portlets.
+ * Attempts to fill the spaces around the remaining larger portlets if already installed, then alternates
+ * adding to left and right columns. Assumes dashboard has only two columns.
+ *
+ * @param keyNameMap portlet key|name map
+ * @param dashboard dasboard instance to update
+ */
+ private void updateDashboardWithPortlets(Map<String, String> keyNameMap, Dashboard dashboard, int initialHeight) {
+ if ((keyNameMap != null) && (dashboard != null)) {
+ for (String key : keyNameMap.keySet()) {
+ //locate portlet and add to dashboard
+ DashboardPortlet portlet = new DashboardPortlet(keyNameMap.get(key), key, initialHeight);
+ if (rowLeft < 4) {
dashboard.addPortlet(portlet, colLeft, rowLeft++);
+ } else {//alternate
+ if (!displayLeft) {
+ dashboard.addPortlet(portlet, colRight, rowRight++);
+ } else {
+ dashboard.addPortlet(portlet, colLeft, rowLeft++);
+ }
+ //toggle
+ displayLeft = !displayLeft;
}
- //toggle
- displayLeft = !displayLeft;
}
}
- return dashboard;
}
@Override
commit e46e1bc770a08dc17173994af8fa5abc28e186c4
Author: Simeon Pinder <spinder(a)redhat.com>
Date: Mon Mar 21 18:21:49 2011 -0400
time range refresh fixes.
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/AlertPortletConfigurationDataSource.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/AlertPortletConfigurationDataSource.java
index 39f2f52..2c6621d 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/AlertPortletConfigurationDataSource.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/AlertPortletConfigurationDataSource.java
@@ -18,6 +18,8 @@
*/
package org.rhq.enterprise.gui.coregui.client.alert;
+import java.util.ArrayList;
+
import com.allen_sauer.gwt.log.client.Log;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.smartgwt.client.data.DSRequest;
@@ -40,6 +42,7 @@ import org.rhq.enterprise.gui.coregui.client.CoreGUI;
import org.rhq.enterprise.gui.coregui.client.dashboard.portlets.PortletConfigurationEditorComponent;
import org.rhq.enterprise.gui.coregui.client.dashboard.portlets.PortletConfigurationEditorComponent.Constant;
import org.rhq.enterprise.gui.coregui.client.dashboard.portlets.recent.alerts.RecentAlertsPortlet;
+import org.rhq.enterprise.gui.coregui.client.util.MeasurementUtility;
/** Customize the AlertDataSource to pull fetch criteria information from
* the Configuration object passed in.
@@ -116,15 +119,38 @@ public class AlertPortletConfigurationDataSource extends AlertDataSource {
pc.setPrimarySortOrder(PageOrdering.ASC);
}
}
+
//result timeframe if enabled
property = portletConfig.getSimple(Constant.METRIC_RANGE_ENABLE);
if (Boolean.valueOf(property.getBooleanValue())) {//then proceed setting
- property = portletConfig.getSimple(Constant.METRIC_RANGE);
+
+ boolean isAdvanced = false;
+ //detect type of widget[Simple|Advanced]
+ property = portletConfig.getSimple(Constant.METRIC_RANGE_BEGIN_END_FLAG);
if (property != null) {
- String currentSetting = property.getStringValue();
- String[] range = currentSetting.split(",");
- criteria.addFilterStartTime(Long.valueOf(range[0]));
- criteria.addFilterEndTime(Long.valueOf(range[1]));
+ isAdvanced = property.getBooleanValue();
+ }
+ if (isAdvanced) {
+ //Advanced time settings
+ property = portletConfig.getSimple(Constant.METRIC_RANGE);
+ if (property != null) {
+ String currentSetting = property.getStringValue();
+ String[] range = currentSetting.split(",");
+ criteria.addFilterStartTime(Long.valueOf(range[0]));
+ criteria.addFilterEndTime(Long.valueOf(range[1]));
+ }
+ } else {
+ //Simple time settings
+ property = portletConfig.getSimple(Constant.METRIC_RANGE_LASTN);
+ if (property != null) {
+ int lastN = property.getIntegerValue();
+ property = portletConfig.getSimple(Constant.METRIC_RANGE_UNIT);
+ int lastUnits = property.getIntegerValue();
+ ArrayList<Long> beginEnd = MeasurementUtility.calculateTimeFrame(lastN, Integer
+ .valueOf(lastUnits));
+ criteria.addFilterStartTime(Long.valueOf(beginEnd.get(0)));
+ criteria.addFilterEndTime(Long.valueOf(beginEnd.get(1)));
+ }
}
}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/groups/GroupEventsPortlet.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/groups/GroupEventsPortlet.java
index 35d5886..9978a6a 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/groups/GroupEventsPortlet.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/groups/GroupEventsPortlet.java
@@ -105,7 +105,7 @@ public class GroupEventsPortlet extends LocatableVLayout implements CustomSettin
protected void onInit() {
super.onInit();
initializeUi();
- loadData();
+ redraw();
}
/**Defines layout for the portlet page.
@@ -178,7 +178,7 @@ public class GroupEventsPortlet extends LocatableVLayout implements CustomSettin
//persist
storedPortlet.setConfiguration(portletConfig);
configure(portletWindow, storedPortlet);
- loadData();
+ redraw();
customSettings.markForRedraw();
}
});
@@ -198,12 +198,33 @@ public class GroupEventsPortlet extends LocatableVLayout implements CustomSettin
//result timeframe if enabled
PropertySimple property = portletConfig.getSimple(Constant.METRIC_RANGE_ENABLE);
if (Boolean.valueOf(property.getBooleanValue())) {//then proceed setting
- property = portletConfig.getSimple(Constant.METRIC_RANGE);
+
+ boolean isAdvanced = false;
+ //detect type of widget[Simple|Advanced]
+ property = portletConfig.getSimple(Constant.METRIC_RANGE_BEGIN_END_FLAG);
if (property != null) {
- String currentSetting = property.getStringValue();
- String[] range = currentSetting.split(",");
- start = Long.valueOf(range[0]);
- end = Long.valueOf(range[1]);
+ isAdvanced = property.getBooleanValue();
+ }
+ if (isAdvanced) {
+ //Advanced time settings
+ property = portletConfig.getSimple(Constant.METRIC_RANGE);
+ if (property != null) {
+ String currentSetting = property.getStringValue();
+ String[] range = currentSetting.split(",");
+ start = Long.valueOf(range[0]);
+ end = Long.valueOf(range[1]);
+ }
+ } else {
+ //Simple time settings
+ property = portletConfig.getSimple(Constant.METRIC_RANGE_LASTN);
+ if (property != null) {
+ int lastN = property.getIntegerValue();
+ property = portletConfig.getSimple(Constant.METRIC_RANGE_UNIT);
+ int lastUnits = property.getIntegerValue();
+ ArrayList<Long> beginEnd = MeasurementUtility.calculateTimeFrame(lastN, Integer.valueOf(lastUnits));
+ start = Long.valueOf(beginEnd.get(0));
+ end = Long.valueOf(beginEnd.get(1));
+ }
}
}
@@ -287,7 +308,6 @@ public class GroupEventsPortlet extends LocatableVLayout implements CustomSettin
refreshTimer = new Timer() {
public void run() {
if (!currentlyLoading) {
- loadData();
redraw();
}
}
@@ -311,5 +331,4 @@ public class GroupEventsPortlet extends LocatableVLayout implements CustomSettin
super.redraw();
loadData();
}
-
}
\ No newline at end of file
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/groups/GroupMetricsPortlet.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/groups/GroupMetricsPortlet.java
index 80bf045..d0a4f84 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/groups/GroupMetricsPortlet.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/groups/GroupMetricsPortlet.java
@@ -219,12 +219,33 @@ public class GroupMetricsPortlet extends LocatableVLayout implements CustomSetti
//result timeframe if enabled
PropertySimple property = portletConfig.getSimple(Constant.METRIC_RANGE_ENABLE);
if (Boolean.valueOf(property.getBooleanValue())) {//then proceed setting
- property = portletConfig.getSimple(Constant.METRIC_RANGE);
+
+ boolean isAdvanced = false;
+ //detect type of widget[Simple|Advanced]
+ property = portletConfig.getSimple(Constant.METRIC_RANGE_BEGIN_END_FLAG);
if (property != null) {
- String currentSetting = property.getStringValue();
- String[] range = currentSetting.split(",");
- start = Long.valueOf(range[0]);
- end = Long.valueOf(range[1]);
+ isAdvanced = property.getBooleanValue();
+ }
+ if (isAdvanced) {
+ //Advanced time settings
+ property = portletConfig.getSimple(Constant.METRIC_RANGE);
+ if (property != null) {
+ String currentSetting = property.getStringValue();
+ String[] range = currentSetting.split(",");
+ start = Long.valueOf(range[0]);
+ end = Long.valueOf(range[1]);
+ }
+ } else {
+ //Simple time settings
+ property = portletConfig.getSimple(Constant.METRIC_RANGE_LASTN);
+ if (property != null) {
+ int lastN = property.getIntegerValue();
+ property = portletConfig.getSimple(Constant.METRIC_RANGE_UNIT);
+ int lastUnits = property.getIntegerValue();
+ ArrayList<Long> beginEnd = MeasurementUtility.calculateTimeFrame(lastN, Integer.valueOf(lastUnits));
+ start = Long.valueOf(beginEnd.get(0));
+ end = Long.valueOf(beginEnd.get(1));
+ }
}
}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/resource/ResourceEventsPortlet.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/resource/ResourceEventsPortlet.java
index d915351..a2a2bda 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/resource/ResourceEventsPortlet.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/resource/ResourceEventsPortlet.java
@@ -40,6 +40,7 @@ import org.rhq.enterprise.gui.coregui.client.gwt.GWTServiceLookup;
import org.rhq.enterprise.gui.coregui.client.inventory.common.detail.summary.AbstractActivityView;
import org.rhq.enterprise.gui.coregui.client.resource.disambiguation.ReportDecorator;
import org.rhq.enterprise.gui.coregui.client.util.GwtTuple;
+import org.rhq.enterprise.gui.coregui.client.util.MeasurementUtility;
import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableDynamicForm;
/**This portlet allows the end user to customize the Events display
@@ -102,16 +103,36 @@ public class ResourceEventsPortlet extends GroupEventsPortlet {
//result timeframe if enabled
PropertySimple property = portletConfig.getSimple(Constant.METRIC_RANGE_ENABLE);
if (Boolean.valueOf(property.getBooleanValue())) {//then proceed setting
- property = portletConfig.getSimple(Constant.METRIC_RANGE);
+
+ boolean isAdvanced = false;
+ //detect type of widget[Simple|Advanced]
+ property = portletConfig.getSimple(Constant.METRIC_RANGE_BEGIN_END_FLAG);
if (property != null) {
- String currentSetting = property.getStringValue();
- String[] range = currentSetting.split(",");
- start = Long.valueOf(range[0]);
- end = Long.valueOf(range[1]);
+ isAdvanced = property.getBooleanValue();
+ }
+ if (isAdvanced) {
+ //Advanced time settings
+ property = portletConfig.getSimple(Constant.METRIC_RANGE);
+ if (property != null) {
+ String currentSetting = property.getStringValue();
+ String[] range = currentSetting.split(",");
+ start = Long.valueOf(range[0]);
+ end = Long.valueOf(range[1]);
+ }
+ } else {
+ //Simple time settings
+ property = portletConfig.getSimple(Constant.METRIC_RANGE_LASTN);
+ if (property != null) {
+ int lastN = property.getIntegerValue();
+ property = portletConfig.getSimple(Constant.METRIC_RANGE_UNIT);
+ int lastUnits = property.getIntegerValue();
+ ArrayList<Long> beginEnd = MeasurementUtility.calculateTimeFrame(lastN, Integer.valueOf(lastUnits));
+ start = Long.valueOf(beginEnd.get(0));
+ end = Long.valueOf(beginEnd.get(1));
+ }
}
}
- // GWTServiceLookup.getEventService().getEventCountsBySeverityForGroup(resourceId, start, end,
GWTServiceLookup.getEventService().getEventCountsBySeverity(resourceId, start, end,
new AsyncCallback<Map<EventSeverity, Integer>>() {
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/resource/ResourceMetricsPortlet.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/resource/ResourceMetricsPortlet.java
index b7ed496..e907ce6 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/resource/ResourceMetricsPortlet.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/resource/ResourceMetricsPortlet.java
@@ -18,6 +18,7 @@
*/
package org.rhq.enterprise.gui.coregui.client.dashboard.portlets.resource;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.EnumSet;
import java.util.HashMap;
@@ -52,6 +53,7 @@ import org.rhq.enterprise.gui.coregui.client.inventory.common.detail.summary.Abs
import org.rhq.enterprise.gui.coregui.client.inventory.resource.type.ResourceTypeRepository;
import org.rhq.enterprise.gui.coregui.client.resource.disambiguation.ReportDecorator;
import org.rhq.enterprise.gui.coregui.client.util.BrowserUtility;
+import org.rhq.enterprise.gui.coregui.client.util.MeasurementUtility;
import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableDynamicForm;
/**This portlet allows the end user to customize the metric display
@@ -121,12 +123,33 @@ public class ResourceMetricsPortlet extends GroupMetricsPortlet {
//result timeframe if enabled
PropertySimple property = portletConfig.getSimple(Constant.METRIC_RANGE_ENABLE);
if (Boolean.valueOf(property.getBooleanValue())) {//then proceed setting
- property = portletConfig.getSimple(Constant.METRIC_RANGE);
+
+ boolean isAdvanced = false;
+ //detect type of widget[Simple|Advanced]
+ property = portletConfig.getSimple(Constant.METRIC_RANGE_BEGIN_END_FLAG);
if (property != null) {
- String currentSetting = property.getStringValue();
- String[] range = currentSetting.split(",");
- start = Long.valueOf(range[0]);
- end = Long.valueOf(range[1]);
+ isAdvanced = property.getBooleanValue();
+ }
+ if (isAdvanced) {
+ //Advanced time settings
+ property = portletConfig.getSimple(Constant.METRIC_RANGE);
+ if (property != null) {
+ String currentSetting = property.getStringValue();
+ String[] range = currentSetting.split(",");
+ start = Long.valueOf(range[0]);
+ end = Long.valueOf(range[1]);
+ }
+ } else {
+ //Simple time settings
+ property = portletConfig.getSimple(Constant.METRIC_RANGE_LASTN);
+ if (property != null) {
+ int lastN = property.getIntegerValue();
+ property = portletConfig.getSimple(Constant.METRIC_RANGE_UNIT);
+ int lastUnits = property.getIntegerValue();
+ ArrayList<Long> beginEnd = MeasurementUtility.calculateTimeFrame(lastN, Integer.valueOf(lastUnits));
+ start = Long.valueOf(beginEnd.get(0));
+ end = Long.valueOf(beginEnd.get(1));
+ }
}
}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/resource/ResourcePkgHistoryPortlet.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/resource/ResourcePkgHistoryPortlet.java
index 6110d7e..41ce660 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/resource/ResourcePkgHistoryPortlet.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/resource/ResourcePkgHistoryPortlet.java
@@ -110,7 +110,6 @@ public class ResourcePkgHistoryPortlet extends GroupPkgHistoryPortlet {
}
PageControl pageControl = new PageControl(0, resultCount);
criteria.setPageControl(pageControl);
- // criteria.addFilterResourceGroupIds(resourceId);
criteria.addFilterResourceId(resourceId);
criteria.addSortStatus(PageOrdering.DESC);
13 years, 3 months
[rhq] 3 commits - modules/enterprise
by Jay Shaughnessy
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/selector/AbstractSelector.java | 9
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/PortletFactory.java | 15
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/inventory/groups/graph/ResourceGroupGraphPortlet.java | 201 +++++
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/inventory/resource/graph/GraphPortlet.java | 181 ----
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/inventory/resource/graph/ResourceGraphPortlet.java | 181 ++++
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/AbstractMetricGraphView.java | 351 +++++++++
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/ResourceGroupContextMenu.java | 16
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/monitoring/ResourceGroupMetricGraphView.java | 134 +++
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/AncestryUtil.java | 21
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/ResourceTreeView.java | 15
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/monitoring/GraphListView.java | 2
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/monitoring/ResourceMetricGraphView.java | 156 ++++
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/monitoring/ResourceScheduledMetricDatasource.java | 19
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/monitoring/SmallGraphView.java | 380 ----------
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/selection/ResourceGroupSelector.java | 42 -
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/selection/SingleResourceGroupSelector.java | 65 +
modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages.properties | 6
modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_de.properties | 3
18 files changed, 1201 insertions(+), 596 deletions(-)
New commits:
commit 41b30a2488ec12255afacb9a293b99a7b2553df5
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Mon Mar 21 17:54:27 2011 -0400
Metric Graph Portlet Work
Fix issues with adding metric portlets from the resource and group
trees. In particular, add missing support for the group tree, and group
metric graphs in general.
- refactor and rename to use an AbstractMetricGraphView supporting resource
and resource group views and portlets.
- add relevant resource or group name info to the portlets so you can see
what it is the metric data actually comes from.
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/PortletFactory.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/PortletFactory.java
index 98220d7..fa76473 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/PortletFactory.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/PortletFactory.java
@@ -33,9 +33,10 @@ import org.rhq.enterprise.gui.coregui.client.dashboard.portlets.groups.GroupMetr
import org.rhq.enterprise.gui.coregui.client.dashboard.portlets.groups.GroupOobsPortlet;
import org.rhq.enterprise.gui.coregui.client.dashboard.portlets.groups.GroupOperationsPortlet;
import org.rhq.enterprise.gui.coregui.client.dashboard.portlets.groups.GroupPkgHistoryPortlet;
+import org.rhq.enterprise.gui.coregui.client.dashboard.portlets.inventory.groups.graph.ResourceGroupGraphPortlet;
import org.rhq.enterprise.gui.coregui.client.dashboard.portlets.inventory.queue.AutodiscoveryPortlet;
import org.rhq.enterprise.gui.coregui.client.dashboard.portlets.inventory.resource.FavoriteResourcesPortlet;
-import org.rhq.enterprise.gui.coregui.client.dashboard.portlets.inventory.resource.graph.GraphPortlet;
+import org.rhq.enterprise.gui.coregui.client.dashboard.portlets.inventory.resource.graph.ResourceGraphPortlet;
import org.rhq.enterprise.gui.coregui.client.dashboard.portlets.platform.PlatformSummaryPortlet;
import org.rhq.enterprise.gui.coregui.client.dashboard.portlets.recent.alerts.RecentAlertsPortlet;
import org.rhq.enterprise.gui.coregui.client.dashboard.portlets.recent.imported.RecentlyAddedResourcesPortlet;
@@ -71,8 +72,8 @@ public class PortletFactory {
private static HashMap<String, String> registeredPortletIconMap;
static {
- //############## Default Dashboard ############################
- //defines portlet factory mappings for landing page Dashboard
+ // ############# Global Dashboard ############################
+ // defines portlet factory mappings for global Dashboard
registeredPortletFactoryMap = new HashMap<String, PortletViewFactory>();
registeredPortletFactoryMap.put(InventorySummaryPortlet.KEY, InventorySummaryPortlet.Factory.INSTANCE);
registeredPortletFactoryMap.put(RecentlyAddedResourcesPortlet.KEY,
@@ -80,7 +81,8 @@ public class PortletFactory {
registeredPortletFactoryMap.put(PlatformSummaryPortlet.KEY, PlatformSummaryPortlet.Factory.INSTANCE);
registeredPortletFactoryMap.put(AutodiscoveryPortlet.KEY, AutodiscoveryPortlet.Factory.INSTANCE);
registeredPortletFactoryMap.put(RecentAlertsPortlet.KEY, RecentAlertsPortlet.Factory.INSTANCE);
- registeredPortletFactoryMap.put(GraphPortlet.KEY, GraphPortlet.Factory.INSTANCE);
+ registeredPortletFactoryMap.put(ResourceGraphPortlet.KEY, ResourceGraphPortlet.Factory.INSTANCE);
+ registeredPortletFactoryMap.put(ResourceGroupGraphPortlet.KEY, ResourceGroupGraphPortlet.Factory.INSTANCE);
registeredPortletFactoryMap.put(TagCloudPortlet.KEY, TagCloudPortlet.Factory.INSTANCE);
registeredPortletFactoryMap.put(FavoriteResourcesPortlet.KEY, FavoriteResourcesPortlet.Factory.INSTANCE);
registeredPortletFactoryMap.put(MashupPortlet.KEY, MashupPortlet.Factory.INSTANCE);
@@ -88,14 +90,15 @@ public class PortletFactory {
registeredPortletFactoryMap.put(ProblemResourcesPortlet.KEY, ProblemResourcesPortlet.Factory.INSTANCE);
registeredPortletFactoryMap.put(OperationsPortlet.KEY, OperationsPortlet.Factory.INSTANCE);
- //defines portlet name mappings for landing page Dashboard
+ // defines portlet name mappings for global Dashboard
registeredPortletNameMap = new HashMap<String, String>(registeredPortletFactoryMap.size());
registeredPortletNameMap.put(InventorySummaryPortlet.KEY, InventorySummaryPortlet.NAME);
registeredPortletNameMap.put(RecentlyAddedResourcesPortlet.KEY, RecentlyAddedResourcesPortlet.NAME);
registeredPortletNameMap.put(PlatformSummaryPortlet.KEY, PlatformSummaryPortlet.NAME);
registeredPortletNameMap.put(AutodiscoveryPortlet.KEY, AutodiscoveryPortlet.NAME);
registeredPortletNameMap.put(RecentAlertsPortlet.KEY, RecentAlertsPortlet.NAME);
- registeredPortletNameMap.put(GraphPortlet.KEY, GraphPortlet.NAME);
+ registeredPortletNameMap.put(ResourceGraphPortlet.KEY, ResourceGraphPortlet.NAME);
+ registeredPortletNameMap.put(ResourceGroupGraphPortlet.KEY, ResourceGroupGraphPortlet.NAME);
registeredPortletNameMap.put(TagCloudPortlet.KEY, TagCloudPortlet.NAME);
registeredPortletNameMap.put(FavoriteResourcesPortlet.KEY, FavoriteResourcesPortlet.NAME);
registeredPortletNameMap.put(MashupPortlet.KEY, MashupPortlet.NAME);
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/inventory/groups/graph/ResourceGroupGraphPortlet.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/inventory/groups/graph/ResourceGroupGraphPortlet.java
new file mode 100644
index 0000000..9ac2534
--- /dev/null
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/inventory/groups/graph/ResourceGroupGraphPortlet.java
@@ -0,0 +1,201 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2010 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+package org.rhq.enterprise.gui.coregui.client.dashboard.portlets.inventory.groups.graph;
+
+import com.smartgwt.client.data.Criteria;
+import com.smartgwt.client.types.Overflow;
+import com.smartgwt.client.types.TitleOrientation;
+import com.smartgwt.client.widgets.Canvas;
+import com.smartgwt.client.widgets.HTMLFlow;
+import com.smartgwt.client.widgets.Label;
+import com.smartgwt.client.widgets.form.DynamicForm;
+import com.smartgwt.client.widgets.form.events.SubmitValuesEvent;
+import com.smartgwt.client.widgets.form.events.SubmitValuesHandler;
+import com.smartgwt.client.widgets.form.fields.CanvasItem;
+import com.smartgwt.client.widgets.form.fields.SelectItem;
+import com.smartgwt.client.widgets.form.fields.SpacerItem;
+
+import org.rhq.core.domain.configuration.PropertySimple;
+import org.rhq.core.domain.dashboard.DashboardPortlet;
+import org.rhq.core.domain.resource.group.GroupCategory;
+import org.rhq.enterprise.gui.coregui.client.components.selector.AssignedItemsChangedEvent;
+import org.rhq.enterprise.gui.coregui.client.components.selector.AssignedItemsChangedHandler;
+import org.rhq.enterprise.gui.coregui.client.dashboard.CustomSettingsPortlet;
+import org.rhq.enterprise.gui.coregui.client.dashboard.Portlet;
+import org.rhq.enterprise.gui.coregui.client.dashboard.PortletViewFactory;
+import org.rhq.enterprise.gui.coregui.client.dashboard.PortletWindow;
+import org.rhq.enterprise.gui.coregui.client.inventory.groups.detail.monitoring.ResourceGroupMetricGraphView;
+import org.rhq.enterprise.gui.coregui.client.inventory.resource.detail.monitoring.ResourceScheduledMetricDatasource;
+import org.rhq.enterprise.gui.coregui.client.inventory.resource.selection.SingleResourceGroupSelector;
+import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableDynamicForm;
+
+/**
+ * @author Greg Hinkle
+ * @author Jay Shaughnessy
+ */
+public class ResourceGroupGraphPortlet extends ResourceGroupMetricGraphView implements CustomSettingsPortlet {
+
+ // A non-displayed, persisted identifier for the portlet
+ public static final String KEY = "ResourceGroupMetric";
+ // A default displayed, persisted name for the portlet
+ public static final String NAME = MSG.view_portlet_defaultName_groupMetric();
+
+ // set on initial configuration, the window for this portlet view.
+ private PortletWindow portletWindow;
+
+ public static final String CFG_RESOURCE_GROUP_ID = "resourceGroupId";
+ public static final String CFG_DEFINITION_ID = "definitionId";
+
+ public ResourceGroupGraphPortlet(String locatorId) {
+ super(locatorId);
+ setOverflow(Overflow.HIDDEN);
+ }
+
+ public void configure(PortletWindow portletWindow, DashboardPortlet storedPortlet) {
+
+ if (null == this.portletWindow && null != portletWindow) {
+ this.portletWindow = portletWindow;
+ }
+
+ if ((null == storedPortlet) || (null == storedPortlet.getConfiguration())) {
+ return;
+ }
+
+ if (storedPortlet.getConfiguration().getSimple(CFG_RESOURCE_GROUP_ID) != null) {
+ setEntityId(storedPortlet.getConfiguration().getSimple(CFG_RESOURCE_GROUP_ID).getIntegerValue());
+ setDefinitionId(storedPortlet.getConfiguration().getSimple(CFG_DEFINITION_ID).getIntegerValue());
+ }
+ }
+
+ public Canvas getHelpCanvas() {
+ return new HTMLFlow(MSG.view_portlet_help_graph());
+ }
+
+ @Override
+ protected void onDraw() {
+ DashboardPortlet storedPortlet = portletWindow.getStoredPortlet();
+
+ if (storedPortlet.getConfiguration().getSimple(CFG_RESOURCE_GROUP_ID) != null) {
+ super.onDraw();
+ } else {
+ removeMembers(getMembers());
+ addMember(new Label("<i>" + MSG.view_portlet_configure_needed() + "</i>"));
+ }
+ }
+
+ public DynamicForm getCustomSettingsForm() {
+ final LocatableDynamicForm form = new LocatableDynamicForm(extendLocatorId("Config"));
+ form.setWidth(750);
+ form.setNumCols(1);
+
+ final CanvasItem selectorItem = new CanvasItem();
+ selectorItem.setTitleOrientation(TitleOrientation.TOP);
+ selectorItem.setShowTitle(false);
+
+ final SingleResourceGroupSelector resourceGroupSelector = new SingleResourceGroupSelector(form
+ .extendLocatorId("Selector"), GroupCategory.COMPATIBLE, false);
+ resourceGroupSelector.setWidth(700);
+ resourceGroupSelector.setHeight(300);
+ //TODO, would probaby be nice to find a way to seed assigned with the current group
+ //ListGridRecord rec = new ListGridRecord();
+ //rec.setAttribute("id", getEntityId());
+ //rec.setAttribute("name", "current");
+ //resourceGroupSelector.setAssigned(new ListGridRecord[] { rec });
+
+ final SelectItem metric = new SelectItem(CFG_DEFINITION_ID, MSG.common_title_metric()) {
+ @Override
+ protected Criteria getPickListFilterCriteria() {
+ Criteria criteria = new Criteria();
+
+ if (resourceGroupSelector.getSelectedItems().size() == 1) {
+ int groupId = resourceGroupSelector.getSelectedItems().iterator().next().getId();
+ criteria.addCriteria(CFG_RESOURCE_GROUP_ID, groupId);
+ form.setValue(CFG_RESOURCE_GROUP_ID, groupId);
+ }
+ return criteria;
+ }
+ };
+ metric.setWidth(300);
+ metric.setTitleOrientation(TitleOrientation.TOP);
+ metric.setValueField("id");
+ metric.setDisplayField("displayName");
+ metric.setOptionDataSource(new ResourceScheduledMetricDatasource());
+
+ resourceGroupSelector.addAssignedItemsChangedHandler(new AssignedItemsChangedHandler() {
+
+ public void onSelectionChanged(AssignedItemsChangedEvent event) {
+
+ if (resourceGroupSelector.getSelectedItems().size() == 1) {
+ metric.fetchData();
+ form.clearValue(CFG_DEFINITION_ID);
+ }
+ }
+ });
+
+ final DashboardPortlet storedPortlet = portletWindow.getStoredPortlet();
+
+ if (storedPortlet.getConfiguration().getSimple(CFG_RESOURCE_GROUP_ID) != null) {
+ form.setValue(CFG_RESOURCE_GROUP_ID, storedPortlet.getConfiguration().getSimple(CFG_RESOURCE_GROUP_ID)
+ .getIntegerValue());
+ form.setValue(CFG_DEFINITION_ID, storedPortlet.getConfiguration().getSimple(CFG_DEFINITION_ID)
+ .getIntegerValue());
+ }
+
+ selectorItem.setCanvas(resourceGroupSelector);
+ form.setFields(selectorItem, metric, new SpacerItem());
+
+ form.addSubmitValuesHandler(new SubmitValuesHandler() {
+ public void onSubmitValues(SubmitValuesEvent submitValuesEvent) {
+ storedPortlet.getConfiguration().put(
+ new PropertySimple(CFG_RESOURCE_GROUP_ID, form.getValue(CFG_RESOURCE_GROUP_ID)));
+ storedPortlet.getConfiguration().put(
+ new PropertySimple(CFG_DEFINITION_ID, form.getValue(CFG_DEFINITION_ID)));
+
+ configure(portletWindow, storedPortlet);
+
+ redraw();
+ }
+ });
+
+ return form;
+ }
+
+ @Override
+ public void redraw() {
+ super.redraw();
+
+ removeMembers(getMembers());
+
+ DashboardPortlet storedPortlet = portletWindow.getStoredPortlet();
+ if (storedPortlet.getConfiguration().getSimple(CFG_RESOURCE_GROUP_ID) != null) {
+ renderGraph();
+ } else {
+ addMember(new Label("<i>" + MSG.view_portlet_configure_needed() + "</i>"));
+ }
+ }
+
+ public static final class Factory implements PortletViewFactory {
+ public static PortletViewFactory INSTANCE = new Factory();
+
+ public final Portlet getInstance(String locatorId) {
+
+ return new ResourceGroupGraphPortlet(locatorId);
+ }
+ }
+}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/inventory/resource/graph/GraphPortlet.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/inventory/resource/graph/GraphPortlet.java
deleted file mode 100644
index 821fe56..0000000
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/inventory/resource/graph/GraphPortlet.java
+++ /dev/null
@@ -1,181 +0,0 @@
-/*
- * RHQ Management Platform
- * Copyright (C) 2005-2010 Red Hat, Inc.
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-package org.rhq.enterprise.gui.coregui.client.dashboard.portlets.inventory.resource.graph;
-
-import com.smartgwt.client.data.Criteria;
-import com.smartgwt.client.types.Overflow;
-import com.smartgwt.client.widgets.Canvas;
-import com.smartgwt.client.widgets.HTMLFlow;
-import com.smartgwt.client.widgets.Label;
-import com.smartgwt.client.widgets.form.DynamicForm;
-import com.smartgwt.client.widgets.form.events.SubmitValuesEvent;
-import com.smartgwt.client.widgets.form.events.SubmitValuesHandler;
-import com.smartgwt.client.widgets.form.fields.SelectItem;
-import com.smartgwt.client.widgets.form.fields.events.ChangedEvent;
-
-import org.rhq.core.domain.configuration.PropertySimple;
-import org.rhq.core.domain.dashboard.DashboardPortlet;
-import org.rhq.enterprise.gui.coregui.client.components.lookup.ResourceLookupComboBoxItem;
-import org.rhq.enterprise.gui.coregui.client.dashboard.CustomSettingsPortlet;
-import org.rhq.enterprise.gui.coregui.client.dashboard.Portlet;
-import org.rhq.enterprise.gui.coregui.client.dashboard.PortletViewFactory;
-import org.rhq.enterprise.gui.coregui.client.dashboard.PortletWindow;
-import org.rhq.enterprise.gui.coregui.client.inventory.resource.detail.monitoring.ResourceScheduledMetricDatasource;
-import org.rhq.enterprise.gui.coregui.client.inventory.resource.detail.monitoring.SmallGraphView;
-
-/**
- * @author Greg Hinkle
- */
-public class GraphPortlet extends SmallGraphView implements CustomSettingsPortlet {
-
- // A non-displayed, persisted identifier for the portlet
- public static final String KEY = "Graph";
- // A default displayed, persisted name for the portlet
- public static final String NAME = MSG.view_portlet_defaultName_graph();
-
- // set on initial configuration, the window for this portlet view.
- private PortletWindow portletWindow;
-
- public static final String CFG_RESOURCE_ID = "resourceId";
- public static final String CFG_DEFINITION_ID = "definitionId";
- public static final String CFG_RESOURCE_GROUP_ID = "resourceGroupId";
-
- public GraphPortlet(String locatorId) {
- super(locatorId);
- setOverflow(Overflow.HIDDEN);
- }
-
- public void configure(PortletWindow portletWindow, DashboardPortlet storedPortlet) {
-
- if (null == this.portletWindow && null != portletWindow) {
- this.portletWindow = portletWindow;
- }
-
- if ((null == storedPortlet) || (null == storedPortlet.getConfiguration())) {
- return;
- }
-
- if (storedPortlet.getConfiguration().getSimple(CFG_RESOURCE_ID) != null) {
- setResourceId(storedPortlet.getConfiguration().getSimple(CFG_RESOURCE_ID).getIntegerValue());
- setDefinitionId(storedPortlet.getConfiguration().getSimple(CFG_DEFINITION_ID).getIntegerValue());
- }
- }
-
- public Canvas getHelpCanvas() {
- return new HTMLFlow(MSG.view_portlet_help_graph());
- }
-
- @Override
- protected void onDraw() {
- DashboardPortlet storedPortlet = portletWindow.getStoredPortlet();
-
- if (storedPortlet.getConfiguration().getSimple(CFG_RESOURCE_ID) != null) {
- super.onDraw();
- } else {
- removeMembers(getMembers());
- addMember(new Label("<i>" + MSG.view_portlet_configure_needed() + "</i>"));
- }
- }
-
- public DynamicForm getCustomSettingsForm() {
- final DynamicForm form = new DynamicForm();
-
- final ResourceLookupComboBoxItem resourceLookupComboBoxItem = new ResourceLookupComboBoxItem(CFG_RESOURCE_ID,
- MSG.common_title_resource());
- resourceLookupComboBoxItem.setWidth(300);
-
- final SelectItem metric = new SelectItem(CFG_DEFINITION_ID, MSG.common_title_metric()) {
- @Override
- protected Criteria getPickListFilterCriteria() {
- Criteria criteria = new Criteria();
-
- if (resourceLookupComboBoxItem.getValue() != null) {
- int resourceId = (Integer) resourceLookupComboBoxItem.getValue();
- criteria.addCriteria(CFG_RESOURCE_ID, resourceId);
- }
- return criteria;
- }
- };
-
- final DashboardPortlet storedPortlet = portletWindow.getStoredPortlet();
-
- metric.setWidth(300);
- metric.setValueField("id");
- metric.setDisplayField("displayName");
- metric.setOptionDataSource(new ResourceScheduledMetricDatasource());
-
- resourceLookupComboBoxItem
- .addChangedHandler(new com.smartgwt.client.widgets.form.fields.events.ChangedHandler() {
- public void onChanged(ChangedEvent event) {
-
- if (form.getValue(CFG_RESOURCE_ID) instanceof Integer) {
- metric.fetchData();
- form.clearValue("defininitionId");
- }
- }
- });
-
- if (storedPortlet.getConfiguration().getSimple(CFG_RESOURCE_ID) != null) {
- form.setValue(CFG_RESOURCE_ID, storedPortlet.getConfiguration().getSimple(CFG_RESOURCE_ID)
- .getIntegerValue());
- form.setValue(CFG_DEFINITION_ID, storedPortlet.getConfiguration().getSimple(CFG_DEFINITION_ID)
- .getIntegerValue());
- }
-
- form.setFields(resourceLookupComboBoxItem, metric);
-
- form.addSubmitValuesHandler(new SubmitValuesHandler() {
- public void onSubmitValues(SubmitValuesEvent submitValuesEvent) {
- storedPortlet.getConfiguration().put(
- new PropertySimple(CFG_RESOURCE_ID, form.getValue(CFG_RESOURCE_ID)));
- storedPortlet.getConfiguration().put(
- new PropertySimple(CFG_DEFINITION_ID, form.getValue(CFG_DEFINITION_ID)));
-
- configure(portletWindow, storedPortlet);
-
- redraw();
- }
- });
-
- return form;
- }
-
- @Override
- public void redraw() {
- super.redraw();
-
- removeMembers(getMembers());
-
- DashboardPortlet storedPortlet = portletWindow.getStoredPortlet();
- if (storedPortlet.getConfiguration().getSimple(CFG_RESOURCE_ID) != null) {
- renderGraph();
- } else {
- addMember(new Label("<i>" + MSG.view_portlet_configure_needed() + "</i>"));
- }
- }
-
- public static final class Factory implements PortletViewFactory {
- public static PortletViewFactory INSTANCE = new Factory();
-
- public final Portlet getInstance(String locatorId) {
-
- return new GraphPortlet(locatorId);
- }
- }
-}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/inventory/resource/graph/ResourceGraphPortlet.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/inventory/resource/graph/ResourceGraphPortlet.java
new file mode 100644
index 0000000..820cf4f
--- /dev/null
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/inventory/resource/graph/ResourceGraphPortlet.java
@@ -0,0 +1,181 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2010 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+package org.rhq.enterprise.gui.coregui.client.dashboard.portlets.inventory.resource.graph;
+
+import com.smartgwt.client.data.Criteria;
+import com.smartgwt.client.types.Overflow;
+import com.smartgwt.client.widgets.Canvas;
+import com.smartgwt.client.widgets.HTMLFlow;
+import com.smartgwt.client.widgets.Label;
+import com.smartgwt.client.widgets.form.DynamicForm;
+import com.smartgwt.client.widgets.form.events.SubmitValuesEvent;
+import com.smartgwt.client.widgets.form.events.SubmitValuesHandler;
+import com.smartgwt.client.widgets.form.fields.SelectItem;
+import com.smartgwt.client.widgets.form.fields.events.ChangedEvent;
+
+import org.rhq.core.domain.configuration.PropertySimple;
+import org.rhq.core.domain.dashboard.DashboardPortlet;
+import org.rhq.enterprise.gui.coregui.client.components.lookup.ResourceLookupComboBoxItem;
+import org.rhq.enterprise.gui.coregui.client.dashboard.CustomSettingsPortlet;
+import org.rhq.enterprise.gui.coregui.client.dashboard.Portlet;
+import org.rhq.enterprise.gui.coregui.client.dashboard.PortletViewFactory;
+import org.rhq.enterprise.gui.coregui.client.dashboard.PortletWindow;
+import org.rhq.enterprise.gui.coregui.client.inventory.resource.detail.monitoring.ResourceMetricGraphView;
+import org.rhq.enterprise.gui.coregui.client.inventory.resource.detail.monitoring.ResourceScheduledMetricDatasource;
+
+/**
+ * @author Greg Hinkle
+ * @author Jay Shaughnessy
+ */
+public class ResourceGraphPortlet extends ResourceMetricGraphView implements CustomSettingsPortlet {
+
+ // A non-displayed, persisted identifier for the portlet
+ public static final String KEY = "ResourceMetric";
+ // A default displayed, persisted name for the portlet
+ public static final String NAME = MSG.view_portlet_defaultName_resourceMetric();
+
+ // set on initial configuration, the window for this portlet view.
+ private PortletWindow portletWindow;
+
+ public static final String CFG_RESOURCE_ID = "resourceId";
+ public static final String CFG_DEFINITION_ID = "definitionId";
+
+ public ResourceGraphPortlet(String locatorId) {
+ super(locatorId);
+ setOverflow(Overflow.HIDDEN);
+ }
+
+ public void configure(PortletWindow portletWindow, DashboardPortlet storedPortlet) {
+
+ if (null == this.portletWindow && null != portletWindow) {
+ this.portletWindow = portletWindow;
+ }
+
+ if ((null == storedPortlet) || (null == storedPortlet.getConfiguration())) {
+ return;
+ }
+
+ if (storedPortlet.getConfiguration().getSimple(CFG_RESOURCE_ID) != null) {
+ setEntityId(storedPortlet.getConfiguration().getSimple(CFG_RESOURCE_ID).getIntegerValue());
+ setDefinitionId(storedPortlet.getConfiguration().getSimple(CFG_DEFINITION_ID).getIntegerValue());
+ }
+ }
+
+ public Canvas getHelpCanvas() {
+ return new HTMLFlow(MSG.view_portlet_help_graph());
+ }
+
+ @Override
+ protected void onDraw() {
+ DashboardPortlet storedPortlet = portletWindow.getStoredPortlet();
+
+ if (storedPortlet.getConfiguration().getSimple(CFG_RESOURCE_ID) != null) {
+ super.onDraw();
+ } else {
+ removeMembers(getMembers());
+ addMember(new Label("<i>" + MSG.view_portlet_configure_needed() + "</i>"));
+ }
+ }
+
+ public DynamicForm getCustomSettingsForm() {
+ final DynamicForm form = new DynamicForm();
+
+ final ResourceLookupComboBoxItem resourceLookupComboBoxItem = new ResourceLookupComboBoxItem(CFG_RESOURCE_ID,
+ MSG.common_title_resource());
+ resourceLookupComboBoxItem.setWidth(300);
+
+ final SelectItem metric = new SelectItem(CFG_DEFINITION_ID, MSG.common_title_metric()) {
+ @Override
+ protected Criteria getPickListFilterCriteria() {
+ Criteria criteria = new Criteria();
+
+ if (resourceLookupComboBoxItem.getValue() != null) {
+ int resourceId = (Integer) resourceLookupComboBoxItem.getValue();
+ criteria.addCriteria(CFG_RESOURCE_ID, resourceId);
+ }
+ return criteria;
+ }
+ };
+
+ final DashboardPortlet storedPortlet = portletWindow.getStoredPortlet();
+
+ metric.setWidth(300);
+ metric.setValueField("id");
+ metric.setDisplayField("displayName");
+ metric.setOptionDataSource(new ResourceScheduledMetricDatasource());
+
+ resourceLookupComboBoxItem
+ .addChangedHandler(new com.smartgwt.client.widgets.form.fields.events.ChangedHandler() {
+ public void onChanged(ChangedEvent event) {
+
+ if (form.getValue(CFG_RESOURCE_ID) instanceof Integer) {
+ metric.fetchData();
+ form.clearValue(CFG_DEFINITION_ID);
+ }
+ }
+ });
+
+ if (storedPortlet.getConfiguration().getSimple(CFG_RESOURCE_ID) != null) {
+ form.setValue(CFG_RESOURCE_ID, storedPortlet.getConfiguration().getSimple(CFG_RESOURCE_ID)
+ .getIntegerValue());
+ form.setValue(CFG_DEFINITION_ID, storedPortlet.getConfiguration().getSimple(CFG_DEFINITION_ID)
+ .getIntegerValue());
+ }
+
+ form.setFields(resourceLookupComboBoxItem, metric);
+
+ form.addSubmitValuesHandler(new SubmitValuesHandler() {
+ public void onSubmitValues(SubmitValuesEvent submitValuesEvent) {
+ storedPortlet.getConfiguration().put(
+ new PropertySimple(CFG_RESOURCE_ID, form.getValue(CFG_RESOURCE_ID)));
+ storedPortlet.getConfiguration().put(
+ new PropertySimple(CFG_DEFINITION_ID, form.getValue(CFG_DEFINITION_ID)));
+
+ configure(portletWindow, storedPortlet);
+
+ redraw();
+ }
+ });
+
+ return form;
+ }
+
+ @Override
+ public void redraw() {
+ super.redraw();
+
+ removeMembers(getMembers());
+
+ DashboardPortlet storedPortlet = portletWindow.getStoredPortlet();
+ if (storedPortlet.getConfiguration().getSimple(CFG_RESOURCE_ID) != null) {
+ renderGraph();
+ } else {
+ addMember(new Label("<i>" + MSG.view_portlet_configure_needed() + "</i>"));
+ }
+ }
+
+ public static final class Factory implements PortletViewFactory {
+ public static PortletViewFactory INSTANCE = new Factory();
+
+ public final Portlet getInstance(String locatorId) {
+
+ return new ResourceGraphPortlet(locatorId);
+ }
+ }
+}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/AbstractMetricGraphView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/AbstractMetricGraphView.java
new file mode 100644
index 0000000..6c9b167
--- /dev/null
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/AbstractMetricGraphView.java
@@ -0,0 +1,351 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2010 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+package org.rhq.enterprise.gui.coregui.client.inventory.common;
+
+import java.util.Date;
+import java.util.List;
+
+import ca.nanometrics.gflot.client.Axis;
+import ca.nanometrics.gflot.client.DataPoint;
+import ca.nanometrics.gflot.client.PlotItem;
+import ca.nanometrics.gflot.client.PlotModel;
+import ca.nanometrics.gflot.client.PlotPosition;
+import ca.nanometrics.gflot.client.SeriesHandler;
+import ca.nanometrics.gflot.client.SimplePlot;
+import ca.nanometrics.gflot.client.event.PlotHoverListener;
+import ca.nanometrics.gflot.client.jsni.Plot;
+import ca.nanometrics.gflot.client.options.AxisOptions;
+import ca.nanometrics.gflot.client.options.GridOptions;
+import ca.nanometrics.gflot.client.options.LineSeriesOptions;
+import ca.nanometrics.gflot.client.options.PlotOptions;
+import ca.nanometrics.gflot.client.options.PointsSeriesOptions;
+import ca.nanometrics.gflot.client.options.TickFormatter;
+
+import com.google.gwt.i18n.client.DateTimeFormat;
+import com.smartgwt.client.types.AnimationEffect;
+import com.smartgwt.client.widgets.HTMLFlow;
+import com.smartgwt.client.widgets.Img;
+import com.smartgwt.client.widgets.Label;
+import com.smartgwt.client.widgets.Window;
+import com.smartgwt.client.widgets.events.ClickEvent;
+import com.smartgwt.client.widgets.events.ClickHandler;
+import com.smartgwt.client.widgets.events.MouseOutEvent;
+import com.smartgwt.client.widgets.events.MouseOutHandler;
+import com.smartgwt.client.widgets.layout.HLayout;
+
+import org.rhq.core.domain.measurement.MeasurementDefinition;
+import org.rhq.core.domain.measurement.composite.MeasurementDataNumericHighLowComposite;
+import org.rhq.enterprise.gui.coregui.client.util.MeasurementConverterClient;
+import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableHLayout;
+import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableImg;
+import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableVLayout;
+import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableWidgetCanvas;
+
+/**
+ * @author Greg Hinkle
+ * @author Jay Shaughnessy
+ */
+public abstract class AbstractMetricGraphView extends LocatableVLayout {
+
+ private static final String INSTRUCTIONS = MSG.view_resource_monitor_graph_instructions();
+
+ /*
+ private static final String[] MONTH_NAMES = { MSG.common_calendar_january_short(),
+ MSG.common_calendar_february_short(), MSG.common_calendar_march_short(), MSG.common_calendar_april_short(),
+ MSG.common_calendar_may_short(), MSG.common_calendar_june_short(), MSG.common_calendar_july_short(),
+ MSG.common_calendar_august_short(), MSG.common_calendar_september_short(), MSG.common_calendar_october_short(),
+ MSG.common_calendar_november_short(), MSG.common_calendar_december_short() };
+ */
+
+ private final Label selectedPointLabel = new Label(INSTRUCTIONS);
+ private final Label positionLabel = new Label();
+ private final Label hoverLabel = new Label();
+
+ private int entityId;
+ private int definitionId;
+
+ private MeasurementDefinition definition;
+ private List<MeasurementDataNumericHighLowComposite> data;
+
+ public AbstractMetricGraphView(String locatorId) {
+ super(locatorId);
+ }
+
+ public AbstractMetricGraphView(String locatorId, int entityId, int definitionId) {
+ this(locatorId);
+
+ this.entityId = entityId;
+ this.definitionId = definitionId;
+ }
+
+ public AbstractMetricGraphView(String locatorId, int entityId, MeasurementDefinition def,
+ List<MeasurementDataNumericHighLowComposite> data) {
+ this(locatorId);
+
+ this.entityId = entityId;
+ this.definition = def;
+ this.data = data;
+ setHeight100();
+ setWidth100();
+ }
+
+ public abstract AbstractMetricGraphView getInstance(String locatorId, int entityId, MeasurementDefinition def,
+ List<MeasurementDataNumericHighLowComposite> data);
+
+ protected abstract void renderGraph();
+
+ protected abstract HTMLFlow getEntityTitle();
+
+ public int getEntityId() {
+ return this.entityId;
+ }
+
+ public void setEntityId(int entityId) {
+ this.entityId = entityId;
+ this.definition = null;
+ }
+
+ public int getDefinitionId() {
+ return definitionId;
+ }
+
+ public void setDefinitionId(int definitionId) {
+ this.definitionId = definitionId;
+ this.definition = null;
+ }
+
+ public MeasurementDefinition getDefinition() {
+ return definition;
+ }
+
+ public void setDefinition(MeasurementDefinition definition) {
+ this.definition = definition;
+ }
+
+ public List<MeasurementDataNumericHighLowComposite> getData() {
+ return data;
+ }
+
+ public void setData(List<MeasurementDataNumericHighLowComposite> data) {
+ this.data = data;
+ }
+
+ @Override
+ protected void onDraw() {
+ super.onDraw();
+ removeMembers(getMembers());
+ renderGraph();
+ }
+
+ @Override
+ public void parentResized() {
+ super.parentResized();
+ removeMembers(getMembers());
+ renderGraph();
+ }
+
+ protected void drawGraph() {
+
+ HLayout titleHLayout = new LocatableHLayout(extendLocatorId("HTitle"));
+
+ if (definition != null) {
+ titleHLayout.setAutoHeight();
+ titleHLayout.setWidth100();
+
+ HTMLFlow entityTitle = getEntityTitle();
+ if (null != entityTitle) {
+ entityTitle.setWidth("*");
+ titleHLayout.addMember(entityTitle);
+ }
+
+ if (supportsLiveGraphViewDialog()) {
+ Img liveGraph = new LocatableImg(extendLocatorId("Live"), "subsystems/monitor/Monitor_16.png", 16, 16);
+ liveGraph.setTooltip(MSG.view_resource_monitor_graph_live_tooltip());
+
+ liveGraph.addClickHandler(new ClickHandler() {
+ public void onClick(ClickEvent clickEvent) {
+ displayLiveGraphViewDialog();
+ }
+ });
+ titleHLayout.addMember(liveGraph);
+ }
+
+ addMember(titleHLayout);
+
+ HTMLFlow title = new HTMLFlow("<b>" + definition.getDisplayName() + "</b> " + definition.getDescription());
+ title.setWidth100();
+ title.addClickHandler(new ClickHandler() {
+ public void onClick(ClickEvent clickEvent) {
+ displayAsDialog(extendLocatorId("Dialog"));
+ }
+ });
+ addMember(title);
+ }
+
+ PlotModel model = new PlotModel();
+ PlotOptions plotOptions = new PlotOptions();
+ plotOptions.setDefaultLineSeriesOptions(new LineSeriesOptions().setLineWidth(1).setShow(true));
+ plotOptions.setDefaultPointsOptions(new PointsSeriesOptions().setRadius(2).setShow(true));
+ plotOptions.setDefaultShadowSize(0);
+
+ // You need make the grid hoverable <<<<<<<<<
+ plotOptions
+ .setGridOptions(new GridOptions().setHoverable(true).setMouseActiveRadius(10).setAutoHighlight(true));
+
+ // create a series
+ if (definition != null && data != null) {
+ loadData(model, plotOptions);
+ }
+
+ // create the plot
+ SimplePlot plot = new SimplePlot(model, plotOptions);
+ plot.setSize(String.valueOf(getInnerContentWidth()), String.valueOf(getInnerContentHeight()
+ - titleHLayout.getHeight() - 50));
+ // "80%","80%");
+
+ // add hover listener
+ plot.addHoverListener(new PlotHoverListener() {
+ public void onPlotHover(Plot plot, PlotPosition position, PlotItem item) {
+ if (position != null) {
+ positionLabel.setContents("position: (" + position.getX() + "," + position.getY() + ")");
+ }
+ if (item != null) {
+ hoverLabel.setContents(getHover(item));
+
+ hoverLabel.animateShow(AnimationEffect.FADE);
+ if (hoverLabel.getLeft() > 0 || hoverLabel.getTop() > 0) {
+ hoverLabel.animateMove(item.getPageX() + 10, item.getPageY() - 35);
+ } else {
+ hoverLabel.moveTo(item.getPageX() + 10, item.getPageY() - 35);
+ }
+ hoverLabel.redraw();
+
+ selectedPointLabel.setContents("x: " + item.getDataPoint().getX() + ", y: "
+ + item.getDataPoint().getY());
+ } else {
+ hoverLabel.animateHide(AnimationEffect.FADE);
+ selectedPointLabel.setContents(INSTRUCTIONS);
+ }
+ }
+ }, false);
+
+ addMouseOutHandler(new MouseOutHandler() {
+ public void onMouseOut(MouseOutEvent mouseOutEvent) {
+ hoverLabel.animateHide(AnimationEffect.FADE);
+ }
+ });
+
+ hoverLabel.setOpacity(80);
+ hoverLabel.setWrap(false);
+ hoverLabel.setHeight(25);
+ hoverLabel.setBackgroundColor("yellow");
+ hoverLabel.setBorder("1px solid orange");
+ hoverLabel.hide();
+
+ if (hoverLabel.isDrawn())
+ hoverLabel.redraw();
+ else
+ hoverLabel.draw();
+
+ // put it on a panel
+
+ addMember(new LocatableWidgetCanvas(extendLocatorId("Plot"), plot));
+
+ plot.setSize(String.valueOf(getInnerContentWidth()), String.valueOf(getInnerContentHeight()
+ - titleHLayout.getHeight() - 50));
+
+ }
+
+ protected boolean supportsLiveGraphViewDialog() {
+ return false;
+ }
+
+ protected void displayLiveGraphViewDialog() {
+ return;
+ }
+
+ @Override
+ public void destroy() {
+ hoverLabel.destroy();
+ super.destroy();
+ }
+
+ @Override
+ public void hide() {
+ super.hide();
+ hoverLabel.hide();
+ }
+
+ protected String getHover(PlotItem item) {
+ if (definition != null) {
+ com.google.gwt.i18n.client.DateTimeFormat df = DateTimeFormat.getMediumDateTimeFormat();
+ return definition.getDisplayName() + ": "
+ + MeasurementConverterClient.format(item.getDataPoint().getY(), definition.getUnits(), true) + "<br/>"
+ + df.format(new Date((long) item.getDataPoint().getX()));
+ } else {
+ return "x: " + item.getDataPoint().getX() + ", y: " + item.getDataPoint().getY();
+ }
+ }
+
+ protected void loadData(PlotModel model, PlotOptions plotOptions) {
+ SeriesHandler handler = model.addSeries(definition.getDisplayName(), "#007f00");
+
+ for (MeasurementDataNumericHighLowComposite d : data) {
+ handler.add(new DataPoint(d.getTimestamp(), d.getValue()));
+ }
+
+ plotOptions.setYAxisOptions(new AxisOptions().setTicks(5).setLabelWidth(70).setTickFormatter(
+ new TickFormatter() {
+ public String formatTickValue(double v, Axis axis) {
+ return MeasurementConverterClient.format(v, definition.getUnits(), true);
+ }
+ }));
+
+ long max = System.currentTimeMillis();
+ long min = max - (1000L * 60 * 60 * 8);
+
+ int xTicks = getWidth() / 140;
+
+ plotOptions.setXAxisOptions(new AxisOptions().setTicks(xTicks).setMinimum(min).setMaximum(max)
+ .setTickFormatter(new TickFormatter() {
+ public String formatTickValue(double tickValue, Axis axis) {
+ com.google.gwt.i18n.client.DateTimeFormat dateFormat = DateTimeFormat.getShortDateTimeFormat();
+ return dateFormat.format(new Date((long) tickValue));
+ // return String.valueOf(new Date((long) tickValue));
+ // return MONTH_NAMES[(int) (tickValue - 1)];
+ }
+ }));
+
+ }
+
+ private void displayAsDialog(String locatorId) {
+ AbstractMetricGraphView graph = getInstance(locatorId, entityId, definition, data);
+ Window graphPopup = new Window();
+ graphPopup.setTitle(MSG.view_resource_monitor_detailed_graph_label());
+ graphPopup.setWidth(800);
+ graphPopup.setHeight(400);
+ graphPopup.setIsModal(true);
+ graphPopup.setShowModalMask(true);
+ graphPopup.setCanDragResize(true);
+ graphPopup.centerInPage();
+ graphPopup.addItem(graph);
+ graphPopup.show();
+ }
+
+}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/ResourceGroupContextMenu.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/ResourceGroupContextMenu.java
index 65d4c88..43b3700 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/ResourceGroupContextMenu.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/ResourceGroupContextMenu.java
@@ -44,7 +44,7 @@ import org.rhq.core.domain.resource.group.composite.ResourceGroupComposite;
import org.rhq.core.domain.util.PageList;
import org.rhq.enterprise.gui.coregui.client.CoreGUI;
import org.rhq.enterprise.gui.coregui.client.LinkManager;
-import org.rhq.enterprise.gui.coregui.client.dashboard.portlets.inventory.resource.graph.GraphPortlet;
+import org.rhq.enterprise.gui.coregui.client.dashboard.portlets.inventory.groups.graph.ResourceGroupGraphPortlet;
import org.rhq.enterprise.gui.coregui.client.gwt.GWTServiceLookup;
import org.rhq.enterprise.gui.coregui.client.inventory.resource.type.ResourceTypeRepository;
import org.rhq.enterprise.gui.coregui.client.util.message.Message;
@@ -291,12 +291,16 @@ public class ResourceGroupContextMenu extends LocatableMenu {
addToDBItem.addClickHandler(new ClickHandler() {
public void onClick(MenuItemClickEvent menuItemClickEvent) {
- DashboardPortlet p = new DashboardPortlet(def.getDisplayName() + " "
- + MSG.view_tree_common_contextMenu_chart(), GraphPortlet.KEY, 250);
+ DashboardPortlet p = new DashboardPortlet(MSG
+ .view_tree_common_contextMenu_groupGraph(), ResourceGroupGraphPortlet.KEY,
+ 250);
p.getConfiguration().put(
- new PropertySimple(GraphPortlet.CFG_RESOURCE_GROUP_ID, group.getId()));
- p.getConfiguration().put(
- new PropertySimple(GraphPortlet.CFG_DEFINITION_ID, def.getId()));
+ new PropertySimple(ResourceGroupGraphPortlet.CFG_RESOURCE_GROUP_ID, group
+ .getId()));
+ p.getConfiguration()
+ .put(
+ new PropertySimple(ResourceGroupGraphPortlet.CFG_DEFINITION_ID, def
+ .getId()));
d.addPortlet(p);
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/monitoring/ResourceGroupMetricGraphView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/monitoring/ResourceGroupMetricGraphView.java
new file mode 100644
index 0000000..61a30ce
--- /dev/null
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/monitoring/ResourceGroupMetricGraphView.java
@@ -0,0 +1,134 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2010 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+package org.rhq.enterprise.gui.coregui.client.inventory.groups.detail.monitoring;
+
+import java.util.EnumSet;
+import java.util.List;
+
+import com.google.gwt.user.client.rpc.AsyncCallback;
+import com.smartgwt.client.widgets.HTMLFlow;
+
+import org.rhq.core.domain.criteria.ResourceGroupCriteria;
+import org.rhq.core.domain.measurement.MeasurementDefinition;
+import org.rhq.core.domain.measurement.composite.MeasurementDataNumericHighLowComposite;
+import org.rhq.core.domain.resource.ResourceType;
+import org.rhq.core.domain.resource.group.ResourceGroup;
+import org.rhq.core.domain.util.PageList;
+import org.rhq.enterprise.gui.coregui.client.CoreGUI;
+import org.rhq.enterprise.gui.coregui.client.LinkManager;
+import org.rhq.enterprise.gui.coregui.client.gwt.GWTServiceLookup;
+import org.rhq.enterprise.gui.coregui.client.gwt.ResourceGroupGWTServiceAsync;
+import org.rhq.enterprise.gui.coregui.client.inventory.common.AbstractMetricGraphView;
+import org.rhq.enterprise.gui.coregui.client.inventory.resource.type.ResourceTypeRepository;
+import org.rhq.enterprise.gui.coregui.client.util.selenium.SeleniumUtility;
+
+/**
+ * @author Greg Hinkle
+ * @author Jay Shaughnessy
+ */
+public class ResourceGroupMetricGraphView extends AbstractMetricGraphView {
+
+ private HTMLFlow resourceGroupTitle;
+
+ public ResourceGroupMetricGraphView(String locatorId) {
+ super(locatorId);
+ }
+
+ public ResourceGroupMetricGraphView(String locatorId, int groupId, int definitionId) {
+ super(locatorId, groupId, definitionId);
+ }
+
+ public ResourceGroupMetricGraphView(String locatorId, int groupId, MeasurementDefinition def,
+ List<MeasurementDataNumericHighLowComposite> data) {
+
+ super(locatorId, groupId, def, data);
+ }
+
+ protected HTMLFlow getEntityTitle() {
+ return resourceGroupTitle;
+ }
+
+ protected void renderGraph() {
+ if (null == getDefinition()) {
+
+ ResourceGroupGWTServiceAsync groupService = GWTServiceLookup.getResourceGroupService();
+
+ ResourceGroupCriteria criteria = new ResourceGroupCriteria();
+ criteria.addFilterId(getEntityId());
+ criteria.fetchResourceType(true);
+ groupService.findResourceGroupsByCriteria(criteria, new AsyncCallback<PageList<ResourceGroup>>() {
+ public void onFailure(Throwable caught) {
+ CoreGUI.getErrorHandler().handleError(MSG.view_resource_monitor_graphs_lookupFailed(), caught);
+ }
+
+ public void onSuccess(PageList<ResourceGroup> result) {
+ if (result.isEmpty()) {
+ return;
+ }
+
+ final ResourceGroup group = result.get(0);
+ String url = LinkManager.getResourceGroupLink(group.getId());
+ resourceGroupTitle = new HTMLFlow(SeleniumUtility.getLocatableHref(url, group.getName(), null));
+
+ ResourceTypeRepository.Cache.getInstance().getResourceTypes(group.getResourceType().getId(),
+ EnumSet.of(ResourceTypeRepository.MetadataType.measurements),
+ new ResourceTypeRepository.TypeLoadedCallback() {
+ public void onTypesLoaded(final ResourceType type) {
+
+ for (MeasurementDefinition def : type.getMetricDefinitions()) {
+ if (def.getId() == getDefinitionId()) {
+ setDefinition(def);
+
+ GWTServiceLookup.getMeasurementDataService().findDataForCompatibleGroup(
+ getEntityId(), new int[] { getDefinitionId() },
+ System.currentTimeMillis() - (1000L * 60 * 60 * 8),
+ System.currentTimeMillis(), 60,
+ new AsyncCallback<List<List<MeasurementDataNumericHighLowComposite>>>() {
+ public void onFailure(Throwable caught) {
+ CoreGUI.getErrorHandler().handleError(
+ MSG.view_resource_monitor_graphs_loadFailed(), caught);
+ }
+
+ public void onSuccess(
+ List<List<MeasurementDataNumericHighLowComposite>> result) {
+ setData(result.get(0));
+
+ drawGraph();
+ }
+ });
+ }
+ }
+ }
+ });
+ }
+ });
+
+ } else {
+
+ drawGraph();
+ }
+ }
+
+ @Override
+ public AbstractMetricGraphView getInstance(String locatorId, int entityId, MeasurementDefinition def,
+ List<MeasurementDataNumericHighLowComposite> data) {
+
+ return new ResourceGroupMetricGraphView(locatorId, entityId, def, data);
+ }
+}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/ResourceTreeView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/ResourceTreeView.java
index cf34caf..9870a42 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/ResourceTreeView.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/ResourceTreeView.java
@@ -71,7 +71,7 @@ import org.rhq.enterprise.gui.coregui.client.CoreGUI;
import org.rhq.enterprise.gui.coregui.client.LinkManager;
import org.rhq.enterprise.gui.coregui.client.ViewId;
import org.rhq.enterprise.gui.coregui.client.ViewPath;
-import org.rhq.enterprise.gui.coregui.client.dashboard.portlets.inventory.resource.graph.GraphPortlet;
+import org.rhq.enterprise.gui.coregui.client.dashboard.portlets.inventory.resource.graph.ResourceGraphPortlet;
import org.rhq.enterprise.gui.coregui.client.gwt.GWTServiceLookup;
import org.rhq.enterprise.gui.coregui.client.gwt.ResourceGWTServiceAsync;
import org.rhq.enterprise.gui.coregui.client.gwt.ResourceGroupGWTServiceAsync;
@@ -421,8 +421,9 @@ public class ResourceTreeView extends LocatableVLayout {
MenuItem operationItem = new MenuItem(operationDefinition.getDisplayName());
operationItem.addClickHandler(new ClickHandler() {
public void onClick(MenuItemClickEvent event) {
- CoreGUI.goToView(LinkManager.getResourceTabLink(resource.getId(), ResourceDetailView.Tab.OPERATIONS,
- ResourceDetailView.OperationsSubTab.SCHEDULES) + "/0/" + operationDefinition.getId());
+ CoreGUI.goToView(LinkManager.getResourceTabLink(resource.getId(),
+ ResourceDetailView.Tab.OPERATIONS, ResourceDetailView.OperationsSubTab.SCHEDULES)
+ + "/0/" + operationDefinition.getId());
}
});
opSubMenu.addItem(operationItem);
@@ -547,12 +548,12 @@ public class ResourceTreeView extends LocatableVLayout {
addToDBItem.addClickHandler(new ClickHandler() {
public void onClick(MenuItemClickEvent menuItemClickEvent) {
- DashboardPortlet p = new DashboardPortlet(def.getDisplayName() + " Chart",
- GraphPortlet.KEY, 250);
+ DashboardPortlet p = new DashboardPortlet(MSG
+ .view_tree_common_contextMenu_resourceGraph(), ResourceGraphPortlet.KEY, 250);
p.getConfiguration().put(
- new PropertySimple(GraphPortlet.CFG_RESOURCE_ID, resource.getId()));
+ new PropertySimple(ResourceGraphPortlet.CFG_RESOURCE_ID, resource.getId()));
p.getConfiguration().put(
- new PropertySimple(GraphPortlet.CFG_DEFINITION_ID, def.getId()));
+ new PropertySimple(ResourceGraphPortlet.CFG_DEFINITION_ID, def.getId()));
d.addPortlet(p);
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/monitoring/GraphListView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/monitoring/GraphListView.java
index dcd89d0..11ed7a5 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/monitoring/GraphListView.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/monitoring/GraphListView.java
@@ -127,7 +127,7 @@ public class GraphListView extends LocatableVLayout implements ResourceSelectLis
}
private void buildGraph(MeasurementDefinition def, List<MeasurementDataNumericHighLowComposite> data) {
- SmallGraphView graph = new SmallGraphView(extendLocatorId(def.getName()), resource.getId(), def, data);
+ ResourceMetricGraphView graph = new ResourceMetricGraphView(extendLocatorId(def.getName()), resource.getId(), def, data);
graph.setWidth("95%");
graph.setHeight(220);
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/monitoring/ResourceMetricGraphView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/monitoring/ResourceMetricGraphView.java
new file mode 100644
index 0000000..d051b92
--- /dev/null
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/monitoring/ResourceMetricGraphView.java
@@ -0,0 +1,156 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2010 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+package org.rhq.enterprise.gui.coregui.client.inventory.resource.detail.monitoring;
+
+import java.util.EnumSet;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+
+import com.google.gwt.user.client.rpc.AsyncCallback;
+import com.smartgwt.client.widgets.HTMLFlow;
+
+import org.rhq.core.domain.criteria.ResourceCriteria;
+import org.rhq.core.domain.measurement.MeasurementDefinition;
+import org.rhq.core.domain.measurement.composite.MeasurementDataNumericHighLowComposite;
+import org.rhq.core.domain.resource.Resource;
+import org.rhq.core.domain.resource.ResourceType;
+import org.rhq.core.domain.util.PageList;
+import org.rhq.enterprise.gui.coregui.client.CoreGUI;
+import org.rhq.enterprise.gui.coregui.client.LinkManager;
+import org.rhq.enterprise.gui.coregui.client.gwt.GWTServiceLookup;
+import org.rhq.enterprise.gui.coregui.client.gwt.ResourceGWTServiceAsync;
+import org.rhq.enterprise.gui.coregui.client.inventory.common.AbstractMetricGraphView;
+import org.rhq.enterprise.gui.coregui.client.inventory.resource.AncestryUtil;
+import org.rhq.enterprise.gui.coregui.client.inventory.resource.type.ResourceTypeRepository;
+import org.rhq.enterprise.gui.coregui.client.util.selenium.SeleniumUtility;
+
+/**
+ * @author Greg Hinkle
+ * @author Jay Shaughnessy
+ */
+public class ResourceMetricGraphView extends AbstractMetricGraphView {
+
+ private HTMLFlow resourceTitle;
+
+ public ResourceMetricGraphView(String locatorId) {
+ super(locatorId);
+ }
+
+ public ResourceMetricGraphView(String locatorId, int resourceId, int definitionId) {
+ super(locatorId, resourceId, definitionId);
+ }
+
+ public ResourceMetricGraphView(String locatorId, int resourceId, MeasurementDefinition def,
+ List<MeasurementDataNumericHighLowComposite> data) {
+
+ super(locatorId, resourceId, def, data);
+ }
+
+ protected HTMLFlow getEntityTitle() {
+ return resourceTitle;
+ }
+
+ protected void renderGraph() {
+ if (null == getDefinition()) {
+
+ ResourceGWTServiceAsync resourceService = GWTServiceLookup.getResourceService();
+
+ ResourceCriteria resourceCriteria = new ResourceCriteria();
+ resourceCriteria.addFilterId(getEntityId());
+ resourceService.findResourcesByCriteria(resourceCriteria, new AsyncCallback<PageList<Resource>>() {
+ public void onFailure(Throwable caught) {
+ CoreGUI.getErrorHandler().handleError(MSG.view_resource_monitor_graphs_lookupFailed(), caught);
+ }
+
+ public void onSuccess(PageList<Resource> result) {
+ if (result.isEmpty()) {
+ return;
+ }
+
+ final Resource resource = result.get(0);
+ HashSet<Integer> typesSet = new HashSet<Integer>();
+ typesSet.add(resource.getResourceType().getId());
+ HashSet<String> ancestries = new HashSet<String>();
+ ancestries.add(resource.getAncestry());
+ // In addition to the types of the result resources, get the types of their ancestry
+ typesSet.addAll(AncestryUtil.getAncestryTypeIds(ancestries));
+
+ ResourceTypeRepository.Cache.getInstance().getResourceTypes(
+ typesSet.toArray(new Integer[typesSet.size()]),
+ EnumSet.of(ResourceTypeRepository.MetadataType.measurements),
+ new ResourceTypeRepository.TypesLoadedCallback() {
+
+ public void onTypesLoaded(Map<Integer, ResourceType> types) {
+ String url = LinkManager.getResourceLink(resource.getId());
+ resourceTitle = new HTMLFlow(SeleniumUtility.getLocatableHref(url, resource.getName(),
+ null));
+ resourceTitle.setTooltip(AncestryUtil.getAncestryHoverHTMLForResource(resource, types,
+ 0));
+
+ ResourceType type = types.get(resource.getResourceType().getId());
+ for (MeasurementDefinition def : type.getMetricDefinitions()) {
+ if (def.getId() == getDefinitionId()) {
+ setDefinition(def);
+
+ GWTServiceLookup.getMeasurementDataService().findDataForResource(getEntityId(),
+ new int[] { getDefinitionId() },
+ System.currentTimeMillis() - (1000L * 60 * 60 * 8),
+ System.currentTimeMillis(), 60,
+ new AsyncCallback<List<List<MeasurementDataNumericHighLowComposite>>>() {
+ public void onFailure(Throwable caught) {
+ CoreGUI.getErrorHandler().handleError(
+ MSG.view_resource_monitor_graphs_loadFailed(), caught);
+ }
+
+ public void onSuccess(
+ List<List<MeasurementDataNumericHighLowComposite>> result) {
+ setData(result.get(0));
+
+ drawGraph();
+ }
+ });
+ }
+ }
+ }
+ });
+ }
+ });
+
+ } else {
+
+ drawGraph();
+ }
+ }
+
+ protected boolean supportsLiveGraphViewDialog() {
+ return true;
+ }
+
+ protected void displayLiveGraphViewDialog() {
+ LiveGraphView.displayAsDialog(getLocatorId(), getEntityId(), getDefinition());
+ }
+
+ @Override
+ public AbstractMetricGraphView getInstance(String locatorId, int entityId, MeasurementDefinition def,
+ List<MeasurementDataNumericHighLowComposite> data) {
+
+ return new ResourceMetricGraphView(locatorId, entityId, def, data);
+ }
+}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/monitoring/ResourceScheduledMetricDatasource.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/monitoring/ResourceScheduledMetricDatasource.java
index b255539..f2a92ce 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/monitoring/ResourceScheduledMetricDatasource.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/monitoring/ResourceScheduledMetricDatasource.java
@@ -118,6 +118,25 @@ public class ResourceScheduledMetricDatasource extends RPCDataSource<Measurement
processResponse(request.getRequestId(), response);
}
});
+
+ } else if (request.getCriteria().getValues().containsKey("resourceGroupId")) {
+ MeasurementScheduleCriteria criteria = new MeasurementScheduleCriteria();
+ criteria.fetchDefinition(true);
+
+ criteria.addFilterResourceGroupId(request.getCriteria().getAttributeAsInt("resourceGroupId"));
+
+ GWTServiceLookup.getMeasurementDataService().findMeasurementSchedulesByCriteria(criteria,
+ new AsyncCallback<PageList<MeasurementSchedule>>() {
+ public void onFailure(Throwable caught) {
+ CoreGUI.getErrorHandler().handleError(MSG.dataSource_schedules_loadFailed(), caught);
+ }
+
+ public void onSuccess(PageList<MeasurementSchedule> result) {
+ response.setData(buildRecords(result));
+ processResponse(request.getRequestId(), response);
+ }
+ });
+
} else {
processResponse(request.getRequestId(), response);
}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/monitoring/SmallGraphView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/monitoring/SmallGraphView.java
deleted file mode 100644
index a6d3fe9..0000000
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/monitoring/SmallGraphView.java
+++ /dev/null
@@ -1,380 +0,0 @@
-/*
- * RHQ Management Platform
- * Copyright (C) 2005-2010 Red Hat, Inc.
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-package org.rhq.enterprise.gui.coregui.client.inventory.resource.detail.monitoring;
-
-import java.util.Date;
-import java.util.EnumSet;
-import java.util.List;
-
-import ca.nanometrics.gflot.client.Axis;
-import ca.nanometrics.gflot.client.DataPoint;
-import ca.nanometrics.gflot.client.PlotItem;
-import ca.nanometrics.gflot.client.PlotModel;
-import ca.nanometrics.gflot.client.PlotPosition;
-import ca.nanometrics.gflot.client.SeriesHandler;
-import ca.nanometrics.gflot.client.SimplePlot;
-import ca.nanometrics.gflot.client.event.PlotHoverListener;
-import ca.nanometrics.gflot.client.jsni.Plot;
-import ca.nanometrics.gflot.client.options.AxisOptions;
-import ca.nanometrics.gflot.client.options.GridOptions;
-import ca.nanometrics.gflot.client.options.LineSeriesOptions;
-import ca.nanometrics.gflot.client.options.PlotOptions;
-import ca.nanometrics.gflot.client.options.PointsSeriesOptions;
-import ca.nanometrics.gflot.client.options.TickFormatter;
-
-import com.google.gwt.i18n.client.DateTimeFormat;
-import com.google.gwt.user.client.rpc.AsyncCallback;
-import com.smartgwt.client.types.AnimationEffect;
-import com.smartgwt.client.widgets.HTMLFlow;
-import com.smartgwt.client.widgets.Img;
-import com.smartgwt.client.widgets.Label;
-import com.smartgwt.client.widgets.Window;
-import com.smartgwt.client.widgets.events.ClickEvent;
-import com.smartgwt.client.widgets.events.ClickHandler;
-import com.smartgwt.client.widgets.events.MouseOutEvent;
-import com.smartgwt.client.widgets.events.MouseOutHandler;
-import com.smartgwt.client.widgets.layout.HLayout;
-
-import org.rhq.core.domain.criteria.ResourceCriteria;
-import org.rhq.core.domain.measurement.MeasurementDefinition;
-import org.rhq.core.domain.measurement.composite.MeasurementDataNumericHighLowComposite;
-import org.rhq.core.domain.resource.Resource;
-import org.rhq.core.domain.resource.ResourceType;
-import org.rhq.core.domain.util.PageList;
-import org.rhq.enterprise.gui.coregui.client.CoreGUI;
-import org.rhq.enterprise.gui.coregui.client.gwt.GWTServiceLookup;
-import org.rhq.enterprise.gui.coregui.client.gwt.ResourceGWTServiceAsync;
-import org.rhq.enterprise.gui.coregui.client.inventory.resource.type.ResourceTypeRepository;
-import org.rhq.enterprise.gui.coregui.client.util.MeasurementConverterClient;
-import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableHLayout;
-import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableImg;
-import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableVLayout;
-import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableWidgetCanvas;
-
-/**
- * @author Greg Hinkle
- */
-public class SmallGraphView extends LocatableVLayout {
-
- private static final String INSTRUCTIONS = MSG.view_resource_monitor_graph_instructions();
-
- private static final String[] MONTH_NAMES = { MSG.common_calendar_january_short(),
- MSG.common_calendar_february_short(), MSG.common_calendar_march_short(), MSG.common_calendar_april_short(),
- MSG.common_calendar_may_short(), MSG.common_calendar_june_short(), MSG.common_calendar_july_short(),
- MSG.common_calendar_august_short(), MSG.common_calendar_september_short(), MSG.common_calendar_october_short(),
- MSG.common_calendar_november_short(), MSG.common_calendar_december_short() };
-
- private final Label selectedPointLabel = new Label(INSTRUCTIONS);
- private final Label positionLabel = new Label();
-
- private final Label hoverLabel = new Label();
-
- private int resourceId;
-
- private int definitionId;
-
- private MeasurementDefinition definition;
- private List<MeasurementDataNumericHighLowComposite> data;
-
- public SmallGraphView(String locatorId) {
- super(locatorId);
- }
-
- public SmallGraphView(String locatorId, int resourceId, int definitionId) {
- this(locatorId);
-
- this.resourceId = resourceId;
- this.definitionId = definitionId;
- }
-
- public SmallGraphView(String locatorId, int resourceId, MeasurementDefinition def,
- List<MeasurementDataNumericHighLowComposite> data) {
- this(locatorId);
-
- this.resourceId = resourceId;
- this.definition = def;
- this.data = data;
- setHeight100();
- setWidth100();
- }
-
- public String getName() {
- return "PlotHoverListener";
- }
-
- public int getResourceId() {
- return resourceId;
- }
-
- public void setResourceId(int resourceId) {
- this.resourceId = resourceId;
- this.definition = null;
- }
-
- public int getDefinitionId() {
- return definitionId;
- }
-
- public void setDefinitionId(int definitionId) {
- this.definitionId = definitionId;
- this.definition = null;
- }
-
- @Override
- protected void onDraw() {
- super.onDraw();
- removeMembers(getMembers());
- renderGraph();
- }
-
- @Override
- public void parentResized() {
- super.parentResized();
- removeMembers(getMembers());
- renderGraph();
- }
-
- protected void renderGraph() {
- if (this.definition == null) {
-
- ResourceGWTServiceAsync resourceService = GWTServiceLookup.getResourceService();
-
- ResourceCriteria resourceCriteria = new ResourceCriteria();
- resourceCriteria.addFilterId(resourceId);
- resourceService.findResourcesByCriteria(resourceCriteria, new AsyncCallback<PageList<Resource>>() {
- public void onFailure(Throwable caught) {
- CoreGUI.getErrorHandler().handleError(MSG.view_resource_monitor_graphs_lookupFailed(), caught);
- }
-
- public void onSuccess(PageList<Resource> result) {
- ResourceTypeRepository.Cache.getInstance().getResourceTypes(
- result.get(0).getResourceType().getId(),
- EnumSet.of(ResourceTypeRepository.MetadataType.measurements),
- new ResourceTypeRepository.TypeLoadedCallback() {
- public void onTypesLoaded(final ResourceType type) {
-
- for (MeasurementDefinition def : type.getMetricDefinitions()) {
- if (def.getId() == definitionId) {
- SmallGraphView.this.definition = def;
-
- GWTServiceLookup.getMeasurementDataService().findDataForResource(resourceId,
- new int[] { definitionId },
- System.currentTimeMillis() - (1000L * 60 * 60 * 8),
- System.currentTimeMillis(), 60,
- new AsyncCallback<List<List<MeasurementDataNumericHighLowComposite>>>() {
- public void onFailure(Throwable caught) {
- CoreGUI.getErrorHandler().handleError(
- MSG.view_resource_monitor_graphs_loadFailed(), caught);
- }
-
- public void onSuccess(
- List<List<MeasurementDataNumericHighLowComposite>> result) {
- SmallGraphView.this.data = result.get(0);
-
- drawGraph();
- }
- });
- }
- }
- }
- });
- }
- });
-
- } else {
-
- drawGraph();
-
- }
- }
-
- private void drawGraph() {
-
- HLayout titleLayout = new LocatableHLayout(getLocatorId());
-
- if (definition != null) {
- titleLayout.setAutoHeight();
-
- titleLayout.setWidth100();
-
- HTMLFlow title = new HTMLFlow("<b>" + definition.getDisplayName() + "</b> " + definition.getDescription());
- title.setWidth("*");
- title.addClickHandler(new ClickHandler() {
- public void onClick(ClickEvent clickEvent) {
- displayAsDialog(extendLocatorId("Dialog"));
- }
- });
- titleLayout.addMember(title);
-
- Img liveGraph = new LocatableImg(getLocatorId(), "subsystems/monitor/Monitor_16.png", 16, 16);
- liveGraph.setTooltip(MSG.view_resource_monitor_graph_live_tooltip());
-
- liveGraph.addClickHandler(new ClickHandler() {
- public void onClick(ClickEvent clickEvent) {
- LiveGraphView.displayAsDialog(getLocatorId(), resourceId, definition);
- }
- });
- titleLayout.addMember(liveGraph);
-
- addMember(titleLayout);
- }
-
- PlotModel model = new PlotModel();
- PlotOptions plotOptions = new PlotOptions();
- plotOptions.setDefaultLineSeriesOptions(new LineSeriesOptions().setLineWidth(1).setShow(true));
- plotOptions.setDefaultPointsOptions(new PointsSeriesOptions().setRadius(2).setShow(true));
- plotOptions.setDefaultShadowSize(0);
-
- // You need make the grid hoverable <<<<<<<<<
- plotOptions
- .setGridOptions(new GridOptions().setHoverable(true).setMouseActiveRadius(10).setAutoHighlight(true));
-
- // create a series
- if (definition != null && data != null) {
- loadData(model, plotOptions);
- }
-
- // create the plot
- SimplePlot plot = new SimplePlot(model, plotOptions);
- plot.setSize(String.valueOf(getInnerContentWidth()), String.valueOf(getInnerContentHeight()
- - titleLayout.getHeight() - 50));
- // "80%","80%");
-
- // add hover listener
- plot.addHoverListener(new PlotHoverListener() {
- public void onPlotHover(Plot plot, PlotPosition position, PlotItem item) {
- if (position != null) {
- positionLabel.setContents("position: (" + position.getX() + "," + position.getY() + ")");
- }
- if (item != null) {
- hoverLabel.setContents(getHover(item));
-
- hoverLabel.animateShow(AnimationEffect.FADE);
- if (hoverLabel.getLeft() > 0 || hoverLabel.getTop() > 0) {
- hoverLabel.animateMove(item.getPageX() + 10, item.getPageY() - 35);
- } else {
- hoverLabel.moveTo(item.getPageX() + 10, item.getPageY() - 35);
- }
- hoverLabel.redraw();
-
- selectedPointLabel.setContents("x: " + item.getDataPoint().getX() + ", y: "
- + item.getDataPoint().getY());
- } else {
- hoverLabel.animateHide(AnimationEffect.FADE);
- selectedPointLabel.setContents(INSTRUCTIONS);
- }
- }
- }, false);
-
- addMouseOutHandler(new MouseOutHandler() {
- public void onMouseOut(MouseOutEvent mouseOutEvent) {
- hoverLabel.animateHide(AnimationEffect.FADE);
- }
- });
-
- hoverLabel.setOpacity(80);
- hoverLabel.setWrap(false);
- hoverLabel.setHeight(25);
- hoverLabel.setBackgroundColor("yellow");
- hoverLabel.setBorder("1px solid orange");
- hoverLabel.hide();
-
- if (hoverLabel.isDrawn())
- hoverLabel.redraw();
- else
- hoverLabel.draw();
-
- // put it on a panel
-
- addMember(new LocatableWidgetCanvas(this.getLocatorId(), plot));
-
- plot.setSize(String.valueOf(getInnerContentWidth()), String.valueOf(getInnerContentHeight()
- - titleLayout.getHeight() - 50));
-
- }
-
- @Override
- public void destroy() {
- hoverLabel.destroy();
- super.destroy();
- }
-
- @Override
- public void hide() {
- super.hide();
- hoverLabel.hide();
- }
-
- private String getHover(PlotItem item) {
- if (definition != null) {
- com.google.gwt.i18n.client.DateTimeFormat df = DateTimeFormat.getMediumDateTimeFormat();
- return definition.getDisplayName() + ": "
- + MeasurementConverterClient.format(item.getDataPoint().getY(), definition.getUnits(), true) + "<br/>"
- + df.format(new Date((long) item.getDataPoint().getX()));
- } else {
- return "x: " + item.getDataPoint().getX() + ", y: " + item.getDataPoint().getY();
- }
- }
-
- private void loadData(PlotModel model, PlotOptions plotOptions) {
- SeriesHandler handler = model.addSeries(definition.getDisplayName(), "#007f00");
-
- for (MeasurementDataNumericHighLowComposite d : data) {
- handler.add(new DataPoint(d.getTimestamp(), d.getValue()));
- }
-
- plotOptions.setYAxisOptions(new AxisOptions().setTicks(5).setLabelWidth(70).setTickFormatter(
- new TickFormatter() {
- public String formatTickValue(double v, Axis axis) {
- return MeasurementConverterClient.format(v, definition.getUnits(), true);
- }
- }));
-
- long max = System.currentTimeMillis();
- long min = max - (1000L * 60 * 60 * 8);
-
- int xTicks = getWidth() / 140;
-
- plotOptions.setXAxisOptions(new AxisOptions().setTicks(xTicks).setMinimum(min).setMaximum(max)
- .setTickFormatter(new TickFormatter() {
- public String formatTickValue(double tickValue, Axis axis) {
- com.google.gwt.i18n.client.DateTimeFormat dateFormat = DateTimeFormat.getShortDateTimeFormat();
- return dateFormat.format(new Date((long) tickValue));
- // return String.valueOf(new Date((long) tickValue));
- // return MONTH_NAMES[(int) (tickValue - 1)];
- }
- }));
-
- }
-
- private void displayAsDialog(String locatorId) {
- SmallGraphView graph = new SmallGraphView(locatorId, resourceId, definition, data);
- Window graphPopup = new Window();
- graphPopup.setTitle(MSG.view_resource_monitor_detailed_graph_label());
- graphPopup.setWidth(800);
- graphPopup.setHeight(400);
- graphPopup.setIsModal(true);
- graphPopup.setShowModalMask(true);
- graphPopup.setCanDragResize(true);
- graphPopup.centerInPage();
- graphPopup.addItem(graph);
- graphPopup.show();
- }
-
-}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/selection/ResourceGroupSelector.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/selection/ResourceGroupSelector.java
index 48cd8da..320e341 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/selection/ResourceGroupSelector.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/selection/ResourceGroupSelector.java
@@ -31,7 +31,6 @@ import org.rhq.core.domain.criteria.ResourceGroupCriteria;
import org.rhq.core.domain.resource.group.GroupCategory;
import org.rhq.core.domain.resource.group.ResourceGroup;
import org.rhq.enterprise.gui.coregui.client.components.selector.AbstractSelector;
-import org.rhq.enterprise.gui.coregui.client.components.view.ViewName;
import org.rhq.enterprise.gui.coregui.client.inventory.groups.ResourceGroupDataSourceField;
import org.rhq.enterprise.gui.coregui.client.inventory.groups.ResourceGroupsDataSource;
import org.rhq.enterprise.gui.coregui.client.util.RPCDataSource;
@@ -42,17 +41,13 @@ import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableDynamicForm;
*/
public class ResourceGroupSelector extends AbstractSelector<ResourceGroup> {
- private static final ViewName GROUP_COMPATIBLE = new ViewName(GroupCategory.COMPATIBLE.getName(), MSG
- .view_group_summary_compatible());
- private static final ViewName GROUP_MIXED = new ViewName(GroupCategory.MIXED.getName(), MSG
- .view_group_summary_mixed());
private static LinkedHashMap<String, String> CATEGORY_VALUE_MAP = new LinkedHashMap<String, String>();
GroupCategory categoryFilter;
static {
- CATEGORY_VALUE_MAP.put(GroupCategory.COMPATIBLE.getName(), MSG.view_group_summary_compatible() + "-!");
- CATEGORY_VALUE_MAP.put(GroupCategory.MIXED.getName(), MSG.view_group_summary_mixed() + "-!");
+ CATEGORY_VALUE_MAP.put(GroupCategory.COMPATIBLE.getName(), MSG.view_group_summary_compatible());
+ CATEGORY_VALUE_MAP.put(GroupCategory.MIXED.getName(), MSG.view_group_summary_mixed());
}
@@ -78,7 +73,6 @@ public class ResourceGroupSelector extends AbstractSelector<ResourceGroup> {
final TextItem search = new TextItem("search", MSG.common_title_search());
SelectItem groupCategorySelect = new SelectItem("groupCategory", MSG.widget_resourceSelector_groupCategory());
- //groupCategorySelect.setValueMap(GROUP_COMPATIBLE.getTitle(), GROUP_MIXED.getTitle());
groupCategorySelect.setValueMap(CATEGORY_VALUE_MAP);
if (null == categoryFilter) {
groupCategorySelect.setAllowEmptyValue(true);
diff --git a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages.properties b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages.properties
index aebcd71..a07b4b6 100644
--- a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages.properties
+++ b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages.properties
@@ -1444,7 +1444,8 @@ view_dashboardsManager_message_title_details = <h1>Welcome to RHQ</h1>\n<p>The R
view_portlet_defaultName_autodiscovery = Discovery Queue
view_portlet_defaultName_favoriteResources = Favorite Resources
-view_portlet_defaultName_graph = Resource Metric Graph
+view_portlet_defaultName_resourceMetric = Resource Metric Graph
+view_portlet_defaultName_groupMetric = Resource Group Metric Graph
view_portlet_defaultName_inventorySummary = Inventory Summary
view_portlet_defaultName_mashup = Mashup
view_portlet_defaultName_message = Message
@@ -1644,7 +1645,8 @@ view_tree_common_contextMenu_operations = Operations
view_tree_common_contextMenu_operations_loadFailed = Failure to start wizard for running operations
view_tree_common_contextMenu_measurements = Measurements
view_tree_common_contextMenu_addChartToDashboard = Add chart to dashboard [{0}]
-view_tree_common_contextMenu_chart = Chart
+view_tree_common_contextMenu_resourceGraph = Resource Metric Graph
+view_tree_common_contextMenu_groupGraph = Group Metric Graph
view_tree_common_contextMenu_saveChartToDashboardSuccessful = You have saved dashboard [{0}]
view_tree_common_contextMenu_saveChartToDashboardFailure = Failed to save the dashboard
view_tree_common_contextMenu_loadFailed_dashboard = Failed to load user dashboards
diff --git a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_de.properties b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_de.properties
index 242a76b..805d4bf 100644
--- a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_de.properties
+++ b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_de.properties
@@ -1153,7 +1153,8 @@ view_tree_common_contextMenu_operations=Operations~
view_tree_common_contextMenu_operations_loadFailed=Failure to start wizard for running operations~
view_tree_common_contextMenu_measurements=Measurements~
view_tree_common_contextMenu_addChartToDashboard=Diagramm zum Dashboard [{0}] hinzufügen
-view_tree_common_contextMenu_chart=Chart~
+view_tree_common_contextMenu_resourceGraph = Resource Metric Graph~
+view_tree_common_contextMenu_groupGraph = Group Metric Graph~
view_tree_common_contextMenu_saveChartToDashboardSuccessful=sie haben das Dashboard [{0}] gesichert
view_tree_common_contextMenu_saveChartToDashboardFailure=Speichern des Dashboards fehlgeschlagen
view_tree_common_contextMenu_loadFailed_dashboard=Failed to load user dashboards
commit 2d4b0e8ae833aee4d9ea57df914ca19ec50f6810
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Mon Mar 21 16:19:13 2011 -0400
Add AncestryUtil entry point for getting resource hover without using a
ListGridRecord, just the required entity info.
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/AncestryUtil.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/AncestryUtil.java
index b7734c4..8a2cbe2 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/AncestryUtil.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/AncestryUtil.java
@@ -189,9 +189,24 @@ public abstract class AncestryUtil {
Map<Integer, ResourceType> types = ((MapWrapper) listGridRecord.getAttributeAsObject(RESOURCE_ANCESTRY_TYPES))
.getMap();
Integer resourceTypeId = listGridRecord.getAttributeAsInt(RESOURCE_TYPE_ID);
+ String ancestry = listGridRecord.getAttributeAsString(RESOURCE_ANCESTRY);
+
+ String result = getAncestryHoverHTMLString(resourceId, resourceName, ancestry, resourceTypeId, types, width);
+
+ listGridRecord.setAttribute(RESOURCE_ANCESTRY_HOVER, result);
+ return result;
+ }
+
+ public static String getAncestryHoverHTMLForResource(Resource resource, Map<Integer, ResourceType> types, int width) {
+
+ return getAncestryHoverHTMLString(resource.getId(), resource.getName(), resource.getAncestry(), resource
+ .getResourceType().getId(), types, width);
+ }
+
+ private static String getAncestryHoverHTMLString(int resourceId, String resourceName, String ancestry,
+ int resourceTypeId, Map<Integer, ResourceType> types, int width) {
ResourceType type = types.get(resourceTypeId);
String resourceLongName = getResourceLongName(resourceName, type);
- String ancestry = listGridRecord.getAttributeAsString(RESOURCE_ANCESTRY);
width = (width <= 0) ? 500 : width;
@@ -231,9 +246,7 @@ public abstract class AncestryUtil {
sb.append("</p>");
- String result = sb.toString();
- listGridRecord.setAttribute(RESOURCE_ANCESTRY_HOVER, result);
- return result;
+ return sb.toString();
}
private static String getResourceLongName(String resourceName, ResourceType type) {
commit 1cd5508cf4d898bdc29c6f6b7a705a680e338ff3
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Mon Mar 21 16:16:38 2011 -0400
Fix and enhance various selectors
- don't ignore construction-time criteria, so the first fetch can be filtered
- allow localized categories in the resource group selector category filter
- allow preset category filter in group selector (this, for example, can force
only compatible groups).
- add SingleResourceGroupSelector when you only want one group
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/selector/AbstractSelector.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/selector/AbstractSelector.java
index c3ae654..457d13b 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/selector/AbstractSelector.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/selector/AbstractSelector.java
@@ -284,12 +284,13 @@ public abstract class AbstractSelector<T> extends LocatableVLayout {
availableSectionStack.addSection(availableSection);
// Load data.
- this.datasource = getDataSource();
- populateAvailableGrid(new Criteria());
-
if (this.availableFilterForm != null) {
+ // this grabs any initial criteria prior to the first data fetch
+ latestCriteria = getLatestCriteria(availableFilterForm);
+
this.availableFilterForm.addItemChangedHandler(new ItemChangedHandler() {
public void onItemChanged(ItemChangedEvent itemChangedEvent) {
+
latestCriteria = getLatestCriteria(availableFilterForm);
Timer timer = new Timer() {
@@ -306,6 +307,8 @@ public abstract class AbstractSelector<T> extends LocatableVLayout {
}
});
}
+ this.datasource = getDataSource();
+ populateAvailableGrid((null == latestCriteria) ? new Criteria() : latestCriteria);
// Add event handlers.
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/selection/ResourceGroupSelector.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/selection/ResourceGroupSelector.java
index 9424d59..48cd8da 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/selection/ResourceGroupSelector.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/selection/ResourceGroupSelector.java
@@ -18,6 +18,8 @@
*/
package org.rhq.enterprise.gui.coregui.client.inventory.resource.selection;
+import java.util.LinkedHashMap;
+
import com.smartgwt.client.data.Criteria;
import com.smartgwt.client.data.DSRequest;
import com.smartgwt.client.widgets.form.DynamicForm;
@@ -26,8 +28,11 @@ import com.smartgwt.client.widgets.form.fields.SpacerItem;
import com.smartgwt.client.widgets.form.fields.TextItem;
import org.rhq.core.domain.criteria.ResourceGroupCriteria;
+import org.rhq.core.domain.resource.group.GroupCategory;
import org.rhq.core.domain.resource.group.ResourceGroup;
import org.rhq.enterprise.gui.coregui.client.components.selector.AbstractSelector;
+import org.rhq.enterprise.gui.coregui.client.components.view.ViewName;
+import org.rhq.enterprise.gui.coregui.client.inventory.groups.ResourceGroupDataSourceField;
import org.rhq.enterprise.gui.coregui.client.inventory.groups.ResourceGroupsDataSource;
import org.rhq.enterprise.gui.coregui.client.util.RPCDataSource;
import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableDynamicForm;
@@ -37,12 +42,32 @@ import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableDynamicForm;
*/
public class ResourceGroupSelector extends AbstractSelector<ResourceGroup> {
+ private static final ViewName GROUP_COMPATIBLE = new ViewName(GroupCategory.COMPATIBLE.getName(), MSG
+ .view_group_summary_compatible());
+ private static final ViewName GROUP_MIXED = new ViewName(GroupCategory.MIXED.getName(), MSG
+ .view_group_summary_mixed());
+ private static LinkedHashMap<String, String> CATEGORY_VALUE_MAP = new LinkedHashMap<String, String>();
+
+ GroupCategory categoryFilter;
+
+ static {
+ CATEGORY_VALUE_MAP.put(GroupCategory.COMPATIBLE.getName(), MSG.view_group_summary_compatible() + "-!");
+ CATEGORY_VALUE_MAP.put(GroupCategory.MIXED.getName(), MSG.view_group_summary_mixed() + "-!");
+
+ }
+
public ResourceGroupSelector(String locatorId) {
this(locatorId, false);
}
-
+
public ResourceGroupSelector(String locatorId, boolean isReadOnly) {
+ this(locatorId, null, isReadOnly);
+ }
+
+ public ResourceGroupSelector(String locatorId, GroupCategory categoryFilter, boolean isReadOnly) {
super(locatorId, isReadOnly);
+
+ this.categoryFilter = categoryFilter;
}
protected DynamicForm getAvailableFilterForm() {
@@ -53,8 +78,21 @@ public class ResourceGroupSelector extends AbstractSelector<ResourceGroup> {
final TextItem search = new TextItem("search", MSG.common_title_search());
SelectItem groupCategorySelect = new SelectItem("groupCategory", MSG.widget_resourceSelector_groupCategory());
- groupCategorySelect.setValueMap("Compatible", "Mixed"); // I don't think we can i18n these, may need these literal values - need to double check this
- groupCategorySelect.setAllowEmptyValue(true);
+ //groupCategorySelect.setValueMap(GROUP_COMPATIBLE.getTitle(), GROUP_MIXED.getTitle());
+ groupCategorySelect.setValueMap(CATEGORY_VALUE_MAP);
+ if (null == categoryFilter) {
+ groupCategorySelect.setAllowEmptyValue(true);
+ } else {
+ switch (categoryFilter) {
+ case COMPATIBLE:
+ groupCategorySelect.setValue(GroupCategory.COMPATIBLE.getName());
+ break;
+ case MIXED:
+ groupCategorySelect.setValue(GroupCategory.MIXED.getName());
+ break;
+ }
+ groupCategorySelect.setDisabled(true);
+ }
availableFilterForm.setItems(search, groupCategorySelect, new SpacerItem());
return availableFilterForm;
@@ -72,10 +110,10 @@ public class ResourceGroupSelector extends AbstractSelector<ResourceGroup> {
String category = (String) availableFilterForm.getValue("groupCategory");
Criteria criteria = new Criteria();
if (null != search) {
- criteria.addCriteria("name", search);
+ criteria.addCriteria(ResourceGroupDataSourceField.NAME.propertyName(), search);
}
if (null != category) {
- criteria.addCriteria("category", category);
+ criteria.addCriteria(ResourceGroupDataSourceField.CATEGORY.propertyName(), category);
}
return criteria;
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/selection/SingleResourceGroupSelector.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/selection/SingleResourceGroupSelector.java
new file mode 100644
index 0000000..513419f
--- /dev/null
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/selection/SingleResourceGroupSelector.java
@@ -0,0 +1,65 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2010 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+package org.rhq.enterprise.gui.coregui.client.inventory.resource.selection;
+
+import com.smartgwt.client.types.SelectionStyle;
+
+import org.rhq.core.domain.resource.group.GroupCategory;
+
+/**
+ * This forces the user to only be able to select a single resource.
+ *
+ * @author Jay Shaughnessy
+ */
+public class SingleResourceGroupSelector extends ResourceGroupSelector {
+
+ public SingleResourceGroupSelector(String locatorId) {
+ super(locatorId);
+ }
+
+ public SingleResourceGroupSelector(String locatorId, GroupCategory categoryFilter, boolean isReadOnly) {
+ super(locatorId, categoryFilter, isReadOnly);
+ }
+
+ @Override
+ protected void onInit() {
+ super.onInit();
+
+ // we only allow a single resource to be selected
+ availableGrid.setSelectionType(SelectionStyle.SINGLE);
+ }
+
+ @Override
+ protected void updateButtonEnablement() {
+ addButton.setDisabled(!availableGrid.anySelected() || availableGrid.getTotalRows() == 0
+ || assignedGrid.getTotalRows() > 0);
+ removeButton.setDisabled(!assignedGrid.anySelected());
+ addAllButton.hide();
+ removeAllButton.hide();
+ }
+
+ @Override
+ public void addSelectedRows() {
+ // do not allow more than one row into the assigned grid
+ if (assignedGrid.getTotalRows() == 0) {
+ super.addSelectedRows();
+ }
+ }
+}
13 years, 3 months
[rhq] modules/enterprise
by mazz
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/SingleAlertDefinitionView.java | 13 +++++++++-
1 file changed, 12 insertions(+), 1 deletion(-)
New commits:
commit ab15b97d5183df6b04242d52b14d6023d40097fb
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Mon Mar 21 15:04:15 2011 -0400
BZ 560760 don't allow the user to edit alert defs
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/SingleAlertDefinitionView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/SingleAlertDefinitionView.java
index 82aeea7..2bacf3d 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/SingleAlertDefinitionView.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/SingleAlertDefinitionView.java
@@ -52,6 +52,8 @@ public class SingleAlertDefinitionView extends LocatableVLayout {
private Button saveButton;
private Button cancelButton;
+ private boolean allowedToModifyAlertDefinitions;
+
public SingleAlertDefinitionView(String locatorId, AbstractAlertDefinitionsView alertDefView) {
this(locatorId, alertDefView, null);
}
@@ -61,6 +63,7 @@ public class SingleAlertDefinitionView extends LocatableVLayout {
super(locatorId);
this.alertDefinition = alertDefinition;
+ this.allowedToModifyAlertDefinitions = alertDefView.isAllowedToModifyAlertDefinitions();
LocatableTabSet tabSet = new LocatableTabSet(this.getLocatorId());
tabSet.setHeight100();
@@ -107,6 +110,8 @@ public class SingleAlertDefinitionView extends LocatableVLayout {
buttons.addMember(saveButton);
buttons.addMember(cancelButton);
+ editButton.setDisabled(!allowedToModifyAlertDefinitions);
+
editButton.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
@@ -121,7 +126,7 @@ public class SingleAlertDefinitionView extends LocatableVLayout {
setAlertDefinition(getAlertDefinition()); // loads data into static fields
makeViewOnly();
- alertDefView.commitAlertDefinition(getAlertDefinition());
+ alertDefView.commitAlertDefinition(getAlertDefinition());
}
});
@@ -155,6 +160,12 @@ public class SingleAlertDefinitionView extends LocatableVLayout {
}
public void makeEditable() {
+ if (!this.allowedToModifyAlertDefinitions) {
+ // this is just a safety measure - we should never get here if we don't have perms, but just in case,
+ // don't do anything to allow the def to be editable. Should we notify the message center?
+ return;
+ }
+
saveButton.show();
cancelButton.show();
editButton.hide();
13 years, 3 months
[rhq] 10 commits - modules/enterprise
by Simeon Pinder
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/AlertPortletConfigurationDataSource.java | 17
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/measurement/AbstractMeasurementRangeEditor.java | 7
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/measurement/CustomConfigMeasurementRangeEditor.java | 32
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/DashboardView.java | 209 ++
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/PortletFactory.java | 44
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/PortletConfigurationEditorComponent.java | 23
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/groups/GroupAlertsPortlet.java | 435 ++---
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/groups/GroupAlertsPortlet2.java | 394 ----
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/groups/GroupAlertsPortlet3.java | 398 ++++
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/groups/GroupEventsPortlet.java | 2
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/groups/GroupOperationsPortlet.java | 119 -
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/resource/ResourceAlertsPortlet.java | 4
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/resource/ResourceBundleDeploymentsPortlet.java | 1
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/resource/ResourceEventsPortlet.java | 2
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/resource/ResourceOperationsPortlet.java | 145 +
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/detail/summary/AbstractActivityView.java | 51
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/ResourceGroupDetailView.java | 4
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/summary/ActivityView.java | 814 ++-------
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/summary/ActivityView2.java | 229 --
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/summary/ActivityView3.java | 702 ++++++++
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/ResourceDetailView.java | 4
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/Activity2View.java | 205 --
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/ActivityView.java | 825 ++--------
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/ActivityView3.java | 691 ++++++++
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/message/MessageCenterView.java | 4
modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages.properties | 6
26 files changed, 2885 insertions(+), 2482 deletions(-)
New commits:
commit 33815da4e801a6ebce0f9be4e01b4c1da7d0a2df
Author: Simeon Pinder <spinder(a)redhat.com>
Date: Mon Mar 21 12:46:05 2011 -0400
fix resourceOps link issue.
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/resource/ResourceOperationsPortlet.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/resource/ResourceOperationsPortlet.java
index a1f9c3e..f2a0ab4 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/resource/ResourceOperationsPortlet.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/resource/ResourceOperationsPortlet.java
@@ -245,6 +245,11 @@ class ResourceOperationsCriteriaHistoryListView extends AbstractOperationHistory
MSG.view_table_matchingRows(String.valueOf(getListGrid().getTotalRows()), String.valueOf(count)));
}
}
+
+ @Override
+ protected String getBasePath() {
+ return "Resource/" + resourceComposite.getResource().getId() + "/Operations/History";
+ }
}
/** Provide implementation of ResourceOperationHistoryDataSource that dynamically
commit 13336db776cbdf7f8133f9ff3ab6eb38035dccba
Author: Simeon Pinder <spinder(a)redhat.com>
Date: Mon Mar 21 11:52:43 2011 -0400
fix/enforce unmodifiable PortletFactory mapping data.
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/DashboardView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/DashboardView.java
index 10610e4..e8ee80c 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/DashboardView.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/DashboardView.java
@@ -20,6 +20,7 @@ package org.rhq.enterprise.gui.coregui.client.dashboard;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
@@ -194,7 +195,8 @@ public class DashboardView extends LocatableVLayout {
private DynamicForm buildEditForm() {
editForm = new LocatableDynamicForm(extendLocatorId("Editor"));
- final HashMap<String, String> groupKeyNameMap = PortletFactory.getRegisteredGroupPortletNameMap();
+ final Map<String, String> groupKeyNameMap = new HashMap<String, String>(PortletFactory
+ .getRegisteredGroupPortletNameMap());
//remove BundleDeployment and add back later if relevant.
groupKeyNameMap.remove(GroupBundleDeploymentsPortlet.KEY);
//if group, need to do asynch check for bundlePortlet to ensure only Platform members
@@ -246,7 +248,7 @@ public class DashboardView extends LocatableVLayout {
*
* @param groupKeyNameMap
*/
- private void populateBuildEditForm(HashMap<String, String> groupKeyNameMap) {
+ private void populateBuildEditForm(Map<String, String> groupKeyNameMap) {
editForm.setMargin(5);
editForm.setAutoWidth();
editForm.setNumCols(canEditName() ? 12 : 10);
@@ -312,7 +314,7 @@ public class DashboardView extends LocatableVLayout {
});
final Menu addPortletMenu = new LocatableMenu(editForm.extendLocatorId("PortletMenu"));
- HashMap<String, String> keyNameMap = PortletFactory.getRegisteredPortletNameMap();
+ HashMap<String, String> keyNameMap = new HashMap<String, String>(PortletFactory.getRegisteredPortletNameMap());
// the assumption here is that the portlet names are unique. we want a sorted menu here, so create a
// sorted map from portlet name to portlet key and use that to generate the menu. It would be nice if you
// could just call Menu.sort() but it's not supported (yet?).
@@ -333,7 +335,8 @@ public class DashboardView extends LocatableVLayout {
}
}
- HashMap<String, String> resourceKeyNameMap = PortletFactory.getRegisteredResourcePortletNameMap();
+ HashMap<String, String> resourceKeyNameMap = new HashMap<String, String>(PortletFactory
+ .getRegisteredResourcePortletNameMap());
//if resource passed in then add additional portlets to list
if (this.resource != null) {
//trim out portlets that should not be visible
@@ -504,7 +507,7 @@ public class DashboardView extends LocatableVLayout {
/**Process the portletName map to exclude portlets that should not be visible for this
* group. All except BundleDeployment visibility is handled here. Bundle requires runtime check.
*/
- public static HashMap<String, String> processPortletNameMapForGroup(HashMap<String, String> groupKeyNameMap,
+ public static Map<String, String> processPortletNameMapForGroup(Map<String, String> groupKeyNameMap,
ResourceGroupComposite composite) {
if ((composite != null) && (composite.getResourceGroup() != null) && (groupKeyNameMap != null)
&& !groupKeyNameMap.isEmpty()) {
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/PortletFactory.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/PortletFactory.java
index b42ffa5..98220d7 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/PortletFactory.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/PortletFactory.java
@@ -19,8 +19,10 @@
package org.rhq.enterprise.gui.coregui.client.dashboard;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import org.rhq.core.domain.dashboard.DashboardPortlet;
import org.rhq.enterprise.gui.coregui.client.ImageManager;
@@ -66,7 +68,7 @@ public class PortletFactory {
private static final HashMap<String, PortletViewFactory> registeredResourcePortletFactoryMap;
private static final HashMap<String, String> registeredGroupPortletNameMap;
private static final HashMap<String, String> registeredResourcePortletNameMap;
- private static final HashMap<String, String> registeredPortletIconMap;
+ private static HashMap<String, String> registeredPortletIconMap;
static {
//############## Default Dashboard ############################
@@ -209,19 +211,24 @@ public class PortletFactory {
/**
* @return Unmodifiable Map of registered portlet keys to names
*/
- public static HashMap<String, String> getRegisteredPortletNameMap() {
-
- return registeredPortletNameMap;
+ public static Map<String, String> getRegisteredPortletNameMap() {
+ return Collections.unmodifiableMap(registeredPortletNameMap);
}
- public static HashMap<String, String> getRegisteredGroupPortletNameMap() {
+ /**
+ * @return Unmodifiable Map of registered portlet keys to names
+ */
+ public static Map<String, String> getRegisteredGroupPortletNameMap() {
- return registeredGroupPortletNameMap;
+ return Collections.unmodifiableMap(registeredGroupPortletNameMap);
}
- public static HashMap<String, String> getRegisteredResourcePortletNameMap() {
+ /**
+ * @return Unmodifiable Map of registered portlet keys to names
+ */
+ public static Map<String, String> getRegisteredResourcePortletNameMap() {
- return registeredResourcePortletNameMap;
+ return Collections.unmodifiableMap(registeredResourcePortletNameMap);
}
public static String getRegisteredPortletName(String key) {
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/summary/ActivityView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/summary/ActivityView.java
index 106ac4b..7ff4f7d 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/summary/ActivityView.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/summary/ActivityView.java
@@ -19,6 +19,7 @@
package org.rhq.enterprise.gui.coregui.client.inventory.groups.detail.summary;
import java.util.HashMap;
+import java.util.Map;
import java.util.Set;
import com.google.gwt.user.client.rpc.AsyncCallback;
@@ -48,6 +49,7 @@ import org.rhq.enterprise.gui.coregui.client.dashboard.DashboardContainer;
import org.rhq.enterprise.gui.coregui.client.dashboard.DashboardView;
import org.rhq.enterprise.gui.coregui.client.dashboard.PortletFactory;
import org.rhq.enterprise.gui.coregui.client.dashboard.portlets.groups.GroupAlertsPortlet;
+import org.rhq.enterprise.gui.coregui.client.dashboard.portlets.groups.GroupBundleDeploymentsPortlet;
import org.rhq.enterprise.gui.coregui.client.dashboard.portlets.groups.GroupMetricsPortlet;
import org.rhq.enterprise.gui.coregui.client.dashboard.portlets.groups.GroupOperationsPortlet;
import org.rhq.enterprise.gui.coregui.client.gwt.DashboardGWTServiceAsync;
@@ -189,8 +191,13 @@ public class ActivityView extends LocatableVLayout implements DashboardContainer
dashboard.getConfiguration().put(new PropertySimple(Dashboard.CFG_BACKGROUND, "#F1F2F3"));
//figure out which portlets to display and how
- HashMap<String, String> groupKeyNameMap = PortletFactory.getRegisteredGroupPortletNameMap();
+ Map<String, String> groupKeyNameMap = new HashMap<String, String>(PortletFactory
+ .getRegisteredGroupPortletNameMap());
+ //remove BundleDeployment and add back later if relevant.
+ groupKeyNameMap.remove(GroupBundleDeploymentsPortlet.KEY);
groupKeyNameMap = DashboardView.processPortletNameMapForGroup(groupKeyNameMap, groupComposite);
+ //TODO: spinder 3/21/11 need asynch call to execute and then update the menu for bundle
+
int colLeft = 0;
int colRight = 1;
int rowLeft = 0;
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/ActivityView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/ActivityView.java
index ee64837..4cec210 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/ActivityView.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/ActivityView.java
@@ -172,7 +172,8 @@ public class ActivityView extends LocatableVLayout implements DashboardContainer
dashboard.getConfiguration().put(new PropertySimple(Dashboard.CFG_BACKGROUND, "#F1F2F3"));
//figure out which portlets to display and how
- HashMap<String, String> resKeyNameMap = PortletFactory.getRegisteredResourcePortletNameMap();
+ HashMap<String, String> resKeyNameMap = new HashMap<String, String>(PortletFactory
+ .getRegisteredResourcePortletNameMap());
resKeyNameMap = DashboardView.processPortletNameMapForResource(resKeyNameMap, resourceComposite);
int colLeft = 0;
int colRight = 1;
commit 0fcd909efb4236646d9faaa1e1278ce4545ed678
Author: Simeon Pinder <spinder(a)redhat.com>
Date: Mon Mar 21 09:15:00 2011 -0400
i)moved portlet dashboard to first activitytab. Still trailing dashboard reset issue
ii)disable sort results widget
iii)fix resourceOperationsPortlet init issue
iv)add NPE check to messageCenter execution.
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/DashboardView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/DashboardView.java
index a1a1c98..10610e4 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/DashboardView.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/DashboardView.java
@@ -474,22 +474,24 @@ public class DashboardView extends LocatableVLayout {
Resource resource = composite.getResource();
//filter out portlets not relevent for facets
Set<ResourceTypeFacet> facets = composite.getResourceFacets().getFacets();
- //Operation related portlets
- if (!facets.contains(ResourceTypeFacet.OPERATION)) {
- resourceKeyNameMap.remove(ResourceOperationsPortlet.KEY);
- }
- //MEASUREMENT related portlets(METRICS)
- if (!facets.contains(ResourceTypeFacet.MEASUREMENT)) {
- resourceKeyNameMap.remove(ResourceMetricsPortlet.KEY);
- resourceKeyNameMap.remove(ResourceMetricsPortlet.KEY);
- }
- //Content related portlets
- if (!facets.contains(ResourceTypeFacet.CONTENT)) {
- resourceKeyNameMap.remove(ResourcePkgHistoryPortlet.KEY);
- }
- //Event related portlets
- if (!facets.contains(ResourceTypeFacet.EVENT)) {
- resourceKeyNameMap.remove(ResourceEventsPortlet.KEY);
+ if (!facets.isEmpty()) {
+ //Operation related portlets
+ if (!facets.contains(ResourceTypeFacet.OPERATION)) {
+ resourceKeyNameMap.remove(ResourceOperationsPortlet.KEY);
+ }
+ //MEASUREMENT related portlets(METRICS)
+ if (!facets.contains(ResourceTypeFacet.MEASUREMENT)) {
+ resourceKeyNameMap.remove(ResourceMetricsPortlet.KEY);
+ resourceKeyNameMap.remove(ResourceMetricsPortlet.KEY);
+ }
+ //Content related portlets
+ if (!facets.contains(ResourceTypeFacet.CONTENT)) {
+ resourceKeyNameMap.remove(ResourcePkgHistoryPortlet.KEY);
+ }
+ //Event related portlets
+ if (!facets.contains(ResourceTypeFacet.EVENT)) {
+ resourceKeyNameMap.remove(ResourceEventsPortlet.KEY);
+ }
}
//Bundle related portlet
if (!resource.getResourceType().getCategory().equals(ResourceCategory.PLATFORM)) {
@@ -513,18 +515,20 @@ public class DashboardView extends LocatableVLayout {
// ResourceGroup group = composite.getResourceGroup();
//compatible if not a compatible group may need to do some pruning.
if (groupCategory != GroupCategory.COMPATIBLE) {
- //Operations related portlets(Config,PkgHistory)
- if (!facets.contains(ResourceTypeFacet.OPERATION)) {
- groupKeyNameMap.remove(GroupOperationsPortlet.KEY);
- }
- //MEASUREMENT related portlets(METRICS)
- if (!facets.contains(ResourceTypeFacet.MEASUREMENT)) {
- groupKeyNameMap.remove(GroupMetricsPortlet.KEY);
- groupKeyNameMap.remove(GroupOobsPortlet.KEY);
- }
- //CONTENT related portlets(CONTENT)
- if (!facets.contains(ResourceTypeFacet.CONTENT)) {
- groupKeyNameMap.remove(GroupPkgHistoryPortlet.KEY);
+ if (!facets.isEmpty()) {
+ //Operations related portlets(Config,PkgHistory)
+ if (!facets.contains(ResourceTypeFacet.OPERATION)) {
+ groupKeyNameMap.remove(GroupOperationsPortlet.KEY);
+ }
+ //MEASUREMENT related portlets(METRICS)
+ if (!facets.contains(ResourceTypeFacet.MEASUREMENT)) {
+ groupKeyNameMap.remove(GroupMetricsPortlet.KEY);
+ groupKeyNameMap.remove(GroupOobsPortlet.KEY);
+ }
+ //CONTENT related portlets(CONTENT)
+ if (!facets.contains(ResourceTypeFacet.CONTENT)) {
+ groupKeyNameMap.remove(GroupPkgHistoryPortlet.KEY);
+ }
}
// //EVENT related portlets
// if (!facets.contains(ResourceTypeFacet.EVENT)) {
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/PortletFactory.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/PortletFactory.java
index b8d2ddc..b42ffa5 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/PortletFactory.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/PortletFactory.java
@@ -57,16 +57,16 @@ import org.rhq.enterprise.gui.coregui.client.dashboard.portlets.util.MessagePort
*/
public class PortletFactory {
- private static HashMap<String, PortletViewFactory> registeredPortletFactoryMap;
- private static HashMap<String, String> registeredPortletNameMap;
+ private static final HashMap<String, PortletViewFactory> registeredPortletFactoryMap;
+ private static final HashMap<String, String> registeredPortletNameMap;
//Group portlet registrations, diff from default portlets as only applicable for specific group
- private static HashMap<String, PortletViewFactory> registeredGroupPortletFactoryMap;
+ private static final HashMap<String, PortletViewFactory> registeredGroupPortletFactoryMap;
//Resource portlet registrations, diff from default portlets as only applicable for specific resource
- private static HashMap<String, PortletViewFactory> registeredResourcePortletFactoryMap;
- private static HashMap<String, String> registeredGroupPortletNameMap;
- private static HashMap<String, String> registeredResourcePortletNameMap;
- private static HashMap<String, String> registeredPortletIconMap;
+ private static final HashMap<String, PortletViewFactory> registeredResourcePortletFactoryMap;
+ private static final HashMap<String, String> registeredGroupPortletNameMap;
+ private static final HashMap<String, String> registeredResourcePortletNameMap;
+ private static final HashMap<String, String> registeredPortletIconMap;
static {
//############## Default Dashboard ############################
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/groups/GroupOperationsPortlet.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/groups/GroupOperationsPortlet.java
index e148b1e..f2322b0 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/groups/GroupOperationsPortlet.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/groups/GroupOperationsPortlet.java
@@ -46,7 +46,6 @@ import org.rhq.core.domain.operation.OperationRequestStatus;
import org.rhq.core.domain.resource.group.composite.ResourceGroupComposite;
import org.rhq.core.domain.util.PageControl;
import org.rhq.core.domain.util.PageList;
-import org.rhq.core.domain.util.PageOrdering;
import org.rhq.enterprise.gui.coregui.client.CoreGUI;
import org.rhq.enterprise.gui.coregui.client.UserSessionManager;
import org.rhq.enterprise.gui.coregui.client.components.measurement.CustomConfigMeasurementRangeEditor;
@@ -93,8 +92,8 @@ public class GroupOperationsPortlet extends LocatableVLayout implements CustomSe
CONFIG_INCLUDE.add(Constant.METRIC_RANGE_LASTN);
CONFIG_INCLUDE.add(Constant.METRIC_RANGE_UNIT);
CONFIG_INCLUDE.add(Constant.RESULT_COUNT);
- CONFIG_INCLUDE.add(Constant.RESULT_SORT_ORDER);
- CONFIG_INCLUDE.add(Constant.RESULT_SORT_PRIORITY);
+ // CONFIG_INCLUDE.add(Constant.RESULT_SORT_ORDER);
+ // CONFIG_INCLUDE.add(Constant.RESULT_SORT_PRIORITY);
CONFIG_INCLUDE.add(Constant.OPERATION_STATUS);
}
@@ -234,9 +233,9 @@ public class GroupOperationsPortlet extends LocatableVLayout implements CustomSe
//add filter operation status type selector
final SelectItem operationStatusSelector = PortletConfigurationEditorComponent
.getOperationStatusEditor(portletConfig);
- //add sort priority selector
- final SelectItem resultSortSelector = PortletConfigurationEditorComponent
- .getResulSortOrderEditor(portletConfig);
+ // //add sort priority selector
+ // final SelectItem resultSortSelector = PortletConfigurationEditorComponent
+ // .getResulSortOrderEditor(portletConfig);
//add result count selector
final SelectItem resultCountSelector = PortletConfigurationEditorComponent.getResultCountEditor(portletConfig);
@@ -244,7 +243,7 @@ public class GroupOperationsPortlet extends LocatableVLayout implements CustomSe
final CustomConfigMeasurementRangeEditor measurementRangeEditor = PortletConfigurationEditorComponent
.getMeasurementRangeEditor(portletConfig);
- form.setItems(operationStatusSelector, resultSortSelector, resultCountSelector);
+ form.setItems(operationStatusSelector, resultCountSelector);
//submit handler
customSettings.addSubmitValuesHandler(new SubmitValuesHandler() {
@@ -404,18 +403,18 @@ class GroupOperationsCriteriaDataSource extends GroupOperationHistoryDataSource
//retrieve previous settings from portlet config
if (portletConfig != null) {
- //result sort order
- PropertySimple property = portletConfig.getSimple(Constant.RESULT_SORT_ORDER);
- if (property != null) {
- String currentSetting = property.getStringValue();
- if (currentSetting.trim().isEmpty() || currentSetting.equalsIgnoreCase(PageOrdering.DESC.name())) {
- criteria.addSortStatus(PageOrdering.DESC);
- } else {
- criteria.addSortStatus(PageOrdering.ASC);
- }
- }
+ // //result sort order
+ // PropertySimple property = portletConfig.getSimple(Constant.RESULT_SORT_ORDER);
+ // if (property != null) {
+ // String currentSetting = property.getStringValue();
+ // if (currentSetting.trim().isEmpty() || currentSetting.equalsIgnoreCase(PageOrdering.DESC.name())) {
+ // criteria.addSortStatus(PageOrdering.DESC);
+ // } else {
+ // criteria.addSortStatus(PageOrdering.ASC);
+ // }
+ // }
//result timeframe if enabled
- property = portletConfig.getSimple(Constant.METRIC_RANGE_ENABLE);
+ PropertySimple property = portletConfig.getSimple(Constant.METRIC_RANGE_ENABLE);
if (Boolean.valueOf(property.getBooleanValue())) {//then proceed setting
boolean isAdvanced = false;
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/resource/ResourceOperationsPortlet.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/resource/ResourceOperationsPortlet.java
index 30929c1..a1f9c3e 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/resource/ResourceOperationsPortlet.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/resource/ResourceOperationsPortlet.java
@@ -41,7 +41,6 @@ import org.rhq.core.domain.operation.ResourceOperationHistory;
import org.rhq.core.domain.resource.composite.ResourceComposite;
import org.rhq.core.domain.util.PageControl;
import org.rhq.core.domain.util.PageList;
-import org.rhq.core.domain.util.PageOrdering;
import org.rhq.enterprise.gui.coregui.client.CoreGUI;
import org.rhq.enterprise.gui.coregui.client.components.measurement.CustomConfigMeasurementRangeEditor;
import org.rhq.enterprise.gui.coregui.client.dashboard.Portlet;
@@ -87,7 +86,7 @@ public class ResourceOperationsPortlet extends GroupOperationsPortlet {
protected void onInit() {
// super.onInit();
initializeUi();
- // loadData();
+ loadData();
}
@Override
@@ -107,9 +106,9 @@ public class ResourceOperationsPortlet extends GroupOperationsPortlet {
//add filter operation status type selector
final SelectItem operationStatusSelector = PortletConfigurationEditorComponent
.getOperationStatusEditor(portletConfig);
- //add sort priority selector
- final SelectItem resultSortSelector = PortletConfigurationEditorComponent
- .getResulSortOrderEditor(portletConfig);
+ // //add sort priority selector
+ // final SelectItem resultSortSelector = PortletConfigurationEditorComponent
+ // .getResulSortOrderEditor(portletConfig);
//add result count selector
final SelectItem resultCountSelector = PortletConfigurationEditorComponent.getResultCountEditor(portletConfig);
@@ -117,7 +116,7 @@ public class ResourceOperationsPortlet extends GroupOperationsPortlet {
final CustomConfigMeasurementRangeEditor measurementRangeEditor = PortletConfigurationEditorComponent
.getMeasurementRangeEditor(portletConfig);
- form.setItems(operationStatusSelector, resultSortSelector, resultCountSelector);
+ form.setItems(operationStatusSelector, resultCountSelector);
//submit handler
customSettings.addSubmitValuesHandler(new SubmitValuesHandler() {
@@ -279,18 +278,18 @@ class ResourceOperationsCriteriaDataSource extends ResourceOperationHistoryDataS
//retrieve previous settings from portlet config
if (portletConfig != null) {
- //result sort order
- PropertySimple property = portletConfig.getSimple(Constant.RESULT_SORT_ORDER);
- if (property != null) {
- String currentSetting = property.getStringValue();
- if (currentSetting.trim().isEmpty() || currentSetting.equalsIgnoreCase(PageOrdering.DESC.name())) {
- criteria.addSortStatus(PageOrdering.DESC);
- } else {
- criteria.addSortStatus(PageOrdering.ASC);
- }
- }
+ // //result sort order
+ // PropertySimple property = portletConfig.getSimple(Constant.RESULT_SORT_ORDER);
+ // if (property != null) {
+ // String currentSetting = property.getStringValue();
+ // if (currentSetting.trim().isEmpty() || currentSetting.equalsIgnoreCase(PageOrdering.DESC.name())) {
+ // criteria.addSortStatus(PageOrdering.DESC);
+ // } else {
+ // criteria.addSortStatus(PageOrdering.ASC);
+ // }
+ // }
//result timeframe if enabled
- property = portletConfig.getSimple(Constant.METRIC_RANGE_ENABLE);
+ PropertySimple property = portletConfig.getSimple(Constant.METRIC_RANGE_ENABLE);
if (Boolean.valueOf(property.getBooleanValue())) {//then proceed setting
boolean isAdvanced = false;
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/ResourceGroupDetailView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/ResourceGroupDetailView.java
index 9b89dff..86a7c1c 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/ResourceGroupDetailView.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/ResourceGroupDetailView.java
@@ -64,7 +64,7 @@ import org.rhq.enterprise.gui.coregui.client.inventory.groups.detail.monitoring.
import org.rhq.enterprise.gui.coregui.client.inventory.groups.detail.operation.history.GroupOperationHistoryListView;
import org.rhq.enterprise.gui.coregui.client.inventory.groups.detail.operation.schedule.GroupOperationScheduleListView;
import org.rhq.enterprise.gui.coregui.client.inventory.groups.detail.summary.ActivityView;
-import org.rhq.enterprise.gui.coregui.client.inventory.groups.detail.summary.ActivityView2;
+import org.rhq.enterprise.gui.coregui.client.inventory.groups.detail.summary.ActivityView3;
import org.rhq.enterprise.gui.coregui.client.inventory.resource.type.ResourceTypeRepository;
/**
@@ -263,7 +263,7 @@ public class ResourceGroupDetailView extends AbstractTwoLevelTabSetView<Resource
updateSubTab(this.summaryTab, this.summaryActivity2, true, true, new ViewFactory() {
@Override
public Canvas createView() {
- return new ActivityView2(summaryActivity2.extendLocatorId("View2"), groupComposite);
+ return new ActivityView3(summaryActivity2.extendLocatorId("View2"), groupComposite);
}
});
// TODO (ips): Add Timeline subtab?
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/summary/ActivityView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/summary/ActivityView.java
index eb0f23c..106ac4b 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/summary/ActivityView.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/summary/ActivityView.java
@@ -18,685 +18,240 @@
*/
package org.rhq.enterprise.gui.coregui.client.inventory.groups.detail.summary;
-import java.util.ArrayList;
-import java.util.Arrays;
import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
import java.util.Set;
-import com.allen_sauer.gwt.log.client.Log;
import com.google.gwt.user.client.rpc.AsyncCallback;
-import com.smartgwt.client.types.ContentsType;
+import com.smartgwt.client.util.BooleanCallback;
+import com.smartgwt.client.util.SC;
import com.smartgwt.client.widgets.Canvas;
-import com.smartgwt.client.widgets.HTMLFlow;
-import com.smartgwt.client.widgets.form.fields.CanvasItem;
-import com.smartgwt.client.widgets.form.fields.LinkItem;
-import com.smartgwt.client.widgets.form.fields.StaticTextItem;
-import com.smartgwt.client.widgets.layout.VLayout;
-
-import org.rhq.core.domain.alert.Alert;
-import org.rhq.core.domain.bundle.BundleDeployment;
-import org.rhq.core.domain.configuration.group.GroupResourceConfigurationUpdate;
-import org.rhq.core.domain.content.InstalledPackageHistory;
-import org.rhq.core.domain.criteria.AlertCriteria;
-import org.rhq.core.domain.criteria.GroupBundleDeploymentCriteria;
-import org.rhq.core.domain.criteria.GroupOperationHistoryCriteria;
-import org.rhq.core.domain.criteria.GroupResourceConfigurationUpdateCriteria;
-import org.rhq.core.domain.criteria.InstalledPackageHistoryCriteria;
-import org.rhq.core.domain.event.EventSeverity;
-import org.rhq.core.domain.measurement.MeasurementDefinition;
-import org.rhq.core.domain.measurement.composite.MeasurementDataNumericHighLowComposite;
-import org.rhq.core.domain.measurement.composite.MeasurementOOBComposite;
-import org.rhq.core.domain.operation.GroupOperationHistory;
-import org.rhq.core.domain.resource.ResourceTypeFacet;
-import org.rhq.core.domain.resource.group.GroupCategory;
+import com.smartgwt.client.widgets.IButton;
+import com.smartgwt.client.widgets.events.ClickEvent;
+import com.smartgwt.client.widgets.events.ClickHandler;
+
+import org.rhq.core.domain.auth.Subject;
+import org.rhq.core.domain.authz.Permission;
+import org.rhq.core.domain.configuration.PropertySimple;
+import org.rhq.core.domain.criteria.DashboardCriteria;
+import org.rhq.core.domain.dashboard.Dashboard;
+import org.rhq.core.domain.dashboard.DashboardCategory;
+import org.rhq.core.domain.dashboard.DashboardPortlet;
import org.rhq.core.domain.resource.group.ResourceGroup;
import org.rhq.core.domain.resource.group.composite.ResourceGroupComposite;
-import org.rhq.core.domain.util.PageControl;
import org.rhq.core.domain.util.PageList;
-import org.rhq.core.domain.util.PageOrdering;
-import org.rhq.enterprise.gui.coregui.client.ImageManager;
+import org.rhq.enterprise.gui.coregui.client.CoreGUI;
+import org.rhq.enterprise.gui.coregui.client.InitializableView;
+import org.rhq.enterprise.gui.coregui.client.PermissionsLoadedListener;
+import org.rhq.enterprise.gui.coregui.client.PermissionsLoader;
+import org.rhq.enterprise.gui.coregui.client.UserSessionManager;
+import org.rhq.enterprise.gui.coregui.client.dashboard.DashboardContainer;
+import org.rhq.enterprise.gui.coregui.client.dashboard.DashboardView;
+import org.rhq.enterprise.gui.coregui.client.dashboard.PortletFactory;
+import org.rhq.enterprise.gui.coregui.client.dashboard.portlets.groups.GroupAlertsPortlet;
+import org.rhq.enterprise.gui.coregui.client.dashboard.portlets.groups.GroupMetricsPortlet;
+import org.rhq.enterprise.gui.coregui.client.dashboard.portlets.groups.GroupOperationsPortlet;
+import org.rhq.enterprise.gui.coregui.client.gwt.DashboardGWTServiceAsync;
import org.rhq.enterprise.gui.coregui.client.gwt.GWTServiceLookup;
-import org.rhq.enterprise.gui.coregui.client.inventory.common.detail.summary.AbstractActivityView;
-import org.rhq.enterprise.gui.coregui.client.resource.disambiguation.ReportDecorator;
-import org.rhq.enterprise.gui.coregui.client.util.BrowserUtility;
-import org.rhq.enterprise.gui.coregui.client.util.GwtRelativeDurationConverter;
-import org.rhq.enterprise.gui.coregui.client.util.GwtTuple;
-import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableDynamicForm;
+import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableIButton;
+import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableToolStrip;
+import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableVLayout;
/**
- * The content pane for the group Summary>Activity subtab.
+ * The content pane for the group Summary>Dashboard subtab.
*
* @author Simeon Pinder
+ * @author Jay Shaughnessy
*/
-public class ActivityView extends AbstractActivityView {
- private ResourceGroupComposite groupComposite;
+public class ActivityView extends LocatableVLayout implements DashboardContainer, InitializableView {
- public ActivityView(String locatorId, ResourceGroupComposite groupComposite) {
- super(locatorId, groupComposite, null);
- this.groupComposite = groupComposite;
- }
+ private static final String DASHBOARD_NAME_PREFIX = "GroupDashboard_";
- @Override
- protected void onInit() {
- super.onInit();
- loadData();
- }
-
- /**Initiates data request.
- */
- protected void loadData() {
- ResourceGroup group = null;
- GroupCategory groupCategory = null;
- Set<ResourceTypeFacet> facets = null;
- if ((groupComposite != null) && (groupComposite.getResourceGroup() != null)) {
- group = groupComposite.getResourceGroup();
- groupCategory = groupComposite.getResourceGroup().getGroupCategory();
- //Load Facets to conditionally display relevant tabs
- facets = groupComposite.getResourceFacets().getFacets();
-
- getRecentAlerts();
- //events
- if (displayGroupEvents(groupCategory, facets)) {
- getRecentEventUpdates();
- }
- //operations
- if (displayGroupOperations(groupCategory, facets)) {
- getRecentOperations();
- }
- //Config updates
- if (displayGroupConfigurationUpdates(groupCategory, facets)) {
- getRecentConfigurationUpdates();
- }
- //recentMetrics,oobs,pkghistory
- if (groupCategory == GroupCategory.COMPATIBLE) {
- getRecentOobs();
- getRecentPkgHistory();
- getRecentMetrics();
- }
-
- //conditionally display Bundle deployments for groups of platforms only
- displayBundleDeploymentsForPlatformGroups(group);
- }
- }
-
- /** Fetches alerts and updates the DynamicForm instance with the latest
- * alert information.
- */
- private void getRecentAlerts() {
- final int groupId = this.groupComposite.getResourceGroup().getId();
- //fetches last five alerts for this resource
- AlertCriteria criteria = new AlertCriteria();
- PageControl pageControl = new PageControl(0, 5);
- pageControl.initDefaultOrderingField("ctime", PageOrdering.DESC);
- criteria.setPageControl(pageControl);
- criteria.addFilterResourceGroupIds(groupId);
- GWTServiceLookup.getAlertService().findAlertsByCriteria(criteria, new AsyncCallback<PageList<Alert>>() {
- @Override
- public void onSuccess(PageList<Alert> result) {
- VLayout column = new VLayout();
- column.setHeight(10);
- if (!result.isEmpty()) {
- int rowNum = 0;
- for (Alert alert : result) {
- // alert history records do not have a usable locatorId, we'll use rownum, which is unique and
- // may be repeatable.
- LocatableDynamicForm row = new LocatableDynamicForm(recentAlertsContent.extendLocatorId(String
- .valueOf(rowNum++)));
- row.setNumCols(3);
-
- StaticTextItem iconItem = newTextItemIcon(ImageManager.getAlertIcon(alert.getAlertDefinition()
- .getPriority()), alert.getAlertDefinition().getPriority().getDisplayName());
- LinkItem link = newLinkItem(alert.getAlertDefinition().getName() + ": ",
- ReportDecorator.GWT_GROUP_URL + groupId + "/Alerts/History/" + alert.getId());
- StaticTextItem time = newTextItem(GwtRelativeDurationConverter.format(alert.getCtime()));
- row.setItems(iconItem, link, time);
-
- column.addMember(row);
- }
- //link to more details
- LocatableDynamicForm row = new LocatableDynamicForm(recentAlertsContent.extendLocatorId(String
- .valueOf(rowNum++)));
- addSeeMoreLink(row, ReportDecorator.GWT_GROUP_URL + groupId + "/Alerts/History/", column);
- } else {
- LocatableDynamicForm row = createEmptyDisplayRow(recentAlertsContent.extendLocatorId("None"),
- RECENT_ALERTS_NONE);
- column.addMember(row);
- }
- for (Canvas child : recentAlertsContent.getChildren()) {
- child.destroy();
- }
- recentAlertsContent.addChild(column);
- recentAlertsContent.markForRedraw();
- }
+ private ResourceGroupComposite groupComposite;
- @Override
- public void onFailure(Throwable caught) {
- Log.debug("Error retrieving recent alerts for group [" + groupId + "]:" + caught.getMessage());
- }
- });
- }
+ private DashboardGWTServiceAsync dashboardService = GWTServiceLookup.getDashboardService();
- /** Fetches operations and updates the DynamicForm instance with the latest
- * operation information.
- */
- private void getRecentOperations() {
- final int groupId = this.groupComposite.getResourceGroup().getId();
- //fetches five most recent operations.
- PageControl pageControl = new PageControl(0, 5);
-
- GroupOperationHistoryCriteria criteria = new GroupOperationHistoryCriteria();
- List<Integer> filterResourceGroupIds = new ArrayList<Integer>();
- filterResourceGroupIds.add(groupId);
- criteria.addFilterResourceGroupIds(filterResourceGroupIds);
- criteria.setPageControl(pageControl);
- criteria.addSortStatus(PageOrdering.DESC);
-
- GWTServiceLookup.getOperationService().findGroupOperationHistoriesByCriteria(criteria,
- new AsyncCallback<PageList<GroupOperationHistory>>() {
-
- @Override
- public void onFailure(Throwable caught) {
- Log.debug("Error retrieving recent operations for group [" + groupId + "]:" + caught.getMessage());
- }
+ private DashboardView dashboardView;
- @Override
- public void onSuccess(PageList<GroupOperationHistory> result) {
- VLayout column = new VLayout();
- column.setHeight(10);
- if (!result.isEmpty()) {
- int rowNum = 0;
- for (GroupOperationHistory report : result) {
- // operation history records do not have a usable locatorId, we'll use rownum, which is unique and
- // may be repeatable.
- LocatableDynamicForm row = new LocatableDynamicForm(recentOperationsContent
- .extendLocatorId(String.valueOf(rowNum)));
- row.setNumCols(3);
-
- StaticTextItem iconItem = newTextItemIcon(ImageManager.getOperationResultsIcon(report
- .getStatus()), report.getStatus().getDisplayName());
- LinkItem link = newLinkItem(report.getOperationDefinition().getDisplayName() + ": ",
- ReportDecorator.GWT_GROUP_URL + groupId + "/Operations/History/" + report.getId());
- StaticTextItem time = newTextItem(GwtRelativeDurationConverter.format(report
- .getStartedTime()));
- row.setItems(iconItem, link, time);
-
- column.addMember(row);
- }
- //insert see more link
- LocatableDynamicForm row = new LocatableDynamicForm(recentOperationsContent
- .extendLocatorId(String.valueOf(rowNum)));
- addSeeMoreLink(row, ReportDecorator.GWT_GROUP_URL + groupId + "/Operations/History/", column);
- } else {
- LocatableDynamicForm row = createEmptyDisplayRow(recentOperationsContent
- .extendLocatorId("None"), RECENT_OPERATIONS_NONE);
- column.addMember(row);
- }
- for (Canvas child : recentOperationsContent.getChildren()) {
- child.destroy();
- }
- recentOperationsContent.addChild(column);
- recentOperationsContent.markForRedraw();
- }
- });
- }
+ private LocatableToolStrip footer;
+ private IButton editButton;
+ private IButton resetButton;
- /** Fetches configuration updates and updates the DynamicForm instance with the latest
- * config change information.
- */
- private void getRecentConfigurationUpdates() {
- final int groupId = this.groupComposite.getResourceGroup().getId();
-
- PageControl lastFive = new PageControl(0, 5);
- GroupResourceConfigurationUpdateCriteria criteria = new GroupResourceConfigurationUpdateCriteria();
- criteria.setPageControl(lastFive);
- criteria.addSortStatus(PageOrdering.DESC);
- List<Integer> filterResourceGroupIds = new ArrayList<Integer>();
- filterResourceGroupIds.add(groupId);
- criteria.addFilterResourceGroupIds(filterResourceGroupIds);
-
- GWTServiceLookup.getConfigurationService().findGroupResourceConfigurationUpdatesByCriteria(criteria,
- new AsyncCallback<PageList<GroupResourceConfigurationUpdate>>() {
-
- @Override
- public void onFailure(Throwable caught) {
- Log.debug("Error retrieving recent configuration updates for group [" + groupId + "]:"
- + caught.getMessage());
- }
+ // Capture the user's global permissions for use by any dashboard or portlet that may need it for rendering.
+ private Set<Permission> globalPermissions;
- @Override
- public void onSuccess(PageList<GroupResourceConfigurationUpdate> result) {
- VLayout column = new VLayout();
- column.setHeight(10);
- if (!result.isEmpty()) {
- int rowNum = 0;
- for (GroupResourceConfigurationUpdate update : result) {
- // config update history records do not have a usable locatorId, we'll use rownum, which is unique and
- // may be repeatable.
- LocatableDynamicForm row = new LocatableDynamicForm(recentConfigurationContent
- .extendLocatorId(String.valueOf(rowNum)));
- row.setNumCols(3);
-
- StaticTextItem iconItem = newTextItemIcon(ImageManager.getResourceConfigurationIcon(update
- .getStatus()), null);
- String linkTitle = MSG.view_resource_inventory_activity_changed_by() + " "
- + update.getSubjectName() + ":";
- if ((update.getSubjectName() == null) || (update.getSubjectName().trim().isEmpty())) {
- linkTitle = MSG.common_msg_changeAutoDetected();
- }
- LinkItem link = newLinkItem(linkTitle, ReportDecorator.GWT_GROUP_URL + groupId
- + "/Configuration/History/" + update.getId());
- StaticTextItem time = newTextItem(GwtRelativeDurationConverter.format(update
- .getCreatedTime()));
+ private boolean editMode = false;
- row.setItems(iconItem, link, time);
- column.addMember(row);
- }
- //insert see more link
- LocatableDynamicForm row = new LocatableDynamicForm(recentConfigurationContent
- .extendLocatorId(String.valueOf(rowNum)));
- addSeeMoreLink(row, ReportDecorator.GWT_GROUP_URL + groupId + "/Configuration/History/", column);
- } else {
- LocatableDynamicForm row = createEmptyDisplayRow(recentConfigurationContent
- .extendLocatorId("None"), RECENT_CONFIGURATIONS_NONE);
- column.addMember(row);
- }
- //cleanup
- for (Canvas child : recentConfigurationContent.getChildren()) {
- child.destroy();
- }
- recentConfigurationContent.addChild(column);
- recentConfigurationContent.markForRedraw();
+ private boolean isInitialized = false;
- }
- });
+ public ActivityView(String locatorId, ResourceGroupComposite groupComposite) {
+ super(locatorId);
+ this.groupComposite = groupComposite;
}
- /** Fetches recent events and updates the DynamicForm instance with the latest
- * event information over last 24hrs.
- */
- private void getRecentEventUpdates() {
- final int groupId = this.groupComposite.getResourceGroup().getId();
- long now = System.currentTimeMillis();
- long nowMinus24Hours = now - (24 * 60 * 60 * 1000);
- GWTServiceLookup.getEventService().getEventCountsBySeverityForGroup(groupId, nowMinus24Hours, now,
- new AsyncCallback<Map<EventSeverity, Integer>>() {
-
- @Override
- public void onFailure(Throwable caught) {
- Log
- .debug("Error retrieving recent event counts for group [" + groupId + "]:"
- + caught.getMessage());
- }
-
- @Override
- public void onSuccess(Map<EventSeverity, Integer> eventCounts) {
- //Now populated Tuples
- List<GwtTuple<EventSeverity, Integer>> results = new ArrayList<GwtTuple<EventSeverity, Integer>>();
- for (EventSeverity severity : eventCounts.keySet()) {
- int count = eventCounts.get(severity);
- if (count > 0) {
- results.add(new GwtTuple<EventSeverity, Integer>(severity, count));
- }
- }
- //build display
- VLayout column = new VLayout();
- column.setHeight(10);
-
- if (!results.isEmpty()) {
- int rowNum = 0;
- for (GwtTuple<EventSeverity, Integer> tuple : results) {
- // event history records do not have a usable locatorId, we'll use rownum, which is unique and
- // may be repeatable.
- LocatableDynamicForm row = new LocatableDynamicForm(recentEventsContent
- .extendLocatorId(String.valueOf(rowNum)));
- row.setNumCols(2);
- row.setWidth(10);//pack.
-
- //icon
- StaticTextItem iconItem = newTextItemIcon(ImageManager.getEventSeverityIcon(tuple
- .getLefty()), tuple.getLefty().name());
- //count
- StaticTextItem count = newTextItem(String.valueOf(tuple.righty));
- row.setItems(iconItem, count);
-
- column.addMember(row);
+ @Override
+ protected void onInit() {
+ if (!isInitialized()) {
+ super.onInit();
+
+ // first async call to get global permissions
+ new PermissionsLoader().loadExplicitGlobalPermissions(new PermissionsLoadedListener() {
+
+ public void onPermissionsLoaded(Set<Permission> permissions) {
+ globalPermissions = permissions;
+
+ // now make async call to look for customized dash for this user and entity
+ DashboardCriteria criteria = new DashboardCriteria();
+ criteria.addFilterCategory(DashboardCategory.GROUP);
+ criteria.addFilterGroupId(groupComposite.getResourceGroup().getId());
+ dashboardService.findDashboardsByCriteria(criteria, new AsyncCallback<PageList<Dashboard>>() {
+ public void onFailure(Throwable caught) {
+ CoreGUI.getErrorHandler().handleError(MSG.view_dashboardsManager_error1(), caught);
}
- //insert see more link
- LocatableDynamicForm row = new LocatableDynamicForm(recentEventsContent.extendLocatorId(String
- .valueOf(rowNum)));
- addSeeMoreLink(row, ReportDecorator.GWT_GROUP_URL + groupId + "/Events/History/", column);
- } else {
- LocatableDynamicForm row = createEmptyDisplayRow(recentEventsContent.extendLocatorId("None"),
- RECENT_EVENTS_NONE);
- column.addMember(row);
- }
- //cleanup
- for (Canvas child : recentEventsContent.getChildren()) {
- child.destroy();
- }
- recentEventsContent.addChild(column);
- recentEventsContent.markForRedraw();
- }
- });
- }
- /** Fetches OOB measurements and updates the DynamicForm instance with the latest 5
- * oob change details.
- */
- private void getRecentOobs() {
- final int groupId = this.groupComposite.getResourceGroup().getId();
-
- GWTServiceLookup.getMeasurementDataService().getHighestNOOBsForGroup(groupId, 5,
- new AsyncCallback<PageList<MeasurementOOBComposite>>() {
- @Override
- public void onFailure(Throwable caught) {
- Log.debug("Error retrieving recent out of bound metrics for group [" + groupId + "]:"
- + caught.getMessage());
- }
+ public void onSuccess(final PageList<Dashboard> result) {
+ Dashboard dashboard = result.isEmpty() ? getDefaultDashboard() : result.get(0);
+ setDashboard(dashboard);
+
+ isInitialized = true;
- @Override
- public void onSuccess(PageList<MeasurementOOBComposite> result) {
- VLayout column = new VLayout();
- column.setHeight(10);
- if (!result.isEmpty()) {
- for (MeasurementOOBComposite oob : result) {
- LocatableDynamicForm row = new LocatableDynamicForm(recentOobContent.extendLocatorId(oob
- .getScheduleName()));
- row.setNumCols(2);
-
- String title = oob.getScheduleName() + ":";
- String destination = "/resource/common/monitor/Visibility.do?m=" + oob.getDefinitionId()
- + "&id=" + groupId + "&mode=chartSingleMetricSingleResource";
- LinkItem link = newLinkItem(title, destination);
- StaticTextItem time = newTextItem(GwtRelativeDurationConverter.format(oob.getTimestamp()));
-
- row.setItems(link, time);
- column.addMember(row);
+ // draw() may be done since onInit finishes asynchronously, if so redraw
+ if (isDrawn()) {
+ markForRedraw();
+ }
}
- //insert see more link spinder(2/24/11): no page that displays all oobs... See More not possible.
- } else {
- LocatableDynamicForm row = createEmptyDisplayRow(recentOobContent.extendLocatorId("None"),
- RECENT_OOB_NONE);
- column.addMember(row);
- }
- recentOobContent.setContents("");
- for (Canvas child : recentOobContent.getChildren()) {
- child.destroy();
- }
- recentOobContent.addChild(column);
- recentOobContent.markForRedraw();
+ });
}
});
+ }
}
- /** Fetches recent package history information and updates the DynamicForm instance with details.
- */
- private void getRecentPkgHistory() {
- final int groupId = this.groupComposite.getResourceGroup().getId();
- InstalledPackageHistoryCriteria criteria = new InstalledPackageHistoryCriteria();
- PageControl pageControl = new PageControl(0, 5);
- criteria.setPageControl(pageControl);
- criteria.addFilterResourceGroupIds(groupId);
- criteria.addSortStatus(PageOrdering.DESC);
-
- GWTServiceLookup.getContentService().findInstalledPackageHistoryByCriteria(criteria,
-
- new AsyncCallback<PageList<InstalledPackageHistory>>() {
- @Override
- public void onFailure(Throwable caught) {
- Log.debug("Error retrieving installed package history for group [" + groupId + "]:"
- + caught.getMessage());
+ private void setDashboard(Dashboard dashboard) {
+ Canvas[] members = getMembers();
+ removeMembers(members);
+ //pass in the group information
+ dashboardView = new DashboardView(extendLocatorId(dashboard.getName()), this, dashboard, groupComposite, null);
+ addMember(dashboardView);
+
+ footer = new LocatableToolStrip(extendLocatorId("Footer"));
+ footer.setPadding(5);
+ footer.setWidth100();
+ footer.setMembersMargin(15);
+
+ editButton = new LocatableIButton(footer.extendLocatorId("Mode"), editMode ? MSG.common_title_view_mode() : MSG
+ .common_title_edit_mode());
+ editButton.setAutoFit(true);
+ editButton.addClickHandler(new ClickHandler() {
+ public void onClick(ClickEvent clickEvent) {
+ editMode = !editMode;
+ editButton.setTitle(editMode ? MSG.common_title_view_mode() : MSG.common_title_edit_mode());
+ dashboardView.setEditMode(editMode);
}
+ });
- @Override
- public void onSuccess(PageList<InstalledPackageHistory> result) {
- VLayout column = new VLayout();
- column.setHeight(10);
- if (!result.isEmpty()) {
- for (InstalledPackageHistory history : result) {
- LocatableDynamicForm row = new LocatableDynamicForm(recentPkgHistoryContent
- .extendLocatorId(history.getPackageVersion().getFileName()
- + history.getPackageVersion().getVersion()));
- row.setNumCols(3);
-
- StaticTextItem iconItem = newTextItemIcon("subsystems/content/Package_16.png", null);
- String title = history.getPackageVersion().getFileName() + ":";
- String destination = "/rhq/resource/content/audit-trail-item.xhtml?id=" + groupId
- + "&selectedHistoryId=" + history.getId();
- LinkItem link = newLinkItem(title, destination);
- StaticTextItem time = newTextItem(GwtRelativeDurationConverter.format(history.getTimestamp()));
-
- row.setItems(iconItem, link, time);
- column.addMember(row);
+ resetButton = new LocatableIButton(footer.extendLocatorId("Reset"), MSG.common_button_reset());
+ resetButton.setAutoFit(true);
+ resetButton.addClickHandler(new ClickHandler() {
+ public void onClick(ClickEvent clickEvent) {
+ String message = MSG.view_summaryDashboard_resetConfirm();
+
+ SC.ask(message, new BooleanCallback() {
+ public void execute(Boolean confirmed) {
+ if (confirmed) {
+ dashboardView.delete();
+ setDashboard(getDefaultDashboard());
+ markForRedraw();
+ }
}
- // //insert see more link
- // LocatableDynamicForm row = new LocatableDynamicForm(recentPkgHistoryContent
- // .extendLocatorId("PkgHistoryContentSeeMore"));
- // String destination = "/rhq/resource/content/audit-trail-item.xhtml?id=" + groupId;
- // addSeeMoreLink(row, destination, column);
- } else {
- LocatableDynamicForm row = createEmptyDisplayRow(recentPkgHistoryContent.extendLocatorId("None"),
- RECENT_PKG_HISTORY_NONE);
- column.addMember(row);
- }
- //cleanup
- for (Canvas child : recentPkgHistoryContent.getChildren()) {
- child.destroy();
- }
- recentPkgHistoryContent.addChild(column);
- recentPkgHistoryContent.markForRedraw();
+ });
}
});
- }
- /** Fetches recent metric information and updates the DynamicForm instance with i)sparkline information,
- * ii) link to recent metric graph for more details and iii) last metric value formatted to show significant
- * digits.
- */
- private void getRecentMetrics() {
+ footer.addMember(editButton);
+ footer.addMember(resetButton);
- //display container
- final VLayout column = new VLayout();
- column.setHeight(10);//pack
- final int groupId = this.groupComposite.getResourceGroup().getId();
+ addMember(footer);
+ }
- //retrieve all relevant measurement definition ids.
- Set<MeasurementDefinition> definitions = this.groupComposite.getResourceGroup().getResourceType()
- .getMetricDefinitions();
+ protected Dashboard getDefaultDashboard() {
+ Subject sessionSubject = UserSessionManager.getSessionSubject();
+ ResourceGroup group = groupComposite.getResourceGroup();
+
+ Dashboard dashboard = new Dashboard();
+
+ dashboard.setName(DASHBOARD_NAME_PREFIX + sessionSubject.getId() + "_" + group.getId());
+ dashboard.setCategory(DashboardCategory.GROUP);
+ dashboard.setGroup(group);
+ dashboard.setColumns(2);
+
+ // set leftmost column and let the rest be equally divided
+ dashboard.setColumnWidths("40%");
+ dashboard.getConfiguration().put(new PropertySimple(Dashboard.CFG_BACKGROUND, "#F1F2F3"));
+
+ //figure out which portlets to display and how
+ HashMap<String, String> groupKeyNameMap = PortletFactory.getRegisteredGroupPortletNameMap();
+ groupKeyNameMap = DashboardView.processPortletNameMapForGroup(groupKeyNameMap, groupComposite);
+ int colLeft = 0;
+ int colRight = 1;
+ int rowLeft = 0;
+ int rowRight = 0;
+ //Left Column
+ if (groupKeyNameMap.containsKey(GroupMetricsPortlet.KEY)) {//measurments top left if available
+ DashboardPortlet measurements = new DashboardPortlet(GroupMetricsPortlet.NAME, GroupMetricsPortlet.KEY, 220);
+ dashboard.addPortlet(measurements, colLeft, rowLeft++);
+ groupKeyNameMap.remove(GroupMetricsPortlet.KEY);
+ }
- //build id mapping for measurementDefinition instances Ex. Free Memory -> MeasurementDefinition[100071]
- final HashMap<String, MeasurementDefinition> measurementDefMap = new HashMap<String, MeasurementDefinition>();
- for (MeasurementDefinition definition : definitions) {
- measurementDefMap.put(definition.getDisplayName(), definition);
+ // right Column(approx 60%. As larger more room to display table and N rows.)
+ if (groupKeyNameMap.containsKey(GroupAlertsPortlet.KEY)) {//alerts top right if available
+ DashboardPortlet alerts = new DashboardPortlet(GroupAlertsPortlet.NAME, GroupAlertsPortlet.KEY, 220);
+ dashboard.addPortlet(alerts, colRight, rowRight++);
+ groupKeyNameMap.remove(GroupAlertsPortlet.KEY);
}
- //bundle definition ids for asynch call.
- int[] definitionArrayIds = new int[definitions.size()];
- final String[] displayOrder = new String[definitions.size()];
- measurementDefMap.keySet().toArray(displayOrder);
- //sort the charting data ex. Free Memory, Free Swap Space,..System Load
- Arrays.sort(displayOrder);
-
- //organize definitionArrayIds for ordered request on server.
- int index = 0;
- for (String definitionToDisplay : displayOrder) {
- definitionArrayIds[index++] = measurementDefMap.get(definitionToDisplay).getId();
+ if (groupKeyNameMap.containsKey(GroupOperationsPortlet.KEY)) {//operations if available
+ DashboardPortlet ops = new DashboardPortlet(GroupOperationsPortlet.NAME, GroupOperationsPortlet.KEY, 220);
+ dashboard.addPortlet(ops, colRight, rowRight++);
+ groupKeyNameMap.remove(GroupOperationsPortlet.KEY);
}
- //make the asynchronous call for all the measurement data
- GWTServiceLookup.getMeasurementDataService().findDataForCompatibleGroup(groupId, definitionArrayIds,
- System.currentTimeMillis() - (1000L * 60 * 60 * 8), System.currentTimeMillis(), 60,
- new AsyncCallback<List<List<MeasurementDataNumericHighLowComposite>>>() {
- @Override
- public void onFailure(Throwable caught) {
- Log.debug("Error retrieving recent metrics charting data for group [" + groupId + "]:"
- + caught.getMessage());
+ //Fill out left column(typically smaller portlets) then alternate cols with remaining
+ boolean displayLeft = false;
+ for (String key : groupKeyNameMap.keySet()) {
+ DashboardPortlet portlet = new DashboardPortlet(groupKeyNameMap.get(key), key, 100);
+ if (rowLeft < 4) {
+ dashboard.addPortlet(portlet, colLeft, rowLeft++);
+ } else {//alternate
+ if (!displayLeft) {
+ dashboard.addPortlet(portlet, colRight, rowRight++);
+ } else {
+ dashboard.addPortlet(portlet, colLeft, rowLeft++);
}
+ //toggle
+ displayLeft = !displayLeft;
+ }
+ }
+ return dashboard;
+ }
- @Override
- public void onSuccess(List<List<MeasurementDataNumericHighLowComposite>> results) {
- if (!results.isEmpty()) {
- boolean someChartedData = false;
- //iterate over the retrieved charting data
- for (int index = 0; index < displayOrder.length; index++) {
- //retrieve the correct measurement definition
- MeasurementDefinition md = measurementDefMap.get(displayOrder[index]);
-
- //load the data results for the given metric definition
- List<MeasurementDataNumericHighLowComposite> data = results.get(index);
-
- //locate last and minimum values.
- double lastValue = -1;
- double minValue = Double.MAX_VALUE;//
- for (MeasurementDataNumericHighLowComposite d : data) {
- if ((!Double.isNaN(d.getValue()))
- && (String.valueOf(d.getValue()).indexOf("NaN") == -1)) {
- if (d.getValue() < minValue) {
- minValue = d.getValue();
- }
- lastValue = d.getValue();
- }
- }
-
- //collapse the data into comma delimited list for consumption by third party javascript library(jquery.sparkline)
- String commaDelimitedList = "";
-
- for (MeasurementDataNumericHighLowComposite d : data) {
- if ((!Double.isNaN(d.getValue()))
- && (String.valueOf(d.getValue()).indexOf("NaN") == -1)) {
- commaDelimitedList += d.getValue() + ",";
- }
- }
- LocatableDynamicForm row = new LocatableDynamicForm(recentMeasurementsContent
- .extendLocatorId(md.getName()));
- row.setNumCols(3);
- HTMLFlow graph = new HTMLFlow();
- // String contents = "<span id='sparkline_" + index + "' class='dynamicsparkline' width='0'>"
- // + commaDelimitedList + "</span>";
- String contents = "<span id='sparkline_" + index + "' class='dynamicsparkline' width='0' "
- + "values='" + commaDelimitedList + "'>...</span>";
- graph.setContents(contents);
- graph.setContentsType(ContentsType.PAGE);
- //diable scrollbars on span
- graph.setScrollbarSize(0);
-
- CanvasItem graphContainer = new CanvasItem();
- graphContainer.setShowTitle(false);
- graphContainer.setHeight(16);
- graphContainer.setWidth(60);
- graphContainer.setCanvas(graph);
-
- //Link/title element
- //TODO: spinder, change link whenever portal.war/graphing is removed.
- String title = md.getDisplayName() + ":";
- // String destination = "/resource/common/monitor/Visibility.do?mode=chartSingleMetricSingleResource&id="
- // + resourceId + "&m=" + md.getId();
- String destination = "/resource/common/monitor/Visibility.do?mode=chartSingleMetricMultiResource&groupId="
- + groupId + "&m=" + md.getId();
- LinkItem link = newLinkItem(title, destination);
-
- //Value
- String convertedValue = lastValue + " " + md.getUnits();
- convertedValue = convertLastValueForDisplay(lastValue, md);
- StaticTextItem value = newTextItem(convertedValue);
-
- row.setItems(graphContainer, link, value);
- //if graph content returned
- if ((md.getName().trim().indexOf("Trait.") == -1) && (lastValue != -1)) {
- column.addMember(row);
- someChartedData = true;
- }
- }
- if (!someChartedData) {// when there are results but no chartable entries.
- LocatableDynamicForm row = createEmptyDisplayRow(recentMeasurementsContent
- .extendLocatorId("None"), RECENT_MEASUREMENTS_NONE);
- column.addMember(row);
- } else {
- //insert see more link
- LocatableDynamicForm row = new LocatableDynamicForm(recentMeasurementsContent
- .extendLocatorId("RecentMeasurementsContentSeeMore"));
- addSeeMoreLink(row, ReportDecorator.GWT_GROUP_URL + groupId + "/Monitoring/Graphs/", column);
- }
- //call out to 3rd party javascript lib
- BrowserUtility.graphSparkLines();
- } else {
- LocatableDynamicForm row = createEmptyDisplayRow(recentMeasurementsContent
- .extendLocatorId("None"), RECENT_MEASUREMENTS_NONE);
- column.addMember(row);
- }
- }
- });
+ @Override
+ public boolean isInitialized() {
+ return isInitialized;
+ }
- //cleanup
- for (Canvas child : recentMeasurementsContent.getChildren()) {
- child.destroy();
- }
- recentMeasurementsContent.addChild(column);
- recentMeasurementsContent.markForRedraw();
+ public Set<Permission> getGlobalPermissions() {
+ return globalPermissions;
}
- /** Fetches recent bundle deployment information and updates the DynamicForm instance with details.
+ /**
+ * name update not supported because the name is derived from the entity id.
+ * @return
*/
- protected void getRecentBundleDeployments() {
- final int groupId = this.groupComposite.getResourceGroup().getId();
- GroupBundleDeploymentCriteria criteria = new GroupBundleDeploymentCriteria();
- PageControl pageControl = new PageControl(0, 5);
- criteria.setPageControl(pageControl);
- criteria.addFilterResourceGroupIds(groupId);
- criteria.addSortStatus(PageOrdering.DESC);
- criteria.fetchDestination(true);
- criteria.fetchBundleVersion(true);
-
- GWTServiceLookup.getBundleService().findBundleDeploymentsByCriteria(criteria,
- new AsyncCallback<PageList<BundleDeployment>>() {
- @Override
- public void onFailure(Throwable caught) {
- Log.debug("Error retrieving installed bundle deployments for group [" + groupId + "]:"
- + caught.getMessage());
- }
+ public boolean supportsDashboardNameEdit() {
+ return false;
+ }
- @Override
- public void onSuccess(PageList<BundleDeployment> result) {
- VLayout column = new VLayout();
- column.setHeight(10);
- if (!result.isEmpty()) {
- for (BundleDeployment deployment : result) {
- LocatableDynamicForm row = new LocatableDynamicForm(recentBundleDeployContent
- .extendLocatorId(deployment.getBundleVersion().getName()
- + deployment.getBundleVersion().getVersion()));
- row.setNumCols(3);
-
- StaticTextItem iconItem = newTextItemIcon("subsystems/content/Content_16.png", null);
- String title = deployment.getBundleVersion().getName() + "["
- + deployment.getBundleVersion().getVersion() + "]:";
- String destination = ReportDecorator.GWT_BUNDLE_URL
- + deployment.getBundleVersion().getBundle().getId() + "/destinations/"
- + deployment.getDestination().getId();
- LinkItem link = newLinkItem(title, destination);
- StaticTextItem time = newTextItem(GwtRelativeDurationConverter
- .format(deployment.getCtime()));
-
- row.setItems(iconItem, link, time);
- column.addMember(row);
- }
- //insert see more link
- //TODO: spinder:2/25/11 (add this later) no current view for seeing all bundle deployments
- // LocatableDynamicForm row = new LocatableDynamicForm(recentBundleDeployContent.extendLocatorId("RecentBundleContentSeeMore"));
- // addSeeMoreLink(row, LinkManager.getResourceGroupLink(groupId) + "/Events/History/", column);
- } else {
- LocatableDynamicForm row = createEmptyDisplayRow(recentBundleDeployContent
- .extendLocatorId("None"), RECENT_BUNDLE_DEPLOY_NONE);
- column.addMember(row);
- }
- //cleanup
- for (Canvas child : recentBundleDeployContent.getChildren()) {
- child.destroy();
- }
- recentBundleDeployContent.addChild(column);
- recentBundleDeployContent.markForRedraw();
- }
- });
+ public void updateDashboardNames() {
+ return;
}
+
}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/summary/ActivityView2.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/summary/ActivityView2.java
deleted file mode 100644
index af8d09c..0000000
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/summary/ActivityView2.java
+++ /dev/null
@@ -1,257 +0,0 @@
-/*
- * RHQ Management Platform
- * Copyright (C) 2010 Red Hat, Inc.
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-package org.rhq.enterprise.gui.coregui.client.inventory.groups.detail.summary;
-
-import java.util.HashMap;
-import java.util.Set;
-
-import com.google.gwt.user.client.rpc.AsyncCallback;
-import com.smartgwt.client.util.BooleanCallback;
-import com.smartgwt.client.util.SC;
-import com.smartgwt.client.widgets.Canvas;
-import com.smartgwt.client.widgets.IButton;
-import com.smartgwt.client.widgets.events.ClickEvent;
-import com.smartgwt.client.widgets.events.ClickHandler;
-
-import org.rhq.core.domain.auth.Subject;
-import org.rhq.core.domain.authz.Permission;
-import org.rhq.core.domain.configuration.PropertySimple;
-import org.rhq.core.domain.criteria.DashboardCriteria;
-import org.rhq.core.domain.dashboard.Dashboard;
-import org.rhq.core.domain.dashboard.DashboardCategory;
-import org.rhq.core.domain.dashboard.DashboardPortlet;
-import org.rhq.core.domain.resource.group.ResourceGroup;
-import org.rhq.core.domain.resource.group.composite.ResourceGroupComposite;
-import org.rhq.core.domain.util.PageList;
-import org.rhq.enterprise.gui.coregui.client.CoreGUI;
-import org.rhq.enterprise.gui.coregui.client.InitializableView;
-import org.rhq.enterprise.gui.coregui.client.PermissionsLoadedListener;
-import org.rhq.enterprise.gui.coregui.client.PermissionsLoader;
-import org.rhq.enterprise.gui.coregui.client.UserSessionManager;
-import org.rhq.enterprise.gui.coregui.client.dashboard.DashboardContainer;
-import org.rhq.enterprise.gui.coregui.client.dashboard.DashboardView;
-import org.rhq.enterprise.gui.coregui.client.dashboard.PortletFactory;
-import org.rhq.enterprise.gui.coregui.client.dashboard.portlets.groups.GroupAlertsPortlet;
-import org.rhq.enterprise.gui.coregui.client.dashboard.portlets.groups.GroupMetricsPortlet;
-import org.rhq.enterprise.gui.coregui.client.dashboard.portlets.groups.GroupOperationsPortlet;
-import org.rhq.enterprise.gui.coregui.client.gwt.DashboardGWTServiceAsync;
-import org.rhq.enterprise.gui.coregui.client.gwt.GWTServiceLookup;
-import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableIButton;
-import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableToolStrip;
-import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableVLayout;
-
-/**
- * The content pane for the group Summary>Dashboard subtab.
- *
- * @author Simeon Pinder
- * @author Jay Shaughnessy
- */
-
-public class ActivityView2 extends LocatableVLayout implements DashboardContainer, InitializableView {
-
- private static final String DASHBOARD_NAME_PREFIX = "GroupDashboard_";
-
- private ResourceGroupComposite groupComposite;
-
- private DashboardGWTServiceAsync dashboardService = GWTServiceLookup.getDashboardService();
-
- private DashboardView dashboardView;
-
- private LocatableToolStrip footer;
- private IButton editButton;
- private IButton resetButton;
-
- // Capture the user's global permissions for use by any dashboard or portlet that may need it for rendering.
- private Set<Permission> globalPermissions;
-
- private boolean editMode = false;
-
- private boolean isInitialized = false;
-
- public ActivityView2(String locatorId, ResourceGroupComposite groupComposite) {
- super(locatorId);
- this.groupComposite = groupComposite;
- }
-
- @Override
- protected void onInit() {
- if (!isInitialized()) {
- super.onInit();
-
- // first async call to get global permissions
- new PermissionsLoader().loadExplicitGlobalPermissions(new PermissionsLoadedListener() {
-
- public void onPermissionsLoaded(Set<Permission> permissions) {
- globalPermissions = permissions;
-
- // now make async call to look for customized dash for this user and entity
- DashboardCriteria criteria = new DashboardCriteria();
- criteria.addFilterCategory(DashboardCategory.GROUP);
- criteria.addFilterGroupId(groupComposite.getResourceGroup().getId());
- dashboardService.findDashboardsByCriteria(criteria, new AsyncCallback<PageList<Dashboard>>() {
- public void onFailure(Throwable caught) {
- CoreGUI.getErrorHandler().handleError(MSG.view_dashboardsManager_error1(), caught);
- }
-
- public void onSuccess(final PageList<Dashboard> result) {
- Dashboard dashboard = result.isEmpty() ? getDefaultDashboard() : result.get(0);
- setDashboard(dashboard);
-
- isInitialized = true;
-
- // draw() may be done since onInit finishes asynchronously, if so redraw
- if (isDrawn()) {
- markForRedraw();
- }
- }
- });
- }
- });
- }
- }
-
- private void setDashboard(Dashboard dashboard) {
- Canvas[] members = getMembers();
- removeMembers(members);
- //pass in the group information
- dashboardView = new DashboardView(extendLocatorId(dashboard.getName()), this, dashboard, groupComposite, null);
- addMember(dashboardView);
-
- footer = new LocatableToolStrip(extendLocatorId("Footer"));
- footer.setPadding(5);
- footer.setWidth100();
- footer.setMembersMargin(15);
-
- editButton = new LocatableIButton(footer.extendLocatorId("Mode"), editMode ? MSG.common_title_view_mode() : MSG
- .common_title_edit_mode());
- editButton.setAutoFit(true);
- editButton.addClickHandler(new ClickHandler() {
- public void onClick(ClickEvent clickEvent) {
- editMode = !editMode;
- editButton.setTitle(editMode ? MSG.common_title_view_mode() : MSG.common_title_edit_mode());
- dashboardView.setEditMode(editMode);
- }
- });
-
- resetButton = new LocatableIButton(footer.extendLocatorId("Reset"), MSG.common_button_reset());
- resetButton.setAutoFit(true);
- resetButton.addClickHandler(new ClickHandler() {
- public void onClick(ClickEvent clickEvent) {
- String message = MSG.view_summaryDashboard_resetConfirm();
-
- SC.ask(message, new BooleanCallback() {
- public void execute(Boolean confirmed) {
- if (confirmed) {
- dashboardView.delete();
- setDashboard(getDefaultDashboard());
- markForRedraw();
- }
- }
- });
- }
- });
-
- footer.addMember(editButton);
- footer.addMember(resetButton);
-
- addMember(footer);
- }
-
- protected Dashboard getDefaultDashboard() {
- Subject sessionSubject = UserSessionManager.getSessionSubject();
- ResourceGroup group = groupComposite.getResourceGroup();
-
- Dashboard dashboard = new Dashboard();
-
- dashboard.setName(DASHBOARD_NAME_PREFIX + sessionSubject.getId() + "_" + group.getId());
- dashboard.setCategory(DashboardCategory.GROUP);
- dashboard.setGroup(group);
- dashboard.setColumns(2);
-
- // set leftmost column and let the rest be equally divided
- dashboard.setColumnWidths("40%");
- dashboard.getConfiguration().put(new PropertySimple(Dashboard.CFG_BACKGROUND, "#F1F2F3"));
-
- //figure out which portlets to display and how
- HashMap<String, String> groupKeyNameMap = PortletFactory.getRegisteredGroupPortletNameMap();
- groupKeyNameMap = DashboardView.processPortletNameMapForGroup(groupKeyNameMap, groupComposite);
- int colLeft = 0;
- int colRight = 1;
- int rowLeft = 0;
- int rowRight = 0;
- //Left Column
- if (groupKeyNameMap.containsKey(GroupMetricsPortlet.KEY)) {//measurments top left if available
- DashboardPortlet measurements = new DashboardPortlet(GroupMetricsPortlet.NAME, GroupMetricsPortlet.KEY, 220);
- dashboard.addPortlet(measurements, colLeft, rowLeft++);
- groupKeyNameMap.remove(GroupMetricsPortlet.KEY);
- }
-
- // right Column(approx 60%. As larger more room to display table and N rows.)
- if (groupKeyNameMap.containsKey(GroupAlertsPortlet.KEY)) {//alerts top right if available
- DashboardPortlet alerts = new DashboardPortlet(GroupAlertsPortlet.NAME, GroupAlertsPortlet.KEY, 220);
- dashboard.addPortlet(alerts, colRight, rowRight++);
- groupKeyNameMap.remove(GroupAlertsPortlet.KEY);
- }
- if (groupKeyNameMap.containsKey(GroupOperationsPortlet.KEY)) {//operations if available
- DashboardPortlet ops = new DashboardPortlet(GroupOperationsPortlet.NAME, GroupOperationsPortlet.KEY, 220);
- dashboard.addPortlet(ops, colRight, rowRight++);
- groupKeyNameMap.remove(GroupOperationsPortlet.KEY);
- }
-
- //Fill out left column(typically smaller portlets) then alternate cols with remaining
- boolean displayLeft = false;
- for (String key : groupKeyNameMap.keySet()) {
- DashboardPortlet portlet = new DashboardPortlet(groupKeyNameMap.get(key), key, 100);
- if (rowLeft < 4) {
- dashboard.addPortlet(portlet, colLeft, rowLeft++);
- } else {//alternate
- if (!displayLeft) {
- dashboard.addPortlet(portlet, colRight, rowRight++);
- } else {
- dashboard.addPortlet(portlet, colLeft, rowLeft++);
- }
- //toggle
- displayLeft = !displayLeft;
- }
- }
- return dashboard;
- }
-
- @Override
- public boolean isInitialized() {
- return isInitialized;
- }
-
- public Set<Permission> getGlobalPermissions() {
- return globalPermissions;
- }
-
- /**
- * name update not supported because the name is derived from the entity id.
- * @return
- */
- public boolean supportsDashboardNameEdit() {
- return false;
- }
-
- public void updateDashboardNames() {
- return;
- }
-
-}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/summary/ActivityView3.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/summary/ActivityView3.java
new file mode 100644
index 0000000..d8ef22f
--- /dev/null
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/summary/ActivityView3.java
@@ -0,0 +1,702 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2010 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+package org.rhq.enterprise.gui.coregui.client.inventory.groups.detail.summary;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import com.allen_sauer.gwt.log.client.Log;
+import com.google.gwt.user.client.rpc.AsyncCallback;
+import com.smartgwt.client.types.ContentsType;
+import com.smartgwt.client.widgets.Canvas;
+import com.smartgwt.client.widgets.HTMLFlow;
+import com.smartgwt.client.widgets.form.fields.CanvasItem;
+import com.smartgwt.client.widgets.form.fields.LinkItem;
+import com.smartgwt.client.widgets.form.fields.StaticTextItem;
+import com.smartgwt.client.widgets.layout.VLayout;
+
+import org.rhq.core.domain.alert.Alert;
+import org.rhq.core.domain.bundle.BundleDeployment;
+import org.rhq.core.domain.configuration.group.GroupResourceConfigurationUpdate;
+import org.rhq.core.domain.content.InstalledPackageHistory;
+import org.rhq.core.domain.criteria.AlertCriteria;
+import org.rhq.core.domain.criteria.GroupBundleDeploymentCriteria;
+import org.rhq.core.domain.criteria.GroupOperationHistoryCriteria;
+import org.rhq.core.domain.criteria.GroupResourceConfigurationUpdateCriteria;
+import org.rhq.core.domain.criteria.InstalledPackageHistoryCriteria;
+import org.rhq.core.domain.event.EventSeverity;
+import org.rhq.core.domain.measurement.MeasurementDefinition;
+import org.rhq.core.domain.measurement.composite.MeasurementDataNumericHighLowComposite;
+import org.rhq.core.domain.measurement.composite.MeasurementOOBComposite;
+import org.rhq.core.domain.operation.GroupOperationHistory;
+import org.rhq.core.domain.resource.ResourceTypeFacet;
+import org.rhq.core.domain.resource.group.GroupCategory;
+import org.rhq.core.domain.resource.group.ResourceGroup;
+import org.rhq.core.domain.resource.group.composite.ResourceGroupComposite;
+import org.rhq.core.domain.util.PageControl;
+import org.rhq.core.domain.util.PageList;
+import org.rhq.core.domain.util.PageOrdering;
+import org.rhq.enterprise.gui.coregui.client.ImageManager;
+import org.rhq.enterprise.gui.coregui.client.gwt.GWTServiceLookup;
+import org.rhq.enterprise.gui.coregui.client.inventory.common.detail.summary.AbstractActivityView;
+import org.rhq.enterprise.gui.coregui.client.resource.disambiguation.ReportDecorator;
+import org.rhq.enterprise.gui.coregui.client.util.BrowserUtility;
+import org.rhq.enterprise.gui.coregui.client.util.GwtRelativeDurationConverter;
+import org.rhq.enterprise.gui.coregui.client.util.GwtTuple;
+import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableDynamicForm;
+
+/**
+ * The content pane for the group Summary>Activity subtab.
+ *
+ * @author Simeon Pinder
+ */
+public class ActivityView3 extends AbstractActivityView {
+
+ private ResourceGroupComposite groupComposite;
+
+ public ActivityView3(String locatorId, ResourceGroupComposite groupComposite) {
+ super(locatorId, groupComposite, null);
+ this.groupComposite = groupComposite;
+ }
+
+ @Override
+ protected void onInit() {
+ super.onInit();
+ loadData();
+ }
+
+ /**Initiates data request.
+ */
+ protected void loadData() {
+ ResourceGroup group = null;
+ GroupCategory groupCategory = null;
+ Set<ResourceTypeFacet> facets = null;
+ if ((groupComposite != null) && (groupComposite.getResourceGroup() != null)) {
+ group = groupComposite.getResourceGroup();
+ groupCategory = groupComposite.getResourceGroup().getGroupCategory();
+ //Load Facets to conditionally display relevant tabs
+ facets = groupComposite.getResourceFacets().getFacets();
+
+ getRecentAlerts();
+ //events
+ if (displayGroupEvents(groupCategory, facets)) {
+ getRecentEventUpdates();
+ }
+ //operations
+ if (displayGroupOperations(groupCategory, facets)) {
+ getRecentOperations();
+ }
+ //Config updates
+ if (displayGroupConfigurationUpdates(groupCategory, facets)) {
+ getRecentConfigurationUpdates();
+ }
+ //recentMetrics,oobs,pkghistory
+ if (groupCategory == GroupCategory.COMPATIBLE) {
+ getRecentOobs();
+ getRecentPkgHistory();
+ getRecentMetrics();
+ }
+
+ //conditionally display Bundle deployments for groups of platforms only
+ displayBundleDeploymentsForPlatformGroups(group);
+ }
+ }
+
+ /** Fetches alerts and updates the DynamicForm instance with the latest
+ * alert information.
+ */
+ private void getRecentAlerts() {
+ final int groupId = this.groupComposite.getResourceGroup().getId();
+ //fetches last five alerts for this resource
+ AlertCriteria criteria = new AlertCriteria();
+ PageControl pageControl = new PageControl(0, 5);
+ pageControl.initDefaultOrderingField("ctime", PageOrdering.DESC);
+ criteria.setPageControl(pageControl);
+ criteria.addFilterResourceGroupIds(groupId);
+ GWTServiceLookup.getAlertService().findAlertsByCriteria(criteria, new AsyncCallback<PageList<Alert>>() {
+ @Override
+ public void onSuccess(PageList<Alert> result) {
+ VLayout column = new VLayout();
+ column.setHeight(10);
+ if (!result.isEmpty()) {
+ int rowNum = 0;
+ for (Alert alert : result) {
+ // alert history records do not have a usable locatorId, we'll use rownum, which is unique and
+ // may be repeatable.
+ LocatableDynamicForm row = new LocatableDynamicForm(recentAlertsContent.extendLocatorId(String
+ .valueOf(rowNum++)));
+ row.setNumCols(3);
+
+ StaticTextItem iconItem = newTextItemIcon(ImageManager.getAlertIcon(alert.getAlertDefinition()
+ .getPriority()), alert.getAlertDefinition().getPriority().getDisplayName());
+ LinkItem link = newLinkItem(alert.getAlertDefinition().getName() + ": ",
+ ReportDecorator.GWT_GROUP_URL + groupId + "/Alerts/History/" + alert.getId());
+ StaticTextItem time = newTextItem(GwtRelativeDurationConverter.format(alert.getCtime()));
+ row.setItems(iconItem, link, time);
+
+ column.addMember(row);
+ }
+ //link to more details
+ LocatableDynamicForm row = new LocatableDynamicForm(recentAlertsContent.extendLocatorId(String
+ .valueOf(rowNum++)));
+ addSeeMoreLink(row, ReportDecorator.GWT_GROUP_URL + groupId + "/Alerts/History/", column);
+ } else {
+ LocatableDynamicForm row = createEmptyDisplayRow(recentAlertsContent.extendLocatorId("None"),
+ RECENT_ALERTS_NONE);
+ column.addMember(row);
+ }
+ for (Canvas child : recentAlertsContent.getChildren()) {
+ child.destroy();
+ }
+ recentAlertsContent.addChild(column);
+ recentAlertsContent.markForRedraw();
+ }
+
+ @Override
+ public void onFailure(Throwable caught) {
+ Log.debug("Error retrieving recent alerts for group [" + groupId + "]:" + caught.getMessage());
+ }
+ });
+ }
+
+ /** Fetches operations and updates the DynamicForm instance with the latest
+ * operation information.
+ */
+ private void getRecentOperations() {
+ final int groupId = this.groupComposite.getResourceGroup().getId();
+ //fetches five most recent operations.
+ PageControl pageControl = new PageControl(0, 5);
+
+ GroupOperationHistoryCriteria criteria = new GroupOperationHistoryCriteria();
+ List<Integer> filterResourceGroupIds = new ArrayList<Integer>();
+ filterResourceGroupIds.add(groupId);
+ criteria.addFilterResourceGroupIds(filterResourceGroupIds);
+ criteria.setPageControl(pageControl);
+ criteria.addSortStatus(PageOrdering.DESC);
+
+ GWTServiceLookup.getOperationService().findGroupOperationHistoriesByCriteria(criteria,
+ new AsyncCallback<PageList<GroupOperationHistory>>() {
+
+ @Override
+ public void onFailure(Throwable caught) {
+ Log.debug("Error retrieving recent operations for group [" + groupId + "]:" + caught.getMessage());
+ }
+
+ @Override
+ public void onSuccess(PageList<GroupOperationHistory> result) {
+ VLayout column = new VLayout();
+ column.setHeight(10);
+ if (!result.isEmpty()) {
+ int rowNum = 0;
+ for (GroupOperationHistory report : result) {
+ // operation history records do not have a usable locatorId, we'll use rownum, which is unique and
+ // may be repeatable.
+ LocatableDynamicForm row = new LocatableDynamicForm(recentOperationsContent
+ .extendLocatorId(String.valueOf(rowNum)));
+ row.setNumCols(3);
+
+ StaticTextItem iconItem = newTextItemIcon(ImageManager.getOperationResultsIcon(report
+ .getStatus()), report.getStatus().getDisplayName());
+ LinkItem link = newLinkItem(report.getOperationDefinition().getDisplayName() + ": ",
+ ReportDecorator.GWT_GROUP_URL + groupId + "/Operations/History/" + report.getId());
+ StaticTextItem time = newTextItem(GwtRelativeDurationConverter.format(report
+ .getStartedTime()));
+ row.setItems(iconItem, link, time);
+
+ column.addMember(row);
+ }
+ //insert see more link
+ LocatableDynamicForm row = new LocatableDynamicForm(recentOperationsContent
+ .extendLocatorId(String.valueOf(rowNum)));
+ addSeeMoreLink(row, ReportDecorator.GWT_GROUP_URL + groupId + "/Operations/History/", column);
+ } else {
+ LocatableDynamicForm row = createEmptyDisplayRow(recentOperationsContent
+ .extendLocatorId("None"), RECENT_OPERATIONS_NONE);
+ column.addMember(row);
+ }
+ for (Canvas child : recentOperationsContent.getChildren()) {
+ child.destroy();
+ }
+ recentOperationsContent.addChild(column);
+ recentOperationsContent.markForRedraw();
+ }
+ });
+ }
+
+ /** Fetches configuration updates and updates the DynamicForm instance with the latest
+ * config change information.
+ */
+ private void getRecentConfigurationUpdates() {
+ final int groupId = this.groupComposite.getResourceGroup().getId();
+
+ PageControl lastFive = new PageControl(0, 5);
+ GroupResourceConfigurationUpdateCriteria criteria = new GroupResourceConfigurationUpdateCriteria();
+ criteria.setPageControl(lastFive);
+ criteria.addSortStatus(PageOrdering.DESC);
+ List<Integer> filterResourceGroupIds = new ArrayList<Integer>();
+ filterResourceGroupIds.add(groupId);
+ criteria.addFilterResourceGroupIds(filterResourceGroupIds);
+
+ GWTServiceLookup.getConfigurationService().findGroupResourceConfigurationUpdatesByCriteria(criteria,
+ new AsyncCallback<PageList<GroupResourceConfigurationUpdate>>() {
+
+ @Override
+ public void onFailure(Throwable caught) {
+ Log.debug("Error retrieving recent configuration updates for group [" + groupId + "]:"
+ + caught.getMessage());
+ }
+
+ @Override
+ public void onSuccess(PageList<GroupResourceConfigurationUpdate> result) {
+ VLayout column = new VLayout();
+ column.setHeight(10);
+ if (!result.isEmpty()) {
+ int rowNum = 0;
+ for (GroupResourceConfigurationUpdate update : result) {
+ // config update history records do not have a usable locatorId, we'll use rownum, which is unique and
+ // may be repeatable.
+ LocatableDynamicForm row = new LocatableDynamicForm(recentConfigurationContent
+ .extendLocatorId(String.valueOf(rowNum)));
+ row.setNumCols(3);
+
+ StaticTextItem iconItem = newTextItemIcon(ImageManager.getResourceConfigurationIcon(update
+ .getStatus()), null);
+ String linkTitle = MSG.view_resource_inventory_activity_changed_by() + " "
+ + update.getSubjectName() + ":";
+ if ((update.getSubjectName() == null) || (update.getSubjectName().trim().isEmpty())) {
+ linkTitle = MSG.common_msg_changeAutoDetected();
+ }
+ LinkItem link = newLinkItem(linkTitle, ReportDecorator.GWT_GROUP_URL + groupId
+ + "/Configuration/History/" + update.getId());
+ StaticTextItem time = newTextItem(GwtRelativeDurationConverter.format(update
+ .getCreatedTime()));
+
+ row.setItems(iconItem, link, time);
+ column.addMember(row);
+ }
+ //insert see more link
+ LocatableDynamicForm row = new LocatableDynamicForm(recentConfigurationContent
+ .extendLocatorId(String.valueOf(rowNum)));
+ addSeeMoreLink(row, ReportDecorator.GWT_GROUP_URL + groupId + "/Configuration/History/", column);
+ } else {
+ LocatableDynamicForm row = createEmptyDisplayRow(recentConfigurationContent
+ .extendLocatorId("None"), RECENT_CONFIGURATIONS_NONE);
+ column.addMember(row);
+ }
+ //cleanup
+ for (Canvas child : recentConfigurationContent.getChildren()) {
+ child.destroy();
+ }
+ recentConfigurationContent.addChild(column);
+ recentConfigurationContent.markForRedraw();
+
+ }
+ });
+ }
+
+ /** Fetches recent events and updates the DynamicForm instance with the latest
+ * event information over last 24hrs.
+ */
+ private void getRecentEventUpdates() {
+ final int groupId = this.groupComposite.getResourceGroup().getId();
+ long now = System.currentTimeMillis();
+ long nowMinus24Hours = now - (24 * 60 * 60 * 1000);
+ GWTServiceLookup.getEventService().getEventCountsBySeverityForGroup(groupId, nowMinus24Hours, now,
+ new AsyncCallback<Map<EventSeverity, Integer>>() {
+
+ @Override
+ public void onFailure(Throwable caught) {
+ Log
+ .debug("Error retrieving recent event counts for group [" + groupId + "]:"
+ + caught.getMessage());
+ }
+
+ @Override
+ public void onSuccess(Map<EventSeverity, Integer> eventCounts) {
+ //Now populated Tuples
+ List<GwtTuple<EventSeverity, Integer>> results = new ArrayList<GwtTuple<EventSeverity, Integer>>();
+ for (EventSeverity severity : eventCounts.keySet()) {
+ int count = eventCounts.get(severity);
+ if (count > 0) {
+ results.add(new GwtTuple<EventSeverity, Integer>(severity, count));
+ }
+ }
+ //build display
+ VLayout column = new VLayout();
+ column.setHeight(10);
+
+ if (!results.isEmpty()) {
+ int rowNum = 0;
+ for (GwtTuple<EventSeverity, Integer> tuple : results) {
+ // event history records do not have a usable locatorId, we'll use rownum, which is unique and
+ // may be repeatable.
+ LocatableDynamicForm row = new LocatableDynamicForm(recentEventsContent
+ .extendLocatorId(String.valueOf(rowNum)));
+ row.setNumCols(2);
+ row.setWidth(10);//pack.
+
+ //icon
+ StaticTextItem iconItem = newTextItemIcon(ImageManager.getEventSeverityIcon(tuple
+ .getLefty()), tuple.getLefty().name());
+ //count
+ StaticTextItem count = newTextItem(String.valueOf(tuple.righty));
+ row.setItems(iconItem, count);
+
+ column.addMember(row);
+ }
+ //insert see more link
+ LocatableDynamicForm row = new LocatableDynamicForm(recentEventsContent.extendLocatorId(String
+ .valueOf(rowNum)));
+ addSeeMoreLink(row, ReportDecorator.GWT_GROUP_URL + groupId + "/Events/History/", column);
+ } else {
+ LocatableDynamicForm row = createEmptyDisplayRow(recentEventsContent.extendLocatorId("None"),
+ RECENT_EVENTS_NONE);
+ column.addMember(row);
+ }
+ //cleanup
+ for (Canvas child : recentEventsContent.getChildren()) {
+ child.destroy();
+ }
+ recentEventsContent.addChild(column);
+ recentEventsContent.markForRedraw();
+ }
+ });
+ }
+
+ /** Fetches OOB measurements and updates the DynamicForm instance with the latest 5
+ * oob change details.
+ */
+ private void getRecentOobs() {
+ final int groupId = this.groupComposite.getResourceGroup().getId();
+
+ GWTServiceLookup.getMeasurementDataService().getHighestNOOBsForGroup(groupId, 5,
+ new AsyncCallback<PageList<MeasurementOOBComposite>>() {
+ @Override
+ public void onFailure(Throwable caught) {
+ Log.debug("Error retrieving recent out of bound metrics for group [" + groupId + "]:"
+ + caught.getMessage());
+ }
+
+ @Override
+ public void onSuccess(PageList<MeasurementOOBComposite> result) {
+ VLayout column = new VLayout();
+ column.setHeight(10);
+ if (!result.isEmpty()) {
+ for (MeasurementOOBComposite oob : result) {
+ LocatableDynamicForm row = new LocatableDynamicForm(recentOobContent.extendLocatorId(oob
+ .getScheduleName()));
+ row.setNumCols(2);
+
+ String title = oob.getScheduleName() + ":";
+ String destination = "/resource/common/monitor/Visibility.do?m=" + oob.getDefinitionId()
+ + "&id=" + groupId + "&mode=chartSingleMetricSingleResource";
+ LinkItem link = newLinkItem(title, destination);
+ StaticTextItem time = newTextItem(GwtRelativeDurationConverter.format(oob.getTimestamp()));
+
+ row.setItems(link, time);
+ column.addMember(row);
+ }
+ //insert see more link spinder(2/24/11): no page that displays all oobs... See More not possible.
+ } else {
+ LocatableDynamicForm row = createEmptyDisplayRow(recentOobContent.extendLocatorId("None"),
+ RECENT_OOB_NONE);
+ column.addMember(row);
+ }
+ recentOobContent.setContents("");
+ for (Canvas child : recentOobContent.getChildren()) {
+ child.destroy();
+ }
+ recentOobContent.addChild(column);
+ recentOobContent.markForRedraw();
+ }
+ });
+ }
+
+ /** Fetches recent package history information and updates the DynamicForm instance with details.
+ */
+ private void getRecentPkgHistory() {
+ final int groupId = this.groupComposite.getResourceGroup().getId();
+ InstalledPackageHistoryCriteria criteria = new InstalledPackageHistoryCriteria();
+ PageControl pageControl = new PageControl(0, 5);
+ criteria.setPageControl(pageControl);
+ criteria.addFilterResourceGroupIds(groupId);
+ criteria.addSortStatus(PageOrdering.DESC);
+
+ GWTServiceLookup.getContentService().findInstalledPackageHistoryByCriteria(criteria,
+
+ new AsyncCallback<PageList<InstalledPackageHistory>>() {
+ @Override
+ public void onFailure(Throwable caught) {
+ Log.debug("Error retrieving installed package history for group [" + groupId + "]:"
+ + caught.getMessage());
+ }
+
+ @Override
+ public void onSuccess(PageList<InstalledPackageHistory> result) {
+ VLayout column = new VLayout();
+ column.setHeight(10);
+ if (!result.isEmpty()) {
+ for (InstalledPackageHistory history : result) {
+ LocatableDynamicForm row = new LocatableDynamicForm(recentPkgHistoryContent
+ .extendLocatorId(history.getPackageVersion().getFileName()
+ + history.getPackageVersion().getVersion()));
+ row.setNumCols(3);
+
+ StaticTextItem iconItem = newTextItemIcon("subsystems/content/Package_16.png", null);
+ String title = history.getPackageVersion().getFileName() + ":";
+ String destination = "/rhq/resource/content/audit-trail-item.xhtml?id=" + groupId
+ + "&selectedHistoryId=" + history.getId();
+ LinkItem link = newLinkItem(title, destination);
+ StaticTextItem time = newTextItem(GwtRelativeDurationConverter.format(history.getTimestamp()));
+
+ row.setItems(iconItem, link, time);
+ column.addMember(row);
+ }
+ // //insert see more link
+ // LocatableDynamicForm row = new LocatableDynamicForm(recentPkgHistoryContent
+ // .extendLocatorId("PkgHistoryContentSeeMore"));
+ // String destination = "/rhq/resource/content/audit-trail-item.xhtml?id=" + groupId;
+ // addSeeMoreLink(row, destination, column);
+ } else {
+ LocatableDynamicForm row = createEmptyDisplayRow(recentPkgHistoryContent.extendLocatorId("None"),
+ RECENT_PKG_HISTORY_NONE);
+ column.addMember(row);
+ }
+ //cleanup
+ for (Canvas child : recentPkgHistoryContent.getChildren()) {
+ child.destroy();
+ }
+ recentPkgHistoryContent.addChild(column);
+ recentPkgHistoryContent.markForRedraw();
+ }
+ });
+ }
+
+ /** Fetches recent metric information and updates the DynamicForm instance with i)sparkline information,
+ * ii) link to recent metric graph for more details and iii) last metric value formatted to show significant
+ * digits.
+ */
+ private void getRecentMetrics() {
+
+ //display container
+ final VLayout column = new VLayout();
+ column.setHeight(10);//pack
+ final int groupId = this.groupComposite.getResourceGroup().getId();
+
+ //retrieve all relevant measurement definition ids.
+ Set<MeasurementDefinition> definitions = this.groupComposite.getResourceGroup().getResourceType()
+ .getMetricDefinitions();
+
+ //build id mapping for measurementDefinition instances Ex. Free Memory -> MeasurementDefinition[100071]
+ final HashMap<String, MeasurementDefinition> measurementDefMap = new HashMap<String, MeasurementDefinition>();
+ for (MeasurementDefinition definition : definitions) {
+ measurementDefMap.put(definition.getDisplayName(), definition);
+ }
+ //bundle definition ids for asynch call.
+ int[] definitionArrayIds = new int[definitions.size()];
+ final String[] displayOrder = new String[definitions.size()];
+ measurementDefMap.keySet().toArray(displayOrder);
+ //sort the charting data ex. Free Memory, Free Swap Space,..System Load
+ Arrays.sort(displayOrder);
+
+ //organize definitionArrayIds for ordered request on server.
+ int index = 0;
+ for (String definitionToDisplay : displayOrder) {
+ definitionArrayIds[index++] = measurementDefMap.get(definitionToDisplay).getId();
+ }
+
+ //make the asynchronous call for all the measurement data
+ GWTServiceLookup.getMeasurementDataService().findDataForCompatibleGroup(groupId, definitionArrayIds,
+ System.currentTimeMillis() - (1000L * 60 * 60 * 8), System.currentTimeMillis(), 60,
+ new AsyncCallback<List<List<MeasurementDataNumericHighLowComposite>>>() {
+ @Override
+ public void onFailure(Throwable caught) {
+ Log.debug("Error retrieving recent metrics charting data for group [" + groupId + "]:"
+ + caught.getMessage());
+ }
+
+ @Override
+ public void onSuccess(List<List<MeasurementDataNumericHighLowComposite>> results) {
+ if (!results.isEmpty()) {
+ boolean someChartedData = false;
+ //iterate over the retrieved charting data
+ for (int index = 0; index < displayOrder.length; index++) {
+ //retrieve the correct measurement definition
+ MeasurementDefinition md = measurementDefMap.get(displayOrder[index]);
+
+ //load the data results for the given metric definition
+ List<MeasurementDataNumericHighLowComposite> data = results.get(index);
+
+ //locate last and minimum values.
+ double lastValue = -1;
+ double minValue = Double.MAX_VALUE;//
+ for (MeasurementDataNumericHighLowComposite d : data) {
+ if ((!Double.isNaN(d.getValue()))
+ && (String.valueOf(d.getValue()).indexOf("NaN") == -1)) {
+ if (d.getValue() < minValue) {
+ minValue = d.getValue();
+ }
+ lastValue = d.getValue();
+ }
+ }
+
+ //collapse the data into comma delimited list for consumption by third party javascript library(jquery.sparkline)
+ String commaDelimitedList = "";
+
+ for (MeasurementDataNumericHighLowComposite d : data) {
+ if ((!Double.isNaN(d.getValue()))
+ && (String.valueOf(d.getValue()).indexOf("NaN") == -1)) {
+ commaDelimitedList += d.getValue() + ",";
+ }
+ }
+ LocatableDynamicForm row = new LocatableDynamicForm(recentMeasurementsContent
+ .extendLocatorId(md.getName()));
+ row.setNumCols(3);
+ HTMLFlow graph = new HTMLFlow();
+ // String contents = "<span id='sparkline_" + index + "' class='dynamicsparkline' width='0'>"
+ // + commaDelimitedList + "</span>";
+ String contents = "<span id='sparkline_" + index + "' class='dynamicsparkline' width='0' "
+ + "values='" + commaDelimitedList + "'>...</span>";
+ graph.setContents(contents);
+ graph.setContentsType(ContentsType.PAGE);
+ //diable scrollbars on span
+ graph.setScrollbarSize(0);
+
+ CanvasItem graphContainer = new CanvasItem();
+ graphContainer.setShowTitle(false);
+ graphContainer.setHeight(16);
+ graphContainer.setWidth(60);
+ graphContainer.setCanvas(graph);
+
+ //Link/title element
+ //TODO: spinder, change link whenever portal.war/graphing is removed.
+ String title = md.getDisplayName() + ":";
+ // String destination = "/resource/common/monitor/Visibility.do?mode=chartSingleMetricSingleResource&id="
+ // + resourceId + "&m=" + md.getId();
+ String destination = "/resource/common/monitor/Visibility.do?mode=chartSingleMetricMultiResource&groupId="
+ + groupId + "&m=" + md.getId();
+ LinkItem link = newLinkItem(title, destination);
+
+ //Value
+ String convertedValue = lastValue + " " + md.getUnits();
+ convertedValue = convertLastValueForDisplay(lastValue, md);
+ StaticTextItem value = newTextItem(convertedValue);
+
+ row.setItems(graphContainer, link, value);
+ //if graph content returned
+ if ((md.getName().trim().indexOf("Trait.") == -1) && (lastValue != -1)) {
+ column.addMember(row);
+ someChartedData = true;
+ }
+ }
+ if (!someChartedData) {// when there are results but no chartable entries.
+ LocatableDynamicForm row = createEmptyDisplayRow(recentMeasurementsContent
+ .extendLocatorId("None"), RECENT_MEASUREMENTS_NONE);
+ column.addMember(row);
+ } else {
+ //insert see more link
+ LocatableDynamicForm row = new LocatableDynamicForm(recentMeasurementsContent
+ .extendLocatorId("RecentMeasurementsContentSeeMore"));
+ addSeeMoreLink(row, ReportDecorator.GWT_GROUP_URL + groupId + "/Monitoring/Graphs/", column);
+ }
+ //call out to 3rd party javascript lib
+ BrowserUtility.graphSparkLines();
+ } else {
+ LocatableDynamicForm row = createEmptyDisplayRow(recentMeasurementsContent
+ .extendLocatorId("None"), RECENT_MEASUREMENTS_NONE);
+ column.addMember(row);
+ }
+ }
+ });
+
+ //cleanup
+ for (Canvas child : recentMeasurementsContent.getChildren()) {
+ child.destroy();
+ }
+ recentMeasurementsContent.addChild(column);
+ recentMeasurementsContent.markForRedraw();
+ }
+
+ /** Fetches recent bundle deployment information and updates the DynamicForm instance with details.
+ */
+ protected void getRecentBundleDeployments() {
+ final int groupId = this.groupComposite.getResourceGroup().getId();
+ GroupBundleDeploymentCriteria criteria = new GroupBundleDeploymentCriteria();
+ PageControl pageControl = new PageControl(0, 5);
+ criteria.setPageControl(pageControl);
+ criteria.addFilterResourceGroupIds(groupId);
+ criteria.addSortStatus(PageOrdering.DESC);
+ criteria.fetchDestination(true);
+ criteria.fetchBundleVersion(true);
+
+ GWTServiceLookup.getBundleService().findBundleDeploymentsByCriteria(criteria,
+ new AsyncCallback<PageList<BundleDeployment>>() {
+ @Override
+ public void onFailure(Throwable caught) {
+ Log.debug("Error retrieving installed bundle deployments for group [" + groupId + "]:"
+ + caught.getMessage());
+ }
+
+ @Override
+ public void onSuccess(PageList<BundleDeployment> result) {
+ VLayout column = new VLayout();
+ column.setHeight(10);
+ if (!result.isEmpty()) {
+ for (BundleDeployment deployment : result) {
+ LocatableDynamicForm row = new LocatableDynamicForm(recentBundleDeployContent
+ .extendLocatorId(deployment.getBundleVersion().getName()
+ + deployment.getBundleVersion().getVersion()));
+ row.setNumCols(3);
+
+ StaticTextItem iconItem = newTextItemIcon("subsystems/content/Content_16.png", null);
+ String title = deployment.getBundleVersion().getName() + "["
+ + deployment.getBundleVersion().getVersion() + "]:";
+ String destination = ReportDecorator.GWT_BUNDLE_URL
+ + deployment.getBundleVersion().getBundle().getId() + "/destinations/"
+ + deployment.getDestination().getId();
+ LinkItem link = newLinkItem(title, destination);
+ StaticTextItem time = newTextItem(GwtRelativeDurationConverter
+ .format(deployment.getCtime()));
+
+ row.setItems(iconItem, link, time);
+ column.addMember(row);
+ }
+ //insert see more link
+ //TODO: spinder:2/25/11 (add this later) no current view for seeing all bundle deployments
+ // LocatableDynamicForm row = new LocatableDynamicForm(recentBundleDeployContent.extendLocatorId("RecentBundleContentSeeMore"));
+ // addSeeMoreLink(row, LinkManager.getResourceGroupLink(groupId) + "/Events/History/", column);
+ } else {
+ LocatableDynamicForm row = createEmptyDisplayRow(recentBundleDeployContent
+ .extendLocatorId("None"), RECENT_BUNDLE_DEPLOY_NONE);
+ column.addMember(row);
+ }
+ //cleanup
+ for (Canvas child : recentBundleDeployContent.getChildren()) {
+ child.destroy();
+ }
+ recentBundleDeployContent.addChild(column);
+ recentBundleDeployContent.markForRedraw();
+ }
+ });
+ }
+}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/ResourceDetailView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/ResourceDetailView.java
index aec77ac..38e09eb 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/ResourceDetailView.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/ResourceDetailView.java
@@ -67,8 +67,8 @@ import org.rhq.enterprise.gui.coregui.client.inventory.resource.detail.monitorin
import org.rhq.enterprise.gui.coregui.client.inventory.resource.detail.monitoring.traits.TraitsView;
import org.rhq.enterprise.gui.coregui.client.inventory.resource.detail.operation.history.ResourceOperationHistoryListView;
import org.rhq.enterprise.gui.coregui.client.inventory.resource.detail.operation.schedule.ResourceOperationScheduleListView;
-import org.rhq.enterprise.gui.coregui.client.inventory.resource.detail.summary.Activity2View;
import org.rhq.enterprise.gui.coregui.client.inventory.resource.detail.summary.ActivityView;
+import org.rhq.enterprise.gui.coregui.client.inventory.resource.detail.summary.ActivityView3;
import org.rhq.enterprise.gui.coregui.client.inventory.resource.type.ResourceTypeRepository;
import org.rhq.enterprise.gui.coregui.client.util.message.Message;
@@ -287,7 +287,7 @@ public class ResourceDetailView extends AbstractTwoLevelTabSetView<ResourceCompo
updateSubTab(this.summaryTab, this.summaryActivity2, true, true, new ViewFactory() {
@Override
public Canvas createView() {
- return new Activity2View(summaryActivity2.extendLocatorId("View"), resourceComposite);
+ return new ActivityView3(summaryActivity2.extendLocatorId("View"), resourceComposite);
}
});
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/Activity2View.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/Activity2View.java
deleted file mode 100644
index ad6e607..0000000
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/Activity2View.java
+++ /dev/null
@@ -1,243 +0,0 @@
-package org.rhq.enterprise.gui.coregui.client.inventory.resource.detail.summary;
-
-import java.util.HashMap;
-import java.util.Set;
-
-import com.google.gwt.user.client.rpc.AsyncCallback;
-import com.smartgwt.client.util.BooleanCallback;
-import com.smartgwt.client.util.SC;
-import com.smartgwt.client.widgets.Canvas;
-import com.smartgwt.client.widgets.IButton;
-import com.smartgwt.client.widgets.events.ClickEvent;
-import com.smartgwt.client.widgets.events.ClickHandler;
-
-import org.rhq.core.domain.auth.Subject;
-import org.rhq.core.domain.authz.Permission;
-import org.rhq.core.domain.configuration.PropertySimple;
-import org.rhq.core.domain.criteria.DashboardCriteria;
-import org.rhq.core.domain.dashboard.Dashboard;
-import org.rhq.core.domain.dashboard.DashboardCategory;
-import org.rhq.core.domain.dashboard.DashboardPortlet;
-import org.rhq.core.domain.resource.Resource;
-import org.rhq.core.domain.resource.composite.ResourceComposite;
-import org.rhq.core.domain.util.PageList;
-import org.rhq.enterprise.gui.coregui.client.CoreGUI;
-import org.rhq.enterprise.gui.coregui.client.InitializableView;
-import org.rhq.enterprise.gui.coregui.client.PermissionsLoadedListener;
-import org.rhq.enterprise.gui.coregui.client.PermissionsLoader;
-import org.rhq.enterprise.gui.coregui.client.UserSessionManager;
-import org.rhq.enterprise.gui.coregui.client.dashboard.DashboardContainer;
-import org.rhq.enterprise.gui.coregui.client.dashboard.DashboardView;
-import org.rhq.enterprise.gui.coregui.client.dashboard.PortletFactory;
-import org.rhq.enterprise.gui.coregui.client.dashboard.portlets.resource.ResourceAlertsPortlet;
-import org.rhq.enterprise.gui.coregui.client.dashboard.portlets.resource.ResourceMetricsPortlet;
-import org.rhq.enterprise.gui.coregui.client.dashboard.portlets.resource.ResourceOperationsPortlet;
-import org.rhq.enterprise.gui.coregui.client.gwt.DashboardGWTServiceAsync;
-import org.rhq.enterprise.gui.coregui.client.gwt.GWTServiceLookup;
-import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableIButton;
-import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableToolStrip;
-import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableVLayout;
-
-/**
- * The content pane for the resource Summary>Dashboard subtab.
- *
- * @author Jay Shaughnessy
- */
-
-public class Activity2View extends LocatableVLayout implements DashboardContainer, InitializableView {
-
- private static final String DASHBOARD_NAME_PREFIX = "ResourceDashboard_";
-
- private ResourceComposite resourceComposite;
-
- private DashboardGWTServiceAsync dashboardService = GWTServiceLookup.getDashboardService();
-
- private DashboardView dashboardView;
-
- private LocatableToolStrip footer;
- private IButton editButton;
- private IButton resetButton;
-
- // Capture the user's global permissions for use by any dashboard or portlet that may need it for rendering.
- private Set<Permission> globalPermissions;
-
- private boolean editMode = false;
-
- private boolean isInitialized = false;
-
- public Activity2View(String locatorId, ResourceComposite resourceComposite) {
- super(locatorId);
- this.resourceComposite = resourceComposite;
- }
-
- @Override
- protected void onInit() {
- if (!isInitialized()) {
- super.onInit();
-
- // first async call to get global permissions
- new PermissionsLoader().loadExplicitGlobalPermissions(new PermissionsLoadedListener() {
-
- public void onPermissionsLoaded(Set<Permission> permissions) {
- globalPermissions = permissions;
-
- // now make async call to look for customized dash for this user and entity
- DashboardCriteria criteria = new DashboardCriteria();
- criteria.addFilterCategory(DashboardCategory.RESOURCE);
- criteria.addFilterResourceId(resourceComposite.getResource().getId());
- dashboardService.findDashboardsByCriteria(criteria, new AsyncCallback<PageList<Dashboard>>() {
- public void onFailure(Throwable caught) {
- CoreGUI.getErrorHandler().handleError(MSG.view_dashboardsManager_error1(), caught);
- }
-
- public void onSuccess(final PageList<Dashboard> result) {
- Dashboard dashboard = result.isEmpty() ? getDefaultDashboard() : result.get(0);
- setDashboard(dashboard);
-
- isInitialized = true;
-
- // draw() may be done since onInit finishes asynchronously, if so redraw
- if (isDrawn()) {
- markForRedraw();
- }
- }
- });
- }
- });
- }
- }
-
- private void setDashboard(Dashboard dashboard) {
- Canvas[] members = getMembers();
- removeMembers(members);
- //pass in the resource information
- dashboardView = new DashboardView(extendLocatorId(dashboard.getName()), this, dashboard, null,
- resourceComposite);
- addMember(dashboardView);
-
- footer = new LocatableToolStrip(extendLocatorId("Footer"));
- footer.setPadding(5);
- footer.setWidth100();
- footer.setMembersMargin(15);
-
- editButton = new LocatableIButton(footer.extendLocatorId("Mode"), editMode ? MSG.common_title_view_mode() : MSG
- .common_title_edit_mode());
- editButton.setAutoFit(true);
- editButton.addClickHandler(new ClickHandler() {
- public void onClick(ClickEvent clickEvent) {
- editMode = !editMode;
- editButton.setTitle(editMode ? MSG.common_title_view_mode() : MSG.common_title_edit_mode());
- dashboardView.setEditMode(editMode);
- }
- });
-
- resetButton = new LocatableIButton(footer.extendLocatorId("Reset"), MSG.common_button_reset());
- resetButton.setAutoFit(true);
- resetButton.addClickHandler(new ClickHandler() {
- public void onClick(ClickEvent clickEvent) {
- String message = MSG.view_summaryDashboard_resetConfirm();
-
- SC.ask(message, new BooleanCallback() {
- public void execute(Boolean confirmed) {
- if (confirmed) {
- dashboardView.delete();
- setDashboard(getDefaultDashboard());
- markForRedraw();
- }
- }
- });
- }
- });
-
- footer.addMember(editButton);
- footer.addMember(resetButton);
-
- addMember(footer);
- }
-
- protected Dashboard getDefaultDashboard() {
- Subject sessionSubject = UserSessionManager.getSessionSubject();
- Resource resource = resourceComposite.getResource();
-
- Dashboard dashboard = new Dashboard();
-
- dashboard.setName(DASHBOARD_NAME_PREFIX + sessionSubject.getId() + "_" + resource.getId());
- dashboard.setCategory(DashboardCategory.RESOURCE);
- dashboard.setResource(resource);
- dashboard.setColumns(2);
-
- // TODO, add real portlets
- // set leftmost column and let the rest be equally divided
- dashboard.setColumnWidths("40%");
- dashboard.getConfiguration().put(new PropertySimple(Dashboard.CFG_BACKGROUND, "#F1F2F3"));
-
- //figure out which portlets to display and how
- HashMap<String, String> resKeyNameMap = PortletFactory.getRegisteredResourcePortletNameMap();
- resKeyNameMap = DashboardView.processPortletNameMapForResource(resKeyNameMap, resourceComposite);
- int colLeft = 0;
- int colRight = 1;
- int rowLeft = 0;
- int rowRight = 0;
- //Left Column
- if (resKeyNameMap.containsKey(ResourceMetricsPortlet.KEY)) {//measurments top left if available
- DashboardPortlet measurements = new DashboardPortlet(ResourceMetricsPortlet.NAME,
- ResourceMetricsPortlet.KEY, 220);
- dashboard.addPortlet(measurements, colLeft, rowLeft++);
- resKeyNameMap.remove(ResourceMetricsPortlet.KEY);
- }
-
- // right Column(approx 60%. As larger more room to display table and N rows.)
- if (resKeyNameMap.containsKey(ResourceAlertsPortlet.KEY)) {//alerts top right if available
- DashboardPortlet alerts = new DashboardPortlet(ResourceAlertsPortlet.NAME, ResourceAlertsPortlet.KEY, 220);
- dashboard.addPortlet(alerts, colRight, rowRight++);
- resKeyNameMap.remove(ResourceAlertsPortlet.KEY);
- }
- if (resKeyNameMap.containsKey(ResourceOperationsPortlet.KEY)) {//operations if available
- DashboardPortlet ops = new DashboardPortlet(ResourceOperationsPortlet.NAME, ResourceOperationsPortlet.KEY,
- 220);
- dashboard.addPortlet(ops, colRight, rowRight++);
- resKeyNameMap.remove(ResourceOperationsPortlet.KEY);
- }
-
- //Fill out left column(typically smaller portlets) then alternate cols with remaining
- boolean displayLeft = false;
- for (String key : resKeyNameMap.keySet()) {
- DashboardPortlet portlet = new DashboardPortlet(resKeyNameMap.get(key), key, 100);
- if (rowLeft < 4) {
- dashboard.addPortlet(portlet, colLeft, rowLeft++);
- } else {//alternate
- if (!displayLeft) {
- dashboard.addPortlet(portlet, colRight, rowRight++);
- } else {
- dashboard.addPortlet(portlet, colLeft, rowLeft++);
- }
- //toggle
- displayLeft = !displayLeft;
- }
- }
-
- return dashboard;
- }
-
- @Override
- public boolean isInitialized() {
- return isInitialized;
- }
-
- public Set<Permission> getGlobalPermissions() {
- return globalPermissions;
- }
-
- /**
- * name update not supported because the name is derived from the entity id.
- * @return
- */
- public boolean supportsDashboardNameEdit() {
- return false;
- }
-
- public void updateDashboardNames() {
- return;
- }
-
-}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/ActivityView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/ActivityView.java
index 1ef75de..ee64837 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/ActivityView.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/ActivityView.java
@@ -1,691 +1,243 @@
-/*
- * RHQ Management Platform
- * Copyright (C) 2005-2010 Red Hat, Inc.
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
package org.rhq.enterprise.gui.coregui.client.inventory.resource.detail.summary;
-import java.util.ArrayList;
-import java.util.Arrays;
import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
import java.util.Set;
-import com.allen_sauer.gwt.log.client.Log;
import com.google.gwt.user.client.rpc.AsyncCallback;
-import com.smartgwt.client.types.ContentsType;
+import com.smartgwt.client.util.BooleanCallback;
+import com.smartgwt.client.util.SC;
import com.smartgwt.client.widgets.Canvas;
-import com.smartgwt.client.widgets.HTMLFlow;
-import com.smartgwt.client.widgets.form.fields.CanvasItem;
-import com.smartgwt.client.widgets.form.fields.LinkItem;
-import com.smartgwt.client.widgets.form.fields.StaticTextItem;
-import com.smartgwt.client.widgets.layout.VLayout;
-
-import org.rhq.core.domain.alert.Alert;
-import org.rhq.core.domain.bundle.BundleDeployment;
-import org.rhq.core.domain.configuration.ResourceConfigurationUpdate;
-import org.rhq.core.domain.content.InstalledPackageHistory;
-import org.rhq.core.domain.criteria.AlertCriteria;
-import org.rhq.core.domain.criteria.InstalledPackageCriteria;
-import org.rhq.core.domain.criteria.ResourceBundleDeploymentCriteria;
-import org.rhq.core.domain.event.EventSeverity;
-import org.rhq.core.domain.measurement.MeasurementDefinition;
-import org.rhq.core.domain.measurement.composite.MeasurementDataNumericHighLowComposite;
-import org.rhq.core.domain.measurement.composite.MeasurementOOBComposite;
-import org.rhq.core.domain.operation.composite.ResourceOperationLastCompletedComposite;
+import com.smartgwt.client.widgets.IButton;
+import com.smartgwt.client.widgets.events.ClickEvent;
+import com.smartgwt.client.widgets.events.ClickHandler;
+
+import org.rhq.core.domain.auth.Subject;
+import org.rhq.core.domain.authz.Permission;
+import org.rhq.core.domain.configuration.PropertySimple;
+import org.rhq.core.domain.criteria.DashboardCriteria;
+import org.rhq.core.domain.dashboard.Dashboard;
+import org.rhq.core.domain.dashboard.DashboardCategory;
+import org.rhq.core.domain.dashboard.DashboardPortlet;
import org.rhq.core.domain.resource.Resource;
-import org.rhq.core.domain.resource.ResourceType;
-import org.rhq.core.domain.resource.ResourceTypeFacet;
import org.rhq.core.domain.resource.composite.ResourceComposite;
-import org.rhq.core.domain.util.PageControl;
import org.rhq.core.domain.util.PageList;
-import org.rhq.core.domain.util.PageOrdering;
-import org.rhq.enterprise.gui.coregui.client.ImageManager;
-import org.rhq.enterprise.gui.coregui.client.LinkManager;
+import org.rhq.enterprise.gui.coregui.client.CoreGUI;
+import org.rhq.enterprise.gui.coregui.client.InitializableView;
+import org.rhq.enterprise.gui.coregui.client.PermissionsLoadedListener;
+import org.rhq.enterprise.gui.coregui.client.PermissionsLoader;
+import org.rhq.enterprise.gui.coregui.client.UserSessionManager;
+import org.rhq.enterprise.gui.coregui.client.dashboard.DashboardContainer;
+import org.rhq.enterprise.gui.coregui.client.dashboard.DashboardView;
+import org.rhq.enterprise.gui.coregui.client.dashboard.PortletFactory;
+import org.rhq.enterprise.gui.coregui.client.dashboard.portlets.resource.ResourceAlertsPortlet;
+import org.rhq.enterprise.gui.coregui.client.dashboard.portlets.resource.ResourceMetricsPortlet;
+import org.rhq.enterprise.gui.coregui.client.dashboard.portlets.resource.ResourceOperationsPortlet;
+import org.rhq.enterprise.gui.coregui.client.gwt.DashboardGWTServiceAsync;
import org.rhq.enterprise.gui.coregui.client.gwt.GWTServiceLookup;
-import org.rhq.enterprise.gui.coregui.client.inventory.common.detail.summary.AbstractActivityView;
-import org.rhq.enterprise.gui.coregui.client.resource.disambiguation.ReportDecorator;
-import org.rhq.enterprise.gui.coregui.client.util.BrowserUtility;
-import org.rhq.enterprise.gui.coregui.client.util.GwtRelativeDurationConverter;
-import org.rhq.enterprise.gui.coregui.client.util.GwtTuple;
-import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableDynamicForm;
+import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableIButton;
+import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableToolStrip;
+import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableVLayout;
/**
- * The content pane of the Resource Summary>Activity tab.
+ * The content pane for the resource Summary>Dashboard subtab.
*
- * @author Simeon Pinder
+ * @author Jay Shaughnessy
*/
-public class ActivityView extends AbstractActivityView {
-
- private ResourceComposite resourceComposite;
-
- public ActivityView(String locatorId, ResourceComposite resourceComposite) {
- super(locatorId, null, resourceComposite);
- this.resourceComposite = resourceComposite;
- }
- @Override
- protected void onInit() {
- super.onInit();
- loadData();
- }
+public class ActivityView extends LocatableVLayout implements DashboardContainer, InitializableView {
- /**Initiates data request.
- */
- protected void loadData() {
-
- ResourceType type = null;
- Resource resource = null;
- Set<ResourceTypeFacet> facets = null;
-
- if ((resourceComposite != null) && (resourceComposite.getResource() != null)) {
- resource = resourceComposite.getResource();
- type = this.resourceComposite.getResource().getResourceType();
- facets = this.resourceComposite.getResourceFacets().getFacets();
-
- //alerts
- getRecentAlerts();
- //operations
- if (facets.contains(ResourceTypeFacet.OPERATION)) {
- getRecentOperations();
- }
- //config updates
- if (facets.contains(ResourceTypeFacet.CONFIGURATION)) {
- getRecentConfigurationUpdates();
- }
- //events
- if (facets.contains(ResourceTypeFacet.EVENT)) {
- getRecentEventUpdates();
- }
- //measurements
- getRecentOobs();
- getRecentPkgHistory();
- getRecentMetrics();
-
- //conditionally display Bundle Deployments region.
- if (displayBundlesForResource(resource)) {
- getRecentBundleDeployments();
- }
- }
- }
-
- /** Fetches alerts and updates the DynamicForm instance with the latest
- * alert information.
- */
- private void getRecentAlerts() {
- final int resourceId = this.resourceComposite.getResource().getId();
- //fetches last five alerts for this resource
- AlertCriteria criteria = new AlertCriteria();
- PageControl pageControl = new PageControl(0, 5);
- pageControl.initDefaultOrderingField("ctime", PageOrdering.DESC);
- criteria.setPageControl(pageControl);
- criteria.addFilterResourceIds(resourceId);
- GWTServiceLookup.getAlertService().findAlertsByCriteria(criteria, new AsyncCallback<PageList<Alert>>() {
- @Override
- public void onSuccess(PageList<Alert> result) {
- VLayout column = new VLayout();
- column.setHeight(10);
- if (!result.isEmpty()) {
- int rowNum = 0;
- for (Alert alert : result) {
- // alert history records do not have a usable locatorId, we'll use rownum, which is unique and
- // may be repeatable.
- LocatableDynamicForm row = new LocatableDynamicForm(recentAlertsContent.extendLocatorId(String
- .valueOf(rowNum++)));
- row.setNumCols(3);
- StaticTextItem iconItem = newTextItemIcon(ImageManager.getAlertIcon(alert.getAlertDefinition()
- .getPriority()), alert.getAlertDefinition().getPriority().getDisplayName());
- LinkItem link = newLinkItem(alert.getAlertDefinition().getName() + ": ",
- ReportDecorator.GWT_RESOURCE_URL + resourceId + "/Alerts/History/" + alert.getId());
- StaticTextItem time = newTextItem(GwtRelativeDurationConverter.format(alert.getCtime()));
- row.setItems(iconItem, link, time);
-
- column.addMember(row);
- }
- //link to more details
- LocatableDynamicForm row = new LocatableDynamicForm(recentAlertsContent.extendLocatorId(String
- .valueOf(rowNum++)));
- addSeeMoreLink(row, ReportDecorator.GWT_RESOURCE_URL + resourceId + "/Alerts/History/", column);
- } else {
- LocatableDynamicForm row = createEmptyDisplayRow(recentAlertsContent.extendLocatorId("None"),
- RECENT_ALERTS_NONE);
- column.addMember(row);
- }
- for (Canvas child : recentAlertsContent.getChildren()) {
- child.destroy();
- }
- recentAlertsContent.addChild(column);
- recentAlertsContent.markForRedraw();
- }
+ private static final String DASHBOARD_NAME_PREFIX = "ResourceDashboard_";
- @Override
- public void onFailure(Throwable caught) {
- Log.debug("Error retrieving recent alerts for resource [" + resourceId + "]:" + caught.getMessage());
- }
- });
- }
-
- /** Fetches operations and updates the DynamicForm instance with the latest
- * operation information.
- */
- private void getRecentOperations() {
- final int resourceId = this.resourceComposite.getResource().getId();
- //fetches five most recent operations.
- PageControl pageControl = new PageControl(0, 5);
- pageControl.initDefaultOrderingField("ro.createdTime", PageOrdering.DESC);
- GWTServiceLookup.getOperationService().findRecentCompletedOperations(resourceId, pageControl,
- new AsyncCallback<PageList<ResourceOperationLastCompletedComposite>>() {
-
- @Override
- public void onFailure(Throwable caught) {
- Log.debug("Error retrieving recent operations for resource [" + resourceId + "]:"
- + caught.getMessage());
- }
+ private ResourceComposite resourceComposite;
- @Override
- public void onSuccess(PageList<ResourceOperationLastCompletedComposite> result) {
- VLayout column = new VLayout();
- column.setHeight(10);
- if (!result.isEmpty()) {
- int rowNum = 0;
- for (ResourceOperationLastCompletedComposite report : result) {
- // operation history records do not have a usable locatorId, we'll use rownum, which is unique and
- // may be repeatable.
- LocatableDynamicForm row = new LocatableDynamicForm(recentOperationsContent
- .extendLocatorId(String.valueOf(rowNum)));
- row.setNumCols(3);
-
- StaticTextItem iconItem = newTextItemIcon(ImageManager.getOperationResultsIcon(report
- .getOperationStatus()), report.getOperationStatus().getDisplayName());
- LinkItem link = newLinkItem(report.getOperationName() + ": ", LinkManager
- .getResourceLink(resourceId)
- + "/Operations/History/" + report.getOperationHistoryId());
- StaticTextItem time = newTextItem(GwtRelativeDurationConverter.format(report
- .getOperationStartTime()));
- row.setItems(iconItem, link, time);
-
- column.addMember(row);
- }
- //link to more details
- LocatableDynamicForm row = new LocatableDynamicForm(recentOperationsContent
- .extendLocatorId(String.valueOf(rowNum++)));
- addSeeMoreLink(row, ReportDecorator.GWT_RESOURCE_URL + resourceId + "/Operations/History/",
- column);
- } else {
- LocatableDynamicForm row = createEmptyDisplayRow(recentOperationsContent
- .extendLocatorId("None"), RECENT_OPERATIONS_NONE);
- column.addMember(row);
- }
- for (Canvas child : recentOperationsContent.getChildren()) {
- child.destroy();
- }
- recentOperationsContent.addChild(column);
- recentOperationsContent.markForRedraw();
- }
- });
- }
+ private DashboardGWTServiceAsync dashboardService = GWTServiceLookup.getDashboardService();
- /** Fetches configuration updates and updates the DynamicForm instance with the latest
- * config change information.
- */
- private void getRecentConfigurationUpdates() {
- final int resourceId = this.resourceComposite.getResource().getId();
+ private DashboardView dashboardView;
- PageControl lastFive = new PageControl(0, 5);
- lastFive.initDefaultOrderingField("cu.createdTime", PageOrdering.DESC);
+ private LocatableToolStrip footer;
+ private IButton editButton;
+ private IButton resetButton;
- GWTServiceLookup.getConfigurationService().findResourceConfigurationUpdates(resourceId, null, null, true,
- lastFive, new AsyncCallback<PageList<ResourceConfigurationUpdate>>() {
+ // Capture the user's global permissions for use by any dashboard or portlet that may need it for rendering.
+ private Set<Permission> globalPermissions;
- @Override
- public void onFailure(Throwable caught) {
- Log.debug("Error retrieving recent configuration updates for resource [" + resourceId + "]:"
- + caught.getMessage());
- }
+ private boolean editMode = false;
- @Override
- public void onSuccess(PageList<ResourceConfigurationUpdate> result) {
- VLayout column = new VLayout();
- column.setHeight(10);
- if (!result.isEmpty()) {
- int rowNum = 0;
- for (ResourceConfigurationUpdate update : result) {
- // config update history records do not have a usable locatorId, we'll use rownum, which is unique and
- // may be repeatable.
- LocatableDynamicForm row = new LocatableDynamicForm(recentConfigurationContent
- .extendLocatorId(String.valueOf(rowNum)));
- row.setNumCols(3);
-
- StaticTextItem iconItem = newTextItemIcon(ImageManager.getResourceConfigurationIcon(update
- .getStatus()), null);
- String linkTitle = MSG.view_resource_inventory_activity_changed_by() + " "
- + update.getSubjectName() + ":";
- if ((update.getSubjectName() == null) || (update.getSubjectName().trim().isEmpty())) {
- linkTitle = MSG.common_msg_changeAutoDetected();
- }
- LinkItem link = newLinkItem(linkTitle, LinkManager.getResourceLink(resourceId)
- + "/Configuration/History/" + update.getId());
- StaticTextItem time = newTextItem(GwtRelativeDurationConverter.format(update
- .getCreatedTime()));
+ private boolean isInitialized = false;
- row.setItems(iconItem, link, time);
- column.addMember(row);
- }
- //link to more details
- LocatableDynamicForm row = new LocatableDynamicForm(recentConfigurationContent
- .extendLocatorId(String.valueOf(rowNum++)));
- addSeeMoreLink(row, ReportDecorator.GWT_RESOURCE_URL + resourceId + "/Configuration/History/",
- column);
- } else {
- LocatableDynamicForm row = createEmptyDisplayRow(recentConfigurationContent
- .extendLocatorId("None"), RECENT_CONFIGURATIONS_NONE);
- column.addMember(row);
- }
- //cleanup
- for (Canvas child : recentConfigurationContent.getChildren()) {
- child.destroy();
- }
- recentConfigurationContent.addChild(column);
- recentConfigurationContent.markForRedraw();
- }
- });
+ public ActivityView(String locatorId, ResourceComposite resourceComposite) {
+ super(locatorId);
+ this.resourceComposite = resourceComposite;
}
- /** Fetches recent events and updates the DynamicForm instance with the latest
- * event information over last 24hrs.
- */
- private void getRecentEventUpdates() {
-
- final int resourceId = this.resourceComposite.getResource().getId();
- long now = System.currentTimeMillis();
- long nowMinus24Hours = now - (24 * 60 * 60 * 1000);
+ @Override
+ protected void onInit() {
+ if (!isInitialized()) {
+ super.onInit();
+
+ // first async call to get global permissions
+ new PermissionsLoader().loadExplicitGlobalPermissions(new PermissionsLoadedListener() {
+
+ public void onPermissionsLoaded(Set<Permission> permissions) {
+ globalPermissions = permissions;
+
+ // now make async call to look for customized dash for this user and entity
+ DashboardCriteria criteria = new DashboardCriteria();
+ criteria.addFilterCategory(DashboardCategory.RESOURCE);
+ criteria.addFilterResourceId(resourceComposite.getResource().getId());
+ dashboardService.findDashboardsByCriteria(criteria, new AsyncCallback<PageList<Dashboard>>() {
+ public void onFailure(Throwable caught) {
+ CoreGUI.getErrorHandler().handleError(MSG.view_dashboardsManager_error1(), caught);
+ }
- GWTServiceLookup.getEventService().getEventCountsBySeverity(resourceId, nowMinus24Hours, now,
- new AsyncCallback<Map<EventSeverity, Integer>>() {
+ public void onSuccess(final PageList<Dashboard> result) {
+ Dashboard dashboard = result.isEmpty() ? getDefaultDashboard() : result.get(0);
+ setDashboard(dashboard);
- @Override
- public void onFailure(Throwable caught) {
- Log.debug("Error retrieving recent event counts for resource [" + resourceId + "]:"
- + caught.getMessage());
- }
+ isInitialized = true;
- @Override
- public void onSuccess(Map<EventSeverity, Integer> eventCounts) {
- //Now populated Tuples
- List<GwtTuple<EventSeverity, Integer>> results = new ArrayList<GwtTuple<EventSeverity, Integer>>();
- for (EventSeverity severity : eventCounts.keySet()) {
- int count = eventCounts.get(severity);
- if (count > 0) {
- results.add(new GwtTuple<EventSeverity, Integer>(severity, count));
- }
- }
- //build display
- VLayout column = new VLayout();
- column.setHeight(10);
-
- if (!results.isEmpty()) {
- int rowNum = 0;
- for (GwtTuple<EventSeverity, Integer> tuple : results) {
- // event history records do not have a usable locatorId, we'll use rownum, which is unique and
- // may be repeatable.
- LocatableDynamicForm row = new LocatableDynamicForm(recentEventsContent
- .extendLocatorId(String.valueOf(rowNum)));
- row.setNumCols(2);
- row.setWidth(10);//pack.
-
- //icon
- StaticTextItem iconItem = newTextItemIcon(ImageManager.getEventSeverityIcon(tuple
- .getLefty()), tuple.getLefty().name());
- //count
- StaticTextItem count = newTextItem(String.valueOf(tuple.righty));
- row.setItems(iconItem, count);
-
- column.addMember(row);
+ // draw() may be done since onInit finishes asynchronously, if so redraw
+ if (isDrawn()) {
+ markForRedraw();
+ }
}
- LocatableDynamicForm row = new LocatableDynamicForm(recentEventsContent.extendLocatorId(String
- .valueOf(rowNum++)));
- addSeeMoreLink(row, ReportDecorator.GWT_RESOURCE_URL + resourceId + "/Events/History/", column);
- } else {
- LocatableDynamicForm row = createEmptyDisplayRow(recentEventsContent.extendLocatorId("None"),
- RECENT_EVENTS_NONE);
- column.addMember(row);
- }
- //cleanup
- for (Canvas child : recentEventsContent.getChildren()) {
- child.destroy();
- }
- recentEventsContent.addChild(column);
- recentEventsContent.markForRedraw();
+ });
}
});
+ }
}
- /** Fetches OOB measurements and updates the DynamicForm instance with the latest 5
- * oob change details.
- */
- private void getRecentOobs() {
- final int resourceId = this.resourceComposite.getResource().getId();
- GWTServiceLookup.getMeasurementDataService().getHighestNOOBsForResource(resourceId, 5,
- new AsyncCallback<PageList<MeasurementOOBComposite>>() {
- @Override
- public void onFailure(Throwable caught) {
- Log.debug("Error retrieving recent out of bound metrics for resource [" + resourceId + "]:"
- + caught.getMessage());
- }
+ private void setDashboard(Dashboard dashboard) {
+ Canvas[] members = getMembers();
+ removeMembers(members);
+ //pass in the resource information
+ dashboardView = new DashboardView(extendLocatorId(dashboard.getName()), this, dashboard, null,
+ resourceComposite);
+ addMember(dashboardView);
+
+ footer = new LocatableToolStrip(extendLocatorId("Footer"));
+ footer.setPadding(5);
+ footer.setWidth100();
+ footer.setMembersMargin(15);
+
+ editButton = new LocatableIButton(footer.extendLocatorId("Mode"), editMode ? MSG.common_title_view_mode() : MSG
+ .common_title_edit_mode());
+ editButton.setAutoFit(true);
+ editButton.addClickHandler(new ClickHandler() {
+ public void onClick(ClickEvent clickEvent) {
+ editMode = !editMode;
+ editButton.setTitle(editMode ? MSG.common_title_view_mode() : MSG.common_title_edit_mode());
+ dashboardView.setEditMode(editMode);
+ }
+ });
- @Override
- public void onSuccess(PageList<MeasurementOOBComposite> result) {
- VLayout column = new VLayout();
- column.setHeight(10);
- if (!result.isEmpty()) {
- for (MeasurementOOBComposite oob : result) {
- LocatableDynamicForm row = new LocatableDynamicForm(recentOobContent.extendLocatorId(oob
- .getScheduleName()));
- row.setNumCols(2);
-
- String title = oob.getScheduleName() + ":";
- String destination = "/resource/common/monitor/Visibility.do?m=" + oob.getDefinitionId()
- + "&id=" + resourceId + "&mode=chartSingleMetricSingleResource";
- LinkItem link = newLinkItem(title, destination);
- StaticTextItem time = newTextItem(GwtRelativeDurationConverter.format(oob.getTimestamp()));
-
- row.setItems(link, time);
- column.addMember(row);
+ resetButton = new LocatableIButton(footer.extendLocatorId("Reset"), MSG.common_button_reset());
+ resetButton.setAutoFit(true);
+ resetButton.addClickHandler(new ClickHandler() {
+ public void onClick(ClickEvent clickEvent) {
+ String message = MSG.view_summaryDashboard_resetConfirm();
+
+ SC.ask(message, new BooleanCallback() {
+ public void execute(Boolean confirmed) {
+ if (confirmed) {
+ dashboardView.delete();
+ setDashboard(getDefaultDashboard());
+ markForRedraw();
}
- } else {
- LocatableDynamicForm row = createEmptyDisplayRow(recentOobContent.extendLocatorId("None"),
- RECENT_OOB_NONE);
- column.addMember(row);
- }
- recentOobContent.setContents("");
- for (Canvas child : recentOobContent.getChildren()) {
- child.destroy();
}
- recentOobContent.addChild(column);
- recentOobContent.markForRedraw();
- }
- });
- }
+ });
+ }
+ });
- /** Fetches recent package history information and updates the DynamicForm instance with details.
- */
- private void getRecentPkgHistory() {
- final int resourceId = this.resourceComposite.getResource().getId();
- InstalledPackageCriteria criteria = new InstalledPackageCriteria();
- criteria.addFilterResourceId(resourceId);
- PageControl pageControl = new PageControl(0, 5);
- criteria.setPageControl(pageControl);
-
- GWTServiceLookup.getContentService().getInstalledPackageHistoryForResource(resourceId, 5,
- new AsyncCallback<PageList<InstalledPackageHistory>>() {
- @Override
- public void onFailure(Throwable caught) {
- Log.debug("Error retrieving installed package history for resource [" + resourceId + "]:"
- + caught.getMessage());
- }
+ footer.addMember(editButton);
+ footer.addMember(resetButton);
- @Override
- public void onSuccess(PageList<InstalledPackageHistory> result) {
- VLayout column = new VLayout();
- column.setHeight(10);
- if (!result.isEmpty()) {
- for (InstalledPackageHistory history : result) {
- LocatableDynamicForm row = new LocatableDynamicForm(recentPkgHistoryContent
- .extendLocatorId(history.getPackageVersion().getFileName()
- + history.getPackageVersion().getVersion()));
- row.setNumCols(3);
-
- StaticTextItem iconItem = newTextItemIcon("subsystems/content/Package_16.png", null);
- String title = history.getPackageVersion().getFileName() + ":";
- String destination = "/rhq/resource/content/audit-trail-item.xhtml?id=" + resourceId
- + "&selectedHistoryId=" + history.getId();
- LinkItem link = newLinkItem(title, destination);
- StaticTextItem time = newTextItem(GwtRelativeDurationConverter.format(history
- .getTimestamp()));
-
- row.setItems(iconItem, link, time);
- column.addMember(row);
- }
- // //insert see more link
- // LocatableDynamicForm row = new LocatableDynamicForm(recentPkgHistoryContent
- // .extendLocatorId("RecentPkgHistorySeeMore"));
- // String destination = "/rhq/resource/content/audit-trail-item.xhtml?id=" + resourceId;
- // addSeeMoreLink(row, destination, column);
- } else {
- LocatableDynamicForm row = createEmptyDisplayRow(recentPkgHistoryContent
- .extendLocatorId("None"), RECENT_PKG_HISTORY_NONE);
- column.addMember(row);
- }
- //cleanup
- for (Canvas child : recentPkgHistoryContent.getChildren()) {
- child.destroy();
- }
- recentPkgHistoryContent.addChild(column);
- recentPkgHistoryContent.markForRedraw();
- }
- });
+ addMember(footer);
}
- /** Fetches recent metric information and updates the DynamicForm instance with i)sparkline information,
- * ii) link to recent metric graph for more details and iii) last metric value formatted to show significant
- * digits.
- */
- private void getRecentMetrics() {
- //display container
- final VLayout column = new VLayout();
- column.setHeight(10);//pack
- final int resourceId = this.resourceComposite.getResource().getId();
-
- //retrieve all relevant measurement definition ids.
- Set<MeasurementDefinition> definitions = this.resourceComposite.getResource().getResourceType()
- .getMetricDefinitions();
-
- //build id mapping for measurementDefinition instances Ex. Free Memory -> MeasurementDefinition[100071]
- final HashMap<String, MeasurementDefinition> measurementDefMap = new HashMap<String, MeasurementDefinition>();
- for (MeasurementDefinition definition : definitions) {
- measurementDefMap.put(definition.getDisplayName(), definition);
+ protected Dashboard getDefaultDashboard() {
+ Subject sessionSubject = UserSessionManager.getSessionSubject();
+ Resource resource = resourceComposite.getResource();
+
+ Dashboard dashboard = new Dashboard();
+
+ dashboard.setName(DASHBOARD_NAME_PREFIX + sessionSubject.getId() + "_" + resource.getId());
+ dashboard.setCategory(DashboardCategory.RESOURCE);
+ dashboard.setResource(resource);
+ dashboard.setColumns(2);
+
+ // TODO, add real portlets
+ // set leftmost column and let the rest be equally divided
+ dashboard.setColumnWidths("40%");
+ dashboard.getConfiguration().put(new PropertySimple(Dashboard.CFG_BACKGROUND, "#F1F2F3"));
+
+ //figure out which portlets to display and how
+ HashMap<String, String> resKeyNameMap = PortletFactory.getRegisteredResourcePortletNameMap();
+ resKeyNameMap = DashboardView.processPortletNameMapForResource(resKeyNameMap, resourceComposite);
+ int colLeft = 0;
+ int colRight = 1;
+ int rowLeft = 0;
+ int rowRight = 0;
+ //Left Column
+ if (resKeyNameMap.containsKey(ResourceMetricsPortlet.KEY)) {//measurments top left if available
+ DashboardPortlet measurements = new DashboardPortlet(ResourceMetricsPortlet.NAME,
+ ResourceMetricsPortlet.KEY, 220);
+ dashboard.addPortlet(measurements, colLeft, rowLeft++);
+ resKeyNameMap.remove(ResourceMetricsPortlet.KEY);
}
- //bundle definition ids for asynch call.
- int[] definitionArrayIds = new int[definitions.size()];
- final String[] displayOrder = new String[definitions.size()];
- measurementDefMap.keySet().toArray(displayOrder);
- //sort the charting data ex. Free Memory, Free Swap Space,..System Load
- Arrays.sort(displayOrder);
-
- //organize definitionArrayIds for ordered request on server.
- int index = 0;
- for (String definitionToDisplay : displayOrder) {
- definitionArrayIds[index++] = measurementDefMap.get(definitionToDisplay).getId();
+ // right Column(approx 60%. As larger more room to display table and N rows.)
+ if (resKeyNameMap.containsKey(ResourceAlertsPortlet.KEY)) {//alerts top right if available
+ DashboardPortlet alerts = new DashboardPortlet(ResourceAlertsPortlet.NAME, ResourceAlertsPortlet.KEY, 220);
+ dashboard.addPortlet(alerts, colRight, rowRight++);
+ resKeyNameMap.remove(ResourceAlertsPortlet.KEY);
+ }
+ if (resKeyNameMap.containsKey(ResourceOperationsPortlet.KEY)) {//operations if available
+ DashboardPortlet ops = new DashboardPortlet(ResourceOperationsPortlet.NAME, ResourceOperationsPortlet.KEY,
+ 220);
+ dashboard.addPortlet(ops, colRight, rowRight++);
+ resKeyNameMap.remove(ResourceOperationsPortlet.KEY);
}
- //make the asynchronous call for all the measurement data
- GWTServiceLookup.getMeasurementDataService().findDataForResource(resourceId, definitionArrayIds,
- System.currentTimeMillis() - (1000L * 60 * 60 * 8), System.currentTimeMillis(), 60,
- new AsyncCallback<List<List<MeasurementDataNumericHighLowComposite>>>() {
- @Override
- public void onFailure(Throwable caught) {
- Log.debug("Error retrieving recent metrics charting data for resource [" + resourceId + "]:"
- + caught.getMessage());
- }
- @Override
- public void onSuccess(List<List<MeasurementDataNumericHighLowComposite>> results) {
- if (!results.isEmpty()) {
- boolean someChartedData = false;
- //iterate over the retrieved charting data
- for (int index = 0; index < displayOrder.length; index++) {
-
- //retrieve the correct measurement definition
- MeasurementDefinition md = measurementDefMap.get(displayOrder[index]);
-
- //load the data results for the given metric definition
- List<MeasurementDataNumericHighLowComposite> data = results.get(index);
-
- //locate last and minimum values.
- double lastValue = -1;
- double minValue = Double.MAX_VALUE;//
- for (MeasurementDataNumericHighLowComposite d : data) {
- if ((!Double.isNaN(d.getValue()))
- && (String.valueOf(d.getValue()).indexOf("NaN") == -1)) {
- if (d.getValue() < minValue) {
- minValue = d.getValue();
- }
- lastValue = d.getValue();
- }
- }
+ //Fill out left column(typically smaller portlets) then alternate cols with remaining
+ boolean displayLeft = false;
+ for (String key : resKeyNameMap.keySet()) {
+ DashboardPortlet portlet = new DashboardPortlet(resKeyNameMap.get(key), key, 100);
+ if (rowLeft < 4) {
+ dashboard.addPortlet(portlet, colLeft, rowLeft++);
+ } else {//alternate
+ if (!displayLeft) {
+ dashboard.addPortlet(portlet, colRight, rowRight++);
+ } else {
+ dashboard.addPortlet(portlet, colLeft, rowLeft++);
+ }
+ //toggle
+ displayLeft = !displayLeft;
+ }
+ }
- //collapse the data into comma delimited list for consumption by third party javascript library(jquery.sparkline)
- String commaDelimitedList = "";
+ return dashboard;
+ }
- for (MeasurementDataNumericHighLowComposite d : data) {
- if ((!Double.isNaN(d.getValue()))
- && (String.valueOf(d.getValue()).indexOf("NaN") == -1)) {
- commaDelimitedList += d.getValue() + ",";
- }
- }
- LocatableDynamicForm row = new LocatableDynamicForm(recentMeasurementsContent
- .extendLocatorId(md.getName()));
- row.setNumCols(3);
- HTMLFlow graph = new HTMLFlow();
- // String contents = "<span id='sparkline_" + index + "' class='dynamicsparkline' width='0'>"
- // + commaDelimitedList + "</span>";
- String contents = "<span id='sparkline_" + index + "' class='dynamicsparkline' width='0' "
- + "values='" + commaDelimitedList + "'>...</span>";
- graph.setContents(contents);
- graph.setContentsType(ContentsType.PAGE);
- //diable scrollbars on span
- graph.setScrollbarSize(0);
-
- CanvasItem graphContainer = new CanvasItem();
- graphContainer.setShowTitle(false);
- graphContainer.setHeight(16);
- graphContainer.setWidth(60);
- graphContainer.setCanvas(graph);
-
- //Link/title element
- //TODO: spinder, change link whenever portal.war/graphing is removed.
- String title = md.getDisplayName() + ":";
- String destination = "/resource/common/monitor/Visibility.do?mode=chartSingleMetricSingleResource&id="
- + resourceId + "&m=" + md.getId();
- LinkItem link = newLinkItem(title, destination);
-
- //Value
- String convertedValue = lastValue + " " + md.getUnits();
- convertedValue = convertLastValueForDisplay(lastValue, md);
- StaticTextItem value = newTextItem(convertedValue);
-
- row.setItems(graphContainer, link, value);
- //if graph content returned
- if ((md.getName().trim().indexOf("Trait.") == -1) && (lastValue != -1)) {
- column.addMember(row);
- someChartedData = true;
- }
- }
- if (!someChartedData) {// when there are results but no chartable entries.
- LocatableDynamicForm row = createEmptyDisplayRow(recentMeasurementsContent
- .extendLocatorId("None"), RECENT_MEASUREMENTS_NONE);
- column.addMember(row);
- } else {
- //insert see more link
- LocatableDynamicForm row = new LocatableDynamicForm(recentMeasurementsContent
- .extendLocatorId("RecentMeasurementsContentSeeMore"));
- addSeeMoreLink(row, ReportDecorator.GWT_RESOURCE_URL + resourceId + "/Monitoring/Graphs/",
- column);
- }
- //call out to 3rd party javascript lib
- BrowserUtility.graphSparkLines();
- } else {
- LocatableDynamicForm row = createEmptyDisplayRow(recentMeasurementsContent
- .extendLocatorId("None"), RECENT_MEASUREMENTS_NONE);
- column.addMember(row);
- }
- }
- });
+ @Override
+ public boolean isInitialized() {
+ return isInitialized;
+ }
- //cleanup
- for (Canvas child : recentMeasurementsContent.getChildren()) {
- child.destroy();
- }
- recentMeasurementsContent.addChild(column);
- recentMeasurementsContent.markForRedraw();
+ public Set<Permission> getGlobalPermissions() {
+ return globalPermissions;
}
- /** Fetches recent bundle deployment information and updates the DynamicForm instance with details.
+ /**
+ * name update not supported because the name is derived from the entity id.
+ * @return
*/
- protected void getRecentBundleDeployments() {
- final int resourceId = this.resourceComposite.getResource().getId();
- ResourceBundleDeploymentCriteria criteria = new ResourceBundleDeploymentCriteria();
- PageControl pageControl = new PageControl(0, 5);
- criteria.setPageControl(pageControl);
- criteria.addFilterResourceIds(resourceId);
- criteria.addSortStatus(PageOrdering.DESC);
- criteria.fetchDestination(true);
- criteria.fetchBundleVersion(true);
- criteria.fetchResourceDeployments(true);
-
- GWTServiceLookup.getBundleService().findBundleDeploymentsByCriteria(criteria,
- new AsyncCallback<PageList<BundleDeployment>>() {
- @Override
- public void onFailure(Throwable caught) {
- Log.debug("Error retrieving installed bundle deployments for resource [" + resourceId + "]:"
- + caught.getMessage());
- }
+ public boolean supportsDashboardNameEdit() {
+ return false;
+ }
- @Override
- public void onSuccess(PageList<BundleDeployment> result) {
- VLayout column = new VLayout();
- column.setHeight(10);
- if (!result.isEmpty()) {
- for (BundleDeployment deployment : result) {
- LocatableDynamicForm row = new LocatableDynamicForm(recentBundleDeployContent
- .extendLocatorId(deployment.getBundleVersion().getName()
- + deployment.getBundleVersion().getVersion()));
- row.setNumCols(3);
-
- StaticTextItem iconItem = newTextItemIcon("subsystems/content/Content_16.png", null);
- String title = deployment.getBundleVersion().getName() + "["
- + deployment.getBundleVersion().getVersion() + "]:";
-
- String destination = ReportDecorator.GWT_BUNDLE_URL
- + deployment.getBundleVersion().getBundle().getId() + "/destinations/"
- + deployment.getDestination().getId();
- LinkItem link = newLinkItem(title, destination);
- StaticTextItem time = newTextItem(GwtRelativeDurationConverter
- .format(deployment.getCtime()));
-
- row.setItems(iconItem, link, time);
- column.addMember(row);
- }
- //insert see more link
- //TODO: spinder:2/25/11 (add this later) no current view for seeing all bundle deployments
- // LocatableDynamicForm row = new LocatableDynamicForm(recentBundleDeployContent.extendLocatorId("RecentBundleContentSeeMore"));
- // addSeeMoreLink(row, LinkManager.getResourceGroupLink(groupId) + "/Events/History/", column);
- } else {
- LocatableDynamicForm row = createEmptyDisplayRow(recentBundleDeployContent
- .extendLocatorId("None"), RECENT_BUNDLE_DEPLOY_NONE);
- column.addMember(row);
- }
- //cleanup
- for (Canvas child : recentBundleDeployContent.getChildren()) {
- child.destroy();
- }
- recentBundleDeployContent.addChild(column);
- recentBundleDeployContent.markForRedraw();
- }
- });
+ public void updateDashboardNames() {
+ return;
}
+
}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/ActivityView3.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/ActivityView3.java
new file mode 100644
index 0000000..355a19a
--- /dev/null
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/ActivityView3.java
@@ -0,0 +1,691 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2010 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+package org.rhq.enterprise.gui.coregui.client.inventory.resource.detail.summary;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import com.allen_sauer.gwt.log.client.Log;
+import com.google.gwt.user.client.rpc.AsyncCallback;
+import com.smartgwt.client.types.ContentsType;
+import com.smartgwt.client.widgets.Canvas;
+import com.smartgwt.client.widgets.HTMLFlow;
+import com.smartgwt.client.widgets.form.fields.CanvasItem;
+import com.smartgwt.client.widgets.form.fields.LinkItem;
+import com.smartgwt.client.widgets.form.fields.StaticTextItem;
+import com.smartgwt.client.widgets.layout.VLayout;
+
+import org.rhq.core.domain.alert.Alert;
+import org.rhq.core.domain.bundle.BundleDeployment;
+import org.rhq.core.domain.configuration.ResourceConfigurationUpdate;
+import org.rhq.core.domain.content.InstalledPackageHistory;
+import org.rhq.core.domain.criteria.AlertCriteria;
+import org.rhq.core.domain.criteria.InstalledPackageCriteria;
+import org.rhq.core.domain.criteria.ResourceBundleDeploymentCriteria;
+import org.rhq.core.domain.event.EventSeverity;
+import org.rhq.core.domain.measurement.MeasurementDefinition;
+import org.rhq.core.domain.measurement.composite.MeasurementDataNumericHighLowComposite;
+import org.rhq.core.domain.measurement.composite.MeasurementOOBComposite;
+import org.rhq.core.domain.operation.composite.ResourceOperationLastCompletedComposite;
+import org.rhq.core.domain.resource.Resource;
+import org.rhq.core.domain.resource.ResourceType;
+import org.rhq.core.domain.resource.ResourceTypeFacet;
+import org.rhq.core.domain.resource.composite.ResourceComposite;
+import org.rhq.core.domain.util.PageControl;
+import org.rhq.core.domain.util.PageList;
+import org.rhq.core.domain.util.PageOrdering;
+import org.rhq.enterprise.gui.coregui.client.ImageManager;
+import org.rhq.enterprise.gui.coregui.client.LinkManager;
+import org.rhq.enterprise.gui.coregui.client.gwt.GWTServiceLookup;
+import org.rhq.enterprise.gui.coregui.client.inventory.common.detail.summary.AbstractActivityView;
+import org.rhq.enterprise.gui.coregui.client.resource.disambiguation.ReportDecorator;
+import org.rhq.enterprise.gui.coregui.client.util.BrowserUtility;
+import org.rhq.enterprise.gui.coregui.client.util.GwtRelativeDurationConverter;
+import org.rhq.enterprise.gui.coregui.client.util.GwtTuple;
+import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableDynamicForm;
+
+/**
+ * The content pane of the Resource Summary>Activity tab.
+ *
+ * @author Simeon Pinder
+ */
+public class ActivityView3 extends AbstractActivityView {
+
+ private ResourceComposite resourceComposite;
+
+ public ActivityView3(String locatorId, ResourceComposite resourceComposite) {
+ super(locatorId, null, resourceComposite);
+ this.resourceComposite = resourceComposite;
+ }
+
+ @Override
+ protected void onInit() {
+ super.onInit();
+ loadData();
+ }
+
+ /**Initiates data request.
+ */
+ protected void loadData() {
+
+ ResourceType type = null;
+ Resource resource = null;
+ Set<ResourceTypeFacet> facets = null;
+
+ if ((resourceComposite != null) && (resourceComposite.getResource() != null)) {
+ resource = resourceComposite.getResource();
+ type = this.resourceComposite.getResource().getResourceType();
+ facets = this.resourceComposite.getResourceFacets().getFacets();
+
+ //alerts
+ getRecentAlerts();
+ //operations
+ if (facets.contains(ResourceTypeFacet.OPERATION)) {
+ getRecentOperations();
+ }
+ //config updates
+ if (facets.contains(ResourceTypeFacet.CONFIGURATION)) {
+ getRecentConfigurationUpdates();
+ }
+ //events
+ if (facets.contains(ResourceTypeFacet.EVENT)) {
+ getRecentEventUpdates();
+ }
+ //measurements
+ getRecentOobs();
+ getRecentPkgHistory();
+ getRecentMetrics();
+
+ //conditionally display Bundle Deployments region.
+ if (displayBundlesForResource(resource)) {
+ getRecentBundleDeployments();
+ }
+ }
+ }
+
+ /** Fetches alerts and updates the DynamicForm instance with the latest
+ * alert information.
+ */
+ private void getRecentAlerts() {
+ final int resourceId = this.resourceComposite.getResource().getId();
+ //fetches last five alerts for this resource
+ AlertCriteria criteria = new AlertCriteria();
+ PageControl pageControl = new PageControl(0, 5);
+ pageControl.initDefaultOrderingField("ctime", PageOrdering.DESC);
+ criteria.setPageControl(pageControl);
+ criteria.addFilterResourceIds(resourceId);
+ GWTServiceLookup.getAlertService().findAlertsByCriteria(criteria, new AsyncCallback<PageList<Alert>>() {
+ @Override
+ public void onSuccess(PageList<Alert> result) {
+ VLayout column = new VLayout();
+ column.setHeight(10);
+ if (!result.isEmpty()) {
+ int rowNum = 0;
+ for (Alert alert : result) {
+ // alert history records do not have a usable locatorId, we'll use rownum, which is unique and
+ // may be repeatable.
+ LocatableDynamicForm row = new LocatableDynamicForm(recentAlertsContent.extendLocatorId(String
+ .valueOf(rowNum++)));
+ row.setNumCols(3);
+ StaticTextItem iconItem = newTextItemIcon(ImageManager.getAlertIcon(alert.getAlertDefinition()
+ .getPriority()), alert.getAlertDefinition().getPriority().getDisplayName());
+ LinkItem link = newLinkItem(alert.getAlertDefinition().getName() + ": ",
+ ReportDecorator.GWT_RESOURCE_URL + resourceId + "/Alerts/History/" + alert.getId());
+ StaticTextItem time = newTextItem(GwtRelativeDurationConverter.format(alert.getCtime()));
+ row.setItems(iconItem, link, time);
+
+ column.addMember(row);
+ }
+ //link to more details
+ LocatableDynamicForm row = new LocatableDynamicForm(recentAlertsContent.extendLocatorId(String
+ .valueOf(rowNum++)));
+ addSeeMoreLink(row, ReportDecorator.GWT_RESOURCE_URL + resourceId + "/Alerts/History/", column);
+ } else {
+ LocatableDynamicForm row = createEmptyDisplayRow(recentAlertsContent.extendLocatorId("None"),
+ RECENT_ALERTS_NONE);
+ column.addMember(row);
+ }
+ for (Canvas child : recentAlertsContent.getChildren()) {
+ child.destroy();
+ }
+ recentAlertsContent.addChild(column);
+ recentAlertsContent.markForRedraw();
+ }
+
+ @Override
+ public void onFailure(Throwable caught) {
+ Log.debug("Error retrieving recent alerts for resource [" + resourceId + "]:" + caught.getMessage());
+ }
+ });
+ }
+
+ /** Fetches operations and updates the DynamicForm instance with the latest
+ * operation information.
+ */
+ private void getRecentOperations() {
+ final int resourceId = this.resourceComposite.getResource().getId();
+ //fetches five most recent operations.
+ PageControl pageControl = new PageControl(0, 5);
+ pageControl.initDefaultOrderingField("ro.createdTime", PageOrdering.DESC);
+ GWTServiceLookup.getOperationService().findRecentCompletedOperations(resourceId, pageControl,
+ new AsyncCallback<PageList<ResourceOperationLastCompletedComposite>>() {
+
+ @Override
+ public void onFailure(Throwable caught) {
+ Log.debug("Error retrieving recent operations for resource [" + resourceId + "]:"
+ + caught.getMessage());
+ }
+
+ @Override
+ public void onSuccess(PageList<ResourceOperationLastCompletedComposite> result) {
+ VLayout column = new VLayout();
+ column.setHeight(10);
+ if (!result.isEmpty()) {
+ int rowNum = 0;
+ for (ResourceOperationLastCompletedComposite report : result) {
+ // operation history records do not have a usable locatorId, we'll use rownum, which is unique and
+ // may be repeatable.
+ LocatableDynamicForm row = new LocatableDynamicForm(recentOperationsContent
+ .extendLocatorId(String.valueOf(rowNum)));
+ row.setNumCols(3);
+
+ StaticTextItem iconItem = newTextItemIcon(ImageManager.getOperationResultsIcon(report
+ .getOperationStatus()), report.getOperationStatus().getDisplayName());
+ LinkItem link = newLinkItem(report.getOperationName() + ": ", LinkManager
+ .getResourceLink(resourceId)
+ + "/Operations/History/" + report.getOperationHistoryId());
+ StaticTextItem time = newTextItem(GwtRelativeDurationConverter.format(report
+ .getOperationStartTime()));
+ row.setItems(iconItem, link, time);
+
+ column.addMember(row);
+ }
+ //link to more details
+ LocatableDynamicForm row = new LocatableDynamicForm(recentOperationsContent
+ .extendLocatorId(String.valueOf(rowNum++)));
+ addSeeMoreLink(row, ReportDecorator.GWT_RESOURCE_URL + resourceId + "/Operations/History/",
+ column);
+ } else {
+ LocatableDynamicForm row = createEmptyDisplayRow(recentOperationsContent
+ .extendLocatorId("None"), RECENT_OPERATIONS_NONE);
+ column.addMember(row);
+ }
+ for (Canvas child : recentOperationsContent.getChildren()) {
+ child.destroy();
+ }
+ recentOperationsContent.addChild(column);
+ recentOperationsContent.markForRedraw();
+ }
+ });
+ }
+
+ /** Fetches configuration updates and updates the DynamicForm instance with the latest
+ * config change information.
+ */
+ private void getRecentConfigurationUpdates() {
+ final int resourceId = this.resourceComposite.getResource().getId();
+
+ PageControl lastFive = new PageControl(0, 5);
+ lastFive.initDefaultOrderingField("cu.createdTime", PageOrdering.DESC);
+
+ GWTServiceLookup.getConfigurationService().findResourceConfigurationUpdates(resourceId, null, null, true,
+ lastFive, new AsyncCallback<PageList<ResourceConfigurationUpdate>>() {
+
+ @Override
+ public void onFailure(Throwable caught) {
+ Log.debug("Error retrieving recent configuration updates for resource [" + resourceId + "]:"
+ + caught.getMessage());
+ }
+
+ @Override
+ public void onSuccess(PageList<ResourceConfigurationUpdate> result) {
+ VLayout column = new VLayout();
+ column.setHeight(10);
+ if (!result.isEmpty()) {
+ int rowNum = 0;
+ for (ResourceConfigurationUpdate update : result) {
+ // config update history records do not have a usable locatorId, we'll use rownum, which is unique and
+ // may be repeatable.
+ LocatableDynamicForm row = new LocatableDynamicForm(recentConfigurationContent
+ .extendLocatorId(String.valueOf(rowNum)));
+ row.setNumCols(3);
+
+ StaticTextItem iconItem = newTextItemIcon(ImageManager.getResourceConfigurationIcon(update
+ .getStatus()), null);
+ String linkTitle = MSG.view_resource_inventory_activity_changed_by() + " "
+ + update.getSubjectName() + ":";
+ if ((update.getSubjectName() == null) || (update.getSubjectName().trim().isEmpty())) {
+ linkTitle = MSG.common_msg_changeAutoDetected();
+ }
+ LinkItem link = newLinkItem(linkTitle, LinkManager.getResourceLink(resourceId)
+ + "/Configuration/History/" + update.getId());
+ StaticTextItem time = newTextItem(GwtRelativeDurationConverter.format(update
+ .getCreatedTime()));
+
+ row.setItems(iconItem, link, time);
+ column.addMember(row);
+ }
+ //link to more details
+ LocatableDynamicForm row = new LocatableDynamicForm(recentConfigurationContent
+ .extendLocatorId(String.valueOf(rowNum++)));
+ addSeeMoreLink(row, ReportDecorator.GWT_RESOURCE_URL + resourceId + "/Configuration/History/",
+ column);
+ } else {
+ LocatableDynamicForm row = createEmptyDisplayRow(recentConfigurationContent
+ .extendLocatorId("None"), RECENT_CONFIGURATIONS_NONE);
+ column.addMember(row);
+ }
+ //cleanup
+ for (Canvas child : recentConfigurationContent.getChildren()) {
+ child.destroy();
+ }
+ recentConfigurationContent.addChild(column);
+ recentConfigurationContent.markForRedraw();
+ }
+ });
+ }
+
+ /** Fetches recent events and updates the DynamicForm instance with the latest
+ * event information over last 24hrs.
+ */
+ private void getRecentEventUpdates() {
+
+ final int resourceId = this.resourceComposite.getResource().getId();
+ long now = System.currentTimeMillis();
+ long nowMinus24Hours = now - (24 * 60 * 60 * 1000);
+
+ GWTServiceLookup.getEventService().getEventCountsBySeverity(resourceId, nowMinus24Hours, now,
+ new AsyncCallback<Map<EventSeverity, Integer>>() {
+
+ @Override
+ public void onFailure(Throwable caught) {
+ Log.debug("Error retrieving recent event counts for resource [" + resourceId + "]:"
+ + caught.getMessage());
+ }
+
+ @Override
+ public void onSuccess(Map<EventSeverity, Integer> eventCounts) {
+ //Now populated Tuples
+ List<GwtTuple<EventSeverity, Integer>> results = new ArrayList<GwtTuple<EventSeverity, Integer>>();
+ for (EventSeverity severity : eventCounts.keySet()) {
+ int count = eventCounts.get(severity);
+ if (count > 0) {
+ results.add(new GwtTuple<EventSeverity, Integer>(severity, count));
+ }
+ }
+ //build display
+ VLayout column = new VLayout();
+ column.setHeight(10);
+
+ if (!results.isEmpty()) {
+ int rowNum = 0;
+ for (GwtTuple<EventSeverity, Integer> tuple : results) {
+ // event history records do not have a usable locatorId, we'll use rownum, which is unique and
+ // may be repeatable.
+ LocatableDynamicForm row = new LocatableDynamicForm(recentEventsContent
+ .extendLocatorId(String.valueOf(rowNum)));
+ row.setNumCols(2);
+ row.setWidth(10);//pack.
+
+ //icon
+ StaticTextItem iconItem = newTextItemIcon(ImageManager.getEventSeverityIcon(tuple
+ .getLefty()), tuple.getLefty().name());
+ //count
+ StaticTextItem count = newTextItem(String.valueOf(tuple.righty));
+ row.setItems(iconItem, count);
+
+ column.addMember(row);
+ }
+ LocatableDynamicForm row = new LocatableDynamicForm(recentEventsContent.extendLocatorId(String
+ .valueOf(rowNum++)));
+ addSeeMoreLink(row, ReportDecorator.GWT_RESOURCE_URL + resourceId + "/Events/History/", column);
+ } else {
+ LocatableDynamicForm row = createEmptyDisplayRow(recentEventsContent.extendLocatorId("None"),
+ RECENT_EVENTS_NONE);
+ column.addMember(row);
+ }
+ //cleanup
+ for (Canvas child : recentEventsContent.getChildren()) {
+ child.destroy();
+ }
+ recentEventsContent.addChild(column);
+ recentEventsContent.markForRedraw();
+ }
+ });
+ }
+
+ /** Fetches OOB measurements and updates the DynamicForm instance with the latest 5
+ * oob change details.
+ */
+ private void getRecentOobs() {
+ final int resourceId = this.resourceComposite.getResource().getId();
+ GWTServiceLookup.getMeasurementDataService().getHighestNOOBsForResource(resourceId, 5,
+ new AsyncCallback<PageList<MeasurementOOBComposite>>() {
+ @Override
+ public void onFailure(Throwable caught) {
+ Log.debug("Error retrieving recent out of bound metrics for resource [" + resourceId + "]:"
+ + caught.getMessage());
+ }
+
+ @Override
+ public void onSuccess(PageList<MeasurementOOBComposite> result) {
+ VLayout column = new VLayout();
+ column.setHeight(10);
+ if (!result.isEmpty()) {
+ for (MeasurementOOBComposite oob : result) {
+ LocatableDynamicForm row = new LocatableDynamicForm(recentOobContent.extendLocatorId(oob
+ .getScheduleName()));
+ row.setNumCols(2);
+
+ String title = oob.getScheduleName() + ":";
+ String destination = "/resource/common/monitor/Visibility.do?m=" + oob.getDefinitionId()
+ + "&id=" + resourceId + "&mode=chartSingleMetricSingleResource";
+ LinkItem link = newLinkItem(title, destination);
+ StaticTextItem time = newTextItem(GwtRelativeDurationConverter.format(oob.getTimestamp()));
+
+ row.setItems(link, time);
+ column.addMember(row);
+ }
+ } else {
+ LocatableDynamicForm row = createEmptyDisplayRow(recentOobContent.extendLocatorId("None"),
+ RECENT_OOB_NONE);
+ column.addMember(row);
+ }
+ recentOobContent.setContents("");
+ for (Canvas child : recentOobContent.getChildren()) {
+ child.destroy();
+ }
+ recentOobContent.addChild(column);
+ recentOobContent.markForRedraw();
+ }
+ });
+ }
+
+ /** Fetches recent package history information and updates the DynamicForm instance with details.
+ */
+ private void getRecentPkgHistory() {
+ final int resourceId = this.resourceComposite.getResource().getId();
+ InstalledPackageCriteria criteria = new InstalledPackageCriteria();
+ criteria.addFilterResourceId(resourceId);
+ PageControl pageControl = new PageControl(0, 5);
+ criteria.setPageControl(pageControl);
+
+ GWTServiceLookup.getContentService().getInstalledPackageHistoryForResource(resourceId, 5,
+ new AsyncCallback<PageList<InstalledPackageHistory>>() {
+ @Override
+ public void onFailure(Throwable caught) {
+ Log.debug("Error retrieving installed package history for resource [" + resourceId + "]:"
+ + caught.getMessage());
+ }
+
+ @Override
+ public void onSuccess(PageList<InstalledPackageHistory> result) {
+ VLayout column = new VLayout();
+ column.setHeight(10);
+ if (!result.isEmpty()) {
+ for (InstalledPackageHistory history : result) {
+ LocatableDynamicForm row = new LocatableDynamicForm(recentPkgHistoryContent
+ .extendLocatorId(history.getPackageVersion().getFileName()
+ + history.getPackageVersion().getVersion()));
+ row.setNumCols(3);
+
+ StaticTextItem iconItem = newTextItemIcon("subsystems/content/Package_16.png", null);
+ String title = history.getPackageVersion().getFileName() + ":";
+ String destination = "/rhq/resource/content/audit-trail-item.xhtml?id=" + resourceId
+ + "&selectedHistoryId=" + history.getId();
+ LinkItem link = newLinkItem(title, destination);
+ StaticTextItem time = newTextItem(GwtRelativeDurationConverter.format(history
+ .getTimestamp()));
+
+ row.setItems(iconItem, link, time);
+ column.addMember(row);
+ }
+ // //insert see more link
+ // LocatableDynamicForm row = new LocatableDynamicForm(recentPkgHistoryContent
+ // .extendLocatorId("RecentPkgHistorySeeMore"));
+ // String destination = "/rhq/resource/content/audit-trail-item.xhtml?id=" + resourceId;
+ // addSeeMoreLink(row, destination, column);
+ } else {
+ LocatableDynamicForm row = createEmptyDisplayRow(recentPkgHistoryContent
+ .extendLocatorId("None"), RECENT_PKG_HISTORY_NONE);
+ column.addMember(row);
+ }
+ //cleanup
+ for (Canvas child : recentPkgHistoryContent.getChildren()) {
+ child.destroy();
+ }
+ recentPkgHistoryContent.addChild(column);
+ recentPkgHistoryContent.markForRedraw();
+ }
+ });
+ }
+
+ /** Fetches recent metric information and updates the DynamicForm instance with i)sparkline information,
+ * ii) link to recent metric graph for more details and iii) last metric value formatted to show significant
+ * digits.
+ */
+ private void getRecentMetrics() {
+ //display container
+ final VLayout column = new VLayout();
+ column.setHeight(10);//pack
+ final int resourceId = this.resourceComposite.getResource().getId();
+
+ //retrieve all relevant measurement definition ids.
+ Set<MeasurementDefinition> definitions = this.resourceComposite.getResource().getResourceType()
+ .getMetricDefinitions();
+
+ //build id mapping for measurementDefinition instances Ex. Free Memory -> MeasurementDefinition[100071]
+ final HashMap<String, MeasurementDefinition> measurementDefMap = new HashMap<String, MeasurementDefinition>();
+ for (MeasurementDefinition definition : definitions) {
+ measurementDefMap.put(definition.getDisplayName(), definition);
+ }
+
+ //bundle definition ids for asynch call.
+ int[] definitionArrayIds = new int[definitions.size()];
+ final String[] displayOrder = new String[definitions.size()];
+ measurementDefMap.keySet().toArray(displayOrder);
+ //sort the charting data ex. Free Memory, Free Swap Space,..System Load
+ Arrays.sort(displayOrder);
+
+ //organize definitionArrayIds for ordered request on server.
+ int index = 0;
+ for (String definitionToDisplay : displayOrder) {
+ definitionArrayIds[index++] = measurementDefMap.get(definitionToDisplay).getId();
+ }
+ //make the asynchronous call for all the measurement data
+ GWTServiceLookup.getMeasurementDataService().findDataForResource(resourceId, definitionArrayIds,
+ System.currentTimeMillis() - (1000L * 60 * 60 * 8), System.currentTimeMillis(), 60,
+ new AsyncCallback<List<List<MeasurementDataNumericHighLowComposite>>>() {
+ @Override
+ public void onFailure(Throwable caught) {
+ Log.debug("Error retrieving recent metrics charting data for resource [" + resourceId + "]:"
+ + caught.getMessage());
+ }
+
+ @Override
+ public void onSuccess(List<List<MeasurementDataNumericHighLowComposite>> results) {
+ if (!results.isEmpty()) {
+ boolean someChartedData = false;
+ //iterate over the retrieved charting data
+ for (int index = 0; index < displayOrder.length; index++) {
+
+ //retrieve the correct measurement definition
+ MeasurementDefinition md = measurementDefMap.get(displayOrder[index]);
+
+ //load the data results for the given metric definition
+ List<MeasurementDataNumericHighLowComposite> data = results.get(index);
+
+ //locate last and minimum values.
+ double lastValue = -1;
+ double minValue = Double.MAX_VALUE;//
+ for (MeasurementDataNumericHighLowComposite d : data) {
+ if ((!Double.isNaN(d.getValue()))
+ && (String.valueOf(d.getValue()).indexOf("NaN") == -1)) {
+ if (d.getValue() < minValue) {
+ minValue = d.getValue();
+ }
+ lastValue = d.getValue();
+ }
+ }
+
+ //collapse the data into comma delimited list for consumption by third party javascript library(jquery.sparkline)
+ String commaDelimitedList = "";
+
+ for (MeasurementDataNumericHighLowComposite d : data) {
+ if ((!Double.isNaN(d.getValue()))
+ && (String.valueOf(d.getValue()).indexOf("NaN") == -1)) {
+ commaDelimitedList += d.getValue() + ",";
+ }
+ }
+ LocatableDynamicForm row = new LocatableDynamicForm(recentMeasurementsContent
+ .extendLocatorId(md.getName()));
+ row.setNumCols(3);
+ HTMLFlow graph = new HTMLFlow();
+ // String contents = "<span id='sparkline_" + index + "' class='dynamicsparkline' width='0'>"
+ // + commaDelimitedList + "</span>";
+ String contents = "<span id='sparkline_" + index + "' class='dynamicsparkline' width='0' "
+ + "values='" + commaDelimitedList + "'>...</span>";
+ graph.setContents(contents);
+ graph.setContentsType(ContentsType.PAGE);
+ //diable scrollbars on span
+ graph.setScrollbarSize(0);
+
+ CanvasItem graphContainer = new CanvasItem();
+ graphContainer.setShowTitle(false);
+ graphContainer.setHeight(16);
+ graphContainer.setWidth(60);
+ graphContainer.setCanvas(graph);
+
+ //Link/title element
+ //TODO: spinder, change link whenever portal.war/graphing is removed.
+ String title = md.getDisplayName() + ":";
+ String destination = "/resource/common/monitor/Visibility.do?mode=chartSingleMetricSingleResource&id="
+ + resourceId + "&m=" + md.getId();
+ LinkItem link = newLinkItem(title, destination);
+
+ //Value
+ String convertedValue = lastValue + " " + md.getUnits();
+ convertedValue = convertLastValueForDisplay(lastValue, md);
+ StaticTextItem value = newTextItem(convertedValue);
+
+ row.setItems(graphContainer, link, value);
+ //if graph content returned
+ if ((md.getName().trim().indexOf("Trait.") == -1) && (lastValue != -1)) {
+ column.addMember(row);
+ someChartedData = true;
+ }
+ }
+ if (!someChartedData) {// when there are results but no chartable entries.
+ LocatableDynamicForm row = createEmptyDisplayRow(recentMeasurementsContent
+ .extendLocatorId("None"), RECENT_MEASUREMENTS_NONE);
+ column.addMember(row);
+ } else {
+ //insert see more link
+ LocatableDynamicForm row = new LocatableDynamicForm(recentMeasurementsContent
+ .extendLocatorId("RecentMeasurementsContentSeeMore"));
+ addSeeMoreLink(row, ReportDecorator.GWT_RESOURCE_URL + resourceId + "/Monitoring/Graphs/",
+ column);
+ }
+ //call out to 3rd party javascript lib
+ BrowserUtility.graphSparkLines();
+ } else {
+ LocatableDynamicForm row = createEmptyDisplayRow(recentMeasurementsContent
+ .extendLocatorId("None"), RECENT_MEASUREMENTS_NONE);
+ column.addMember(row);
+ }
+ }
+ });
+
+ //cleanup
+ for (Canvas child : recentMeasurementsContent.getChildren()) {
+ child.destroy();
+ }
+ recentMeasurementsContent.addChild(column);
+ recentMeasurementsContent.markForRedraw();
+ }
+
+ /** Fetches recent bundle deployment information and updates the DynamicForm instance with details.
+ */
+ protected void getRecentBundleDeployments() {
+ final int resourceId = this.resourceComposite.getResource().getId();
+ ResourceBundleDeploymentCriteria criteria = new ResourceBundleDeploymentCriteria();
+ PageControl pageControl = new PageControl(0, 5);
+ criteria.setPageControl(pageControl);
+ criteria.addFilterResourceIds(resourceId);
+ criteria.addSortStatus(PageOrdering.DESC);
+ criteria.fetchDestination(true);
+ criteria.fetchBundleVersion(true);
+ criteria.fetchResourceDeployments(true);
+
+ GWTServiceLookup.getBundleService().findBundleDeploymentsByCriteria(criteria,
+ new AsyncCallback<PageList<BundleDeployment>>() {
+ @Override
+ public void onFailure(Throwable caught) {
+ Log.debug("Error retrieving installed bundle deployments for resource [" + resourceId + "]:"
+ + caught.getMessage());
+ }
+
+ @Override
+ public void onSuccess(PageList<BundleDeployment> result) {
+ VLayout column = new VLayout();
+ column.setHeight(10);
+ if (!result.isEmpty()) {
+ for (BundleDeployment deployment : result) {
+ LocatableDynamicForm row = new LocatableDynamicForm(recentBundleDeployContent
+ .extendLocatorId(deployment.getBundleVersion().getName()
+ + deployment.getBundleVersion().getVersion()));
+ row.setNumCols(3);
+
+ StaticTextItem iconItem = newTextItemIcon("subsystems/content/Content_16.png", null);
+ String title = deployment.getBundleVersion().getName() + "["
+ + deployment.getBundleVersion().getVersion() + "]:";
+
+ String destination = ReportDecorator.GWT_BUNDLE_URL
+ + deployment.getBundleVersion().getBundle().getId() + "/destinations/"
+ + deployment.getDestination().getId();
+ LinkItem link = newLinkItem(title, destination);
+ StaticTextItem time = newTextItem(GwtRelativeDurationConverter
+ .format(deployment.getCtime()));
+
+ row.setItems(iconItem, link, time);
+ column.addMember(row);
+ }
+ //insert see more link
+ //TODO: spinder:2/25/11 (add this later) no current view for seeing all bundle deployments
+ // LocatableDynamicForm row = new LocatableDynamicForm(recentBundleDeployContent.extendLocatorId("RecentBundleContentSeeMore"));
+ // addSeeMoreLink(row, LinkManager.getResourceGroupLink(groupId) + "/Events/History/", column);
+ } else {
+ LocatableDynamicForm row = createEmptyDisplayRow(recentBundleDeployContent
+ .extendLocatorId("None"), RECENT_BUNDLE_DEPLOY_NONE);
+ column.addMember(row);
+ }
+ //cleanup
+ for (Canvas child : recentBundleDeployContent.getChildren()) {
+ child.destroy();
+ }
+ recentBundleDeployContent.addChild(column);
+ recentBundleDeployContent.markForRedraw();
+ }
+ });
+ }
+}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/message/MessageCenterView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/message/MessageCenterView.java
index df35e27..f9ac79c 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/message/MessageCenterView.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/message/MessageCenterView.java
@@ -291,7 +291,9 @@ public class MessageCenterView extends Table implements MessageCenter.MessageLis
public void refresh() {
try {
super.refresh();
- getListGrid().setRecords(transform(CoreGUI.getMessageCenter().getMessages()));
+ if ((getListGrid() != null) && (CoreGUI.getMessageCenter().getMessages() != null)) {
+ getListGrid().setRecords(transform(CoreGUI.getMessageCenter().getMessages()));
+ }
refreshTableInfo();
} catch (Throwable e) {
Log.error("Cannot refresh messages", e);
commit b0a6460388ce646db376eebad485212f7d7427d1
Author: Simeon Pinder <spinder(a)redhat.com>
Date: Sun Mar 20 22:15:48 2011 -0400
i)fix for MeasurementRangeEditor alignment issue
ii)configuration editor widget property cleanup
iii)fix icon refresh issue with event portlets
iv)fix data init duplication issue with resourceOperationsPortlet
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/measurement/AbstractMeasurementRangeEditor.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/measurement/AbstractMeasurementRangeEditor.java
index d8c69b8..1978665 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/measurement/AbstractMeasurementRangeEditor.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/measurement/AbstractMeasurementRangeEditor.java
@@ -219,6 +219,7 @@ public abstract class AbstractMeasurementRangeEditor extends LocatableDynamicFor
advancedStartItem.enable();
advancedEndItem.enable();
advancedSimpleButton.enable();
+ markForRedraw();
}
}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/measurement/CustomConfigMeasurementRangeEditor.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/measurement/CustomConfigMeasurementRangeEditor.java
index 01794cb..f349f5d 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/measurement/CustomConfigMeasurementRangeEditor.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/measurement/CustomConfigMeasurementRangeEditor.java
@@ -36,8 +36,8 @@ public class CustomConfigMeasurementRangeEditor extends AbstractMeasurementRange
public static final String ALERT_METRIC_RANGE_ENABLE = Constant.METRIC_RANGE_ENABLE;
public static final String DEFAULT_VALUE_RANGE_RO = Boolean.FALSE.toString();
- public static final Integer DEFAULT_VALUE_RANGE_LASTN = Integer.valueOf(8);
- public static final Integer DEFAULT_VALUE_RANGE_UNIT = Integer.valueOf(3);
+ public static final Integer DEFAULT_VALUE_RANGE_LASTN = Integer.valueOf(Constant.METRIC_RANGE_LASTN_DEFAULT);
+ public static final Integer DEFAULT_VALUE_RANGE_UNIT = Integer.valueOf(Constant.METRIC_RANGE_UNIT_DEFAULT);
private ConfigurationMeasurementPreferences measurementPrefs;
@@ -106,7 +106,7 @@ public class CustomConfigMeasurementRangeEditor extends AbstractMeasurementRange
if (metricRangePreferences == null) {
metricRangePreferences = new MetricRangePreferences();
}
- // //parse config and lazily init timing elements
+ //parse config and lazily init timing elements
metricRangePreferences.explicitBeginEnd = Boolean.valueOf(
config.getSimple(PREF_METRIC_RANGE_BEGIN_END_FLAG).getStringValue()).booleanValue();
//check to display advanced settings widget components
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/PortletConfigurationEditorComponent.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/PortletConfigurationEditorComponent.java
index 6eb15c4..cea94a9 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/PortletConfigurationEditorComponent.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/PortletConfigurationEditorComponent.java
@@ -46,41 +46,50 @@ public class PortletConfigurationEditorComponent {
public interface Constant {
String ALERT_PRIORITY = "ALERT_PRIORITY";
+ String ALERT_PRIORITY_DEFAULT = "";//all priorities==no priorities
String METRIC_RANGE_ENABLE = "METRIC_RANGE_ENABLE";
+ String METRIC_RANGE_ENABLE_DEFAULT = String.valueOf(false);//disabled
String METRIC_RANGE_BEGIN_END_FLAG = "METRIC_RANGE_BEGIN_END_FLAG";
+ String METRIC_RANGE_BEGIN_END_FLAG_DEFAULT = String.valueOf(false);//disabled
String METRIC_RANGE = "METRIC_RANGE";
+ String METRIC_RANGE_DEFAULT = "";//no previous range.
String METRIC_RANGE_LASTN = "METRIC_RANGE_LASTN";
String METRIC_RANGE_LASTN_DEFAULT = String.valueOf(8);
String METRIC_RANGE_UNIT = "METRIC_RANGE_UNIT";
String METRIC_RANGE_UNIT_DEFAULT = String.valueOf(MeasurementUtility.UNIT_HOURS);
String RESULT_SEVERITY = "severities";
+ String RESULT_SEVERITY_DEFAULT = "";//all severities
String RESULT_SORT_ORDER = "RESULT_SORT_ORDER";
+ String RESULT_SORT_ORDER_DEFAULT = PageOrdering.DESC.name();//descending
String RESULT_SORT_PRIORITY = "sort.priority";
+ // String RESULT_SORT_PRIORITY_DEFAULT = "sort.priority";
String RESULT_COUNT = "RESULT_COUNT";
String RESULT_COUNT_DEFAULT = "5";
String CUSTOM_REFRESH = "CUSTOM_REFRESH";
String OPERATION_STATUS = "OPERATION_STATUS";
+ String OPERATION_STATUS_DEFAULT = "";//empty
}
//configuration map initialization
public static Map<String, String> CONFIG_PROPERTY_INITIALIZATION = new HashMap<String, String>();
static {// Key, Default value
//alert priority, if empty initialize to "" i.e. all priorities
- CONFIG_PROPERTY_INITIALIZATION.put(Constant.ALERT_PRIORITY, "");
+ CONFIG_PROPERTY_INITIALIZATION.put(Constant.ALERT_PRIORITY, Constant.ALERT_PRIORITY_DEFAULT);
//result sort order, if empty initialize to "DESC"
- CONFIG_PROPERTY_INITIALIZATION.put(Constant.RESULT_SORT_ORDER, PageOrdering.DESC.name());
+ CONFIG_PROPERTY_INITIALIZATION.put(Constant.RESULT_SORT_ORDER, Constant.RESULT_SORT_ORDER_DEFAULT);
//result count, if empty initialize to 5
CONFIG_PROPERTY_INITIALIZATION.put(Constant.RESULT_COUNT, Constant.RESULT_COUNT_DEFAULT);
//whether to specify time range for alerts. Defaults to false
- CONFIG_PROPERTY_INITIALIZATION.put(Constant.METRIC_RANGE_ENABLE, String.valueOf(false));
+ CONFIG_PROPERTY_INITIALIZATION.put(Constant.METRIC_RANGE_ENABLE, Constant.METRIC_RANGE_ENABLE_DEFAULT);
//whether Begin and End values set for time. Aka. Advanced/full range setting Defaults to false
- CONFIG_PROPERTY_INITIALIZATION.put(Constant.METRIC_RANGE_BEGIN_END_FLAG, String.valueOf(false));
+ CONFIG_PROPERTY_INITIALIZATION.put(Constant.METRIC_RANGE_BEGIN_END_FLAG,
+ Constant.METRIC_RANGE_BEGIN_END_FLAG_DEFAULT);
//whether in simple mode. Ex. 8 hrs. Defaults to 8
CONFIG_PROPERTY_INITIALIZATION.put(Constant.METRIC_RANGE_LASTN, Constant.METRIC_RANGE_LASTN_DEFAULT);
- //whether in simple mode. Ex. 8 hrs. Defaults to 8
+ //whether in simple mode. Ex. hrs. Defaults to hours
CONFIG_PROPERTY_INITIALIZATION.put(Constant.METRIC_RANGE_UNIT, Constant.METRIC_RANGE_UNIT_DEFAULT);
//operation status, if empty initialize to "" i.e. all stati
- CONFIG_PROPERTY_INITIALIZATION.put(Constant.OPERATION_STATUS, "");
+ CONFIG_PROPERTY_INITIALIZATION.put(Constant.OPERATION_STATUS, Constant.OPERATION_STATUS_DEFAULT);
}
/* Single select combobox for number of items to display on the dashboard
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/groups/GroupAlertsPortlet.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/groups/GroupAlertsPortlet.java
index 120c974..4fa8807 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/groups/GroupAlertsPortlet.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/groups/GroupAlertsPortlet.java
@@ -273,7 +273,6 @@ public class GroupAlertsPortlet extends AlertHistoryView implements CustomSettin
refreshTimer = new Timer() {
public void run() {
-
redraw();
}
};
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/groups/GroupEventsPortlet.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/groups/GroupEventsPortlet.java
index 2ee782e..35d5886 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/groups/GroupEventsPortlet.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/groups/GroupEventsPortlet.java
@@ -250,6 +250,7 @@ public class GroupEventsPortlet extends LocatableVLayout implements CustomSettin
column.addMember(row);
}
+ column.markForRedraw();
//insert see more link
LocatableDynamicForm row = new LocatableDynamicForm(recentEventsContent.extendLocatorId(String
.valueOf(rowNum)));
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/groups/GroupOperationsPortlet.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/groups/GroupOperationsPortlet.java
index 0e2e00c..e148b1e 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/groups/GroupOperationsPortlet.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/groups/GroupOperationsPortlet.java
@@ -58,7 +58,6 @@ import org.rhq.enterprise.gui.coregui.client.dashboard.PortletWindow;
import org.rhq.enterprise.gui.coregui.client.dashboard.portlets.PortletConfigurationEditorComponent;
import org.rhq.enterprise.gui.coregui.client.dashboard.portlets.PortletConfigurationEditorComponent.Constant;
import org.rhq.enterprise.gui.coregui.client.gwt.GWTServiceLookup;
-import org.rhq.enterprise.gui.coregui.client.inventory.common.detail.operation.history.AbstractOperationHistoryDataSource;
import org.rhq.enterprise.gui.coregui.client.inventory.common.detail.summary.AbstractActivityView;
import org.rhq.enterprise.gui.coregui.client.inventory.groups.detail.ResourceGroupDetailView;
import org.rhq.enterprise.gui.coregui.client.inventory.groups.detail.operation.history.GroupOperationHistoryDataSource;
@@ -83,7 +82,7 @@ public class GroupOperationsPortlet extends LocatableVLayout implements CustomSe
// set on initial configuration, the window for this portlet view.
protected PortletWindow portletWindow;
- protected GroupOperationsCriteriaHistoryListView dataSource;
+ private GroupOperationsCriteriaHistoryListView groupOperations;
//defines the list of configuration elements to load/persist for this portlet
protected static List<String> CONFIG_INCLUDE = new ArrayList<String>();
@@ -111,7 +110,6 @@ public class GroupOperationsPortlet extends LocatableVLayout implements CustomSe
protected String baseViewPath = "";
protected LocatableCanvas recentOperationsContent = new LocatableCanvas(extendLocatorId("RecentOperations"));
protected String locatorId;
- private GroupOperationsCriteriaHistoryListView groupOperations;
public GroupOperationsPortlet(String locatorId) {
super(locatorId);
@@ -233,7 +231,6 @@ public class GroupOperationsPortlet extends LocatableVLayout implements CustomSe
form.setMargin(5);
//add label about what configuration affects? redundant?
-
//add filter operation status type selector
final SelectItem operationStatusSelector = PortletConfigurationEditorComponent
.getOperationStatusEditor(portletConfig);
@@ -256,7 +253,6 @@ public class GroupOperationsPortlet extends LocatableVLayout implements CustomSe
public void onSubmitValues(SubmitValuesEvent event) {
//result count
- String selectedValue;
portletConfig = AbstractActivityView.saveResultCounterSettings(resultCountSelector, portletConfig);
//time range configuration
@@ -350,16 +346,16 @@ class GroupOperationsCriteriaHistoryListView extends GroupOperationHistoryListVi
private ResourceGroupComposite composite;
- public GroupOperationsCriteriaHistoryListView(String locatorId, AbstractOperationHistoryDataSource dataSource,
+ public GroupOperationsCriteriaHistoryListView(String locatorId, GroupOperationsCriteriaDataSource dataSource,
String title, Criteria criteria, ResourceGroupComposite composite) {
super(locatorId, composite);
- setDataSource(dataSource);
+ super.setDataSource(dataSource);
this.composite = composite;
setShowFooterRefresh(false); //disable footer refresh
}
- public void setDatasource(AbstractOperationHistoryDataSource datasource) {
- setDataSource(datasource);
+ public void setDatasource(GroupOperationsCriteriaDataSource datasource) {
+ super.setDataSource(datasource);
}
@Override
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/resource/ResourceEventsPortlet.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/resource/ResourceEventsPortlet.java
index 01a0b96..d915351 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/resource/ResourceEventsPortlet.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/resource/ResourceEventsPortlet.java
@@ -60,7 +60,6 @@ public class ResourceEventsPortlet extends GroupEventsPortlet {
//figure out which page we're loading
String currentPage = History.getToken();
String[] elements = currentPage.split("/");
- // int currentGroupIdentifier = Integer.valueOf(elements[1]);
this.resourceId = Integer.valueOf(elements[1]);
}
@@ -157,7 +156,6 @@ public class ResourceEventsPortlet extends GroupEventsPortlet {
//insert see more link
LocatableDynamicForm row = new LocatableDynamicForm(recentEventsContent.extendLocatorId(String
.valueOf(rowNum)));
- // AbstractActivityView.addSeeMoreLink(row, ReportDecorator.GWT_GROUP_URL + resourceId
AbstractActivityView.addSeeMoreLink(row, ReportDecorator.GWT_RESOURCE_URL + resourceId
+ "/Events/History/", column);
} else {
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/resource/ResourceOperationsPortlet.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/resource/ResourceOperationsPortlet.java
index 96be005..30929c1 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/resource/ResourceOperationsPortlet.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/resource/ResourceOperationsPortlet.java
@@ -18,6 +18,8 @@
*/
package org.rhq.enterprise.gui.coregui.client.dashboard.portlets.resource;
+import java.util.ArrayList;
+
import com.allen_sauer.gwt.log.client.Log;
import com.google.gwt.user.client.History;
import com.google.gwt.user.client.rpc.AsyncCallback;
@@ -25,6 +27,10 @@ import com.smartgwt.client.data.Criteria;
import com.smartgwt.client.data.DSRequest;
import com.smartgwt.client.data.DSResponse;
import com.smartgwt.client.widgets.Canvas;
+import com.smartgwt.client.widgets.form.DynamicForm;
+import com.smartgwt.client.widgets.form.events.SubmitValuesEvent;
+import com.smartgwt.client.widgets.form.events.SubmitValuesHandler;
+import com.smartgwt.client.widgets.form.fields.SelectItem;
import org.rhq.core.domain.configuration.Configuration;
import org.rhq.core.domain.configuration.PropertySimple;
@@ -37,15 +43,20 @@ import org.rhq.core.domain.util.PageControl;
import org.rhq.core.domain.util.PageList;
import org.rhq.core.domain.util.PageOrdering;
import org.rhq.enterprise.gui.coregui.client.CoreGUI;
+import org.rhq.enterprise.gui.coregui.client.components.measurement.CustomConfigMeasurementRangeEditor;
import org.rhq.enterprise.gui.coregui.client.dashboard.Portlet;
import org.rhq.enterprise.gui.coregui.client.dashboard.PortletViewFactory;
+import org.rhq.enterprise.gui.coregui.client.dashboard.portlets.PortletConfigurationEditorComponent;
import org.rhq.enterprise.gui.coregui.client.dashboard.portlets.PortletConfigurationEditorComponent.Constant;
import org.rhq.enterprise.gui.coregui.client.dashboard.portlets.groups.GroupOperationsPortlet;
import org.rhq.enterprise.gui.coregui.client.gwt.GWTServiceLookup;
-import org.rhq.enterprise.gui.coregui.client.inventory.common.detail.operation.history.AbstractOperationHistoryDataSource;
import org.rhq.enterprise.gui.coregui.client.inventory.common.detail.operation.history.AbstractOperationHistoryListView;
+import org.rhq.enterprise.gui.coregui.client.inventory.common.detail.summary.AbstractActivityView;
import org.rhq.enterprise.gui.coregui.client.inventory.resource.detail.operation.history.ResourceOperationHistoryDataSource;
import org.rhq.enterprise.gui.coregui.client.inventory.resource.detail.operation.history.ResourceOperationHistoryDetailsView;
+import org.rhq.enterprise.gui.coregui.client.util.MeasurementUtility;
+import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableDynamicForm;
+import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableVLayout;
/**
* @author Simeon Pinder
@@ -74,11 +85,73 @@ public class ResourceOperationsPortlet extends GroupOperationsPortlet {
@Override
protected void onInit() {
- super.onInit();
+ // super.onInit();
initializeUi();
+ // loadData();
+ }
+
+ @Override
+ public void redraw() {
loadData();
}
+ @Override
+ public DynamicForm getCustomSettingsForm() {
+ LocatableDynamicForm customSettings = new LocatableDynamicForm(extendLocatorId("customSettings"));
+ LocatableVLayout page = new LocatableVLayout(customSettings.extendLocatorId("page"));
+ //build editor form container
+ final LocatableDynamicForm form = new LocatableDynamicForm(page.extendLocatorId("alert-filter"));
+ form.setMargin(5);
+
+ //add label about what configuration affects? redundant?
+ //add filter operation status type selector
+ final SelectItem operationStatusSelector = PortletConfigurationEditorComponent
+ .getOperationStatusEditor(portletConfig);
+ //add sort priority selector
+ final SelectItem resultSortSelector = PortletConfigurationEditorComponent
+ .getResulSortOrderEditor(portletConfig);
+ //add result count selector
+ final SelectItem resultCountSelector = PortletConfigurationEditorComponent.getResultCountEditor(portletConfig);
+
+ //add range selector
+ final CustomConfigMeasurementRangeEditor measurementRangeEditor = PortletConfigurationEditorComponent
+ .getMeasurementRangeEditor(portletConfig);
+
+ form.setItems(operationStatusSelector, resultSortSelector, resultCountSelector);
+
+ //submit handler
+ customSettings.addSubmitValuesHandler(new SubmitValuesHandler() {
+
+ @Override
+ public void onSubmitValues(SubmitValuesEvent event) {
+
+ //result count
+ portletConfig = AbstractActivityView.saveResultCounterSettings(resultCountSelector, portletConfig);
+
+ //time range configuration
+ portletConfig = AbstractActivityView.saveMeasurementRangeEditorSettings(measurementRangeEditor,
+ portletConfig);
+
+ //operation priority
+ portletConfig = AbstractActivityView.saveOperationStatusSelectorSettings(operationStatusSelector,
+ portletConfig);
+
+ //persist and reload portlet
+ storedPortlet.setConfiguration(portletConfig);
+ configure(portletWindow, storedPortlet);
+ //resynch the config object in the datasource
+ resourceOperations.setDatasource(new ResourceOperationsCriteriaDataSource(portletConfig));
+ //apply latest settings to the visible result set
+ redraw();
+ }
+ });
+ form.markForRedraw();
+ page.addMember(measurementRangeEditor);
+ page.addMember(form);
+ customSettings.addChild(page);
+ return customSettings;
+ }
+
private void loadData() {
//populate composite data
ResourceCriteria criteria = new ResourceCriteria();
@@ -134,9 +207,9 @@ public class ResourceOperationsPortlet extends GroupOperationsPortlet {
*/
class ResourceOperationsCriteriaHistoryListView extends AbstractOperationHistoryListView {
- private AbstractOperationHistoryDataSource datasource;
+ private ResourceOperationsCriteriaDataSource datasource;
- public ResourceOperationsCriteriaHistoryListView(String locatorId, AbstractOperationHistoryDataSource dataSource,
+ public ResourceOperationsCriteriaHistoryListView(String locatorId, ResourceOperationsCriteriaDataSource dataSource,
String title, Criteria criteria, ResourceComposite composite) {
super(locatorId, dataSource, title, criteria);
this.datasource = dataSource;
@@ -156,11 +229,11 @@ class ResourceOperationsCriteriaHistoryListView extends AbstractOperationHistory
return new ResourceOperationHistoryDetailsView(extendLocatorId("DetailsView"), this.resourceComposite);
}
- public AbstractOperationHistoryDataSource getDatasource() {
+ public ResourceOperationsCriteriaDataSource getDatasource() {
return datasource;
}
- public void setDatasource(AbstractOperationHistoryDataSource datasource) {
+ public void setDatasource(ResourceOperationsCriteriaDataSource datasource) {
this.datasource = datasource;
}
@@ -219,12 +292,34 @@ class ResourceOperationsCriteriaDataSource extends ResourceOperationHistoryDataS
//result timeframe if enabled
property = portletConfig.getSimple(Constant.METRIC_RANGE_ENABLE);
if (Boolean.valueOf(property.getBooleanValue())) {//then proceed setting
- property = portletConfig.getSimple(Constant.METRIC_RANGE);
+
+ boolean isAdvanced = false;
+ //detect type of widget[Simple|Advanced]
+ property = portletConfig.getSimple(Constant.METRIC_RANGE_BEGIN_END_FLAG);
if (property != null) {
- String currentSetting = property.getStringValue();
- String[] range = currentSetting.split(",");
- criteria.addFilterStartTime(Long.valueOf(range[0]));
- criteria.addFilterEndTime(Long.valueOf(range[1]));
+ isAdvanced = property.getBooleanValue();
+ }
+ if (isAdvanced) {
+ //Advanced time settings
+ property = portletConfig.getSimple(Constant.METRIC_RANGE);
+ if (property != null) {
+ String currentSetting = property.getStringValue();
+ String[] range = currentSetting.split(",");
+ criteria.addFilterStartTime(Long.valueOf(range[0]));
+ criteria.addFilterEndTime(Long.valueOf(range[1]));
+ }
+ } else {
+ //Simple time settings
+ property = portletConfig.getSimple(Constant.METRIC_RANGE_LASTN);
+ if (property != null) {
+ int lastN = property.getIntegerValue();
+ property = portletConfig.getSimple(Constant.METRIC_RANGE_UNIT);
+ int lastUnits = property.getIntegerValue();
+ ArrayList<Long> beginEnd = MeasurementUtility.calculateTimeFrame(lastN, Integer
+ .valueOf(lastUnits));
+ criteria.addFilterStartTime(Long.valueOf(beginEnd.get(0)));
+ criteria.addFilterEndTime(Long.valueOf(beginEnd.get(1)));
+ }
}
}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/detail/summary/AbstractActivityView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/detail/summary/AbstractActivityView.java
index c67dce9..2da6e15 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/detail/summary/AbstractActivityView.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/detail/summary/AbstractActivityView.java
@@ -58,6 +58,7 @@ import org.rhq.enterprise.gui.coregui.client.components.measurement.CustomConfig
import org.rhq.enterprise.gui.coregui.client.dashboard.portlets.PortletConfigurationEditorComponent.Constant;
import org.rhq.enterprise.gui.coregui.client.gwt.GWTServiceLookup;
import org.rhq.enterprise.gui.coregui.client.util.BrowserUtility;
+import org.rhq.enterprise.gui.coregui.client.util.MeasurementUtility;
import org.rhq.enterprise.gui.coregui.client.util.measurement.GwtMonitorUtils;
import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableCanvas;
import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableDynamicForm;
@@ -517,29 +518,40 @@ public abstract class AbstractActivityView extends LocatableVLayout implements R
//time range filter. Check for enabled and then persist property. Dealing with compound widget.
FormItem item = measurementRangeEditor.getItem(CustomConfigMeasurementRangeEditor.ENABLE_RANGE_ITEM);
CheckboxItem itemC = (CheckboxItem) item;
- selectedValue = String.valueOf(itemC.getValueAsBoolean());
- if (!selectedValue.trim().isEmpty()) {//then call
- portletConfig.put(new PropertySimple(Constant.METRIC_RANGE_ENABLE, selectedValue));
- }
-
- //time advanced time filter enabled.
- boolean isAdvanceTimeSetting = false;
- selectedValue = String.valueOf(measurementRangeEditor.isAdvanced());
- if ((selectedValue != null) && (!selectedValue.trim().isEmpty())) {
- portletConfig.put(new PropertySimple(Constant.METRIC_RANGE_BEGIN_END_FLAG, selectedValue));
- isAdvanceTimeSetting = Boolean.valueOf(selectedValue);
- }
-
- //time frame
- List<Long> begEnd = measurementRangeEditor.getBeginEndTimes();
- if (isAdvanceTimeSetting) {//advanced settings
- portletConfig.put(new PropertySimple(Constant.METRIC_RANGE, (begEnd.get(0) + "," + begEnd.get(1))));
- } else {
- //save not advanced time range
- portletConfig.put(new PropertySimple(Constant.METRIC_RANGE_LASTN, measurementRangeEditor
- .getMetricRangePreferences().lastN));
- portletConfig.put(new PropertySimple(Constant.METRIC_RANGE_UNIT, measurementRangeEditor
- .getMetricRangePreferences().unit));
+ boolean persistTimeRangeSettings = itemC.getValueAsBoolean();
+ if (persistTimeRangeSettings) {//retrieve values and persist
+ selectedValue = String.valueOf(itemC.getValueAsBoolean());
+ if (!selectedValue.trim().isEmpty()) {//then call
+ portletConfig.put(new PropertySimple(Constant.METRIC_RANGE_ENABLE, selectedValue));
+ }
+
+ //time advanced time filter enabled.
+ boolean isAdvanceTimeSetting = false;
+ selectedValue = String.valueOf(measurementRangeEditor.isAdvanced());
+ if ((selectedValue != null) && (!selectedValue.trim().isEmpty())) {
+ portletConfig.put(new PropertySimple(Constant.METRIC_RANGE_BEGIN_END_FLAG, selectedValue));
+ isAdvanceTimeSetting = Boolean.valueOf(selectedValue);
+ }
+
+ //time frame
+ List<Long> begEnd = measurementRangeEditor.getBeginEndTimes();
+ if (isAdvanceTimeSetting) {//advanced settings
+ portletConfig.put(new PropertySimple(Constant.METRIC_RANGE, (begEnd.get(0) + "," + begEnd.get(1))));
+ } else {
+ //save not advanced time range
+ portletConfig.put(new PropertySimple(Constant.METRIC_RANGE_LASTN, measurementRangeEditor
+ .getMetricRangePreferences().lastN));
+ portletConfig.put(new PropertySimple(Constant.METRIC_RANGE_UNIT, measurementRangeEditor
+ .getMetricRangePreferences().unit));
+ }
+ } else {//if disabled, reset time defaults
+ portletConfig.put(new PropertySimple(Constant.METRIC_RANGE_ENABLE, false));
+ portletConfig.put(new PropertySimple(Constant.METRIC_RANGE_BEGIN_END_FLAG, false));
+ List<Long> rangeArray = MeasurementUtility.calculateTimeFrame(Integer
+ .valueOf(Constant.METRIC_RANGE_LASTN_DEFAULT), Integer.valueOf(Constant.METRIC_RANGE_UNIT_DEFAULT));
+ // String[] range = {String.valueOf(rangeArray.get(0)),String.valueOf(rangeArray.get(1))};
+ portletConfig.put(new PropertySimple(Constant.METRIC_RANGE,
+ (String.valueOf(rangeArray.get(0)) + "," + String.valueOf(rangeArray.get(1)))));
}
}
return portletConfig;
commit e581e677447f29be3be27fedf9849284e299c1b4
Author: Simeon Pinder <spinder(a)redhat.com>
Date: Sat Mar 19 21:18:13 2011 -0400
i)edit config bug ii)fix dashboard edit mode on init iii)display messages.
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/DashboardView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/DashboardView.java
index 1d17199..a1a1c98 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/DashboardView.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/DashboardView.java
@@ -460,7 +460,6 @@ public class DashboardView extends LocatableVLayout {
this.refreshMenuButton.markForRedraw();
markForRedraw();
//attempt to initialize
- editForm.show();
editForm.markForRedraw();
markForRedraw();
}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/PortletConfigurationEditorComponent.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/PortletConfigurationEditorComponent.java
index c02f378..6eb15c4 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/PortletConfigurationEditorComponent.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/PortletConfigurationEditorComponent.java
@@ -33,6 +33,7 @@ import org.rhq.enterprise.gui.coregui.client.CoreGUI;
import org.rhq.enterprise.gui.coregui.client.ImageManager;
import org.rhq.enterprise.gui.coregui.client.Messages;
import org.rhq.enterprise.gui.coregui.client.components.measurement.CustomConfigMeasurementRangeEditor;
+import org.rhq.enterprise.gui.coregui.client.util.MeasurementUtility;
/** Shared portlet configuration component where initial configuration settings
* and widgets shared across portlet editors is defined.
@@ -51,6 +52,7 @@ public class PortletConfigurationEditorComponent {
String METRIC_RANGE_LASTN = "METRIC_RANGE_LASTN";
String METRIC_RANGE_LASTN_DEFAULT = String.valueOf(8);
String METRIC_RANGE_UNIT = "METRIC_RANGE_UNIT";
+ String METRIC_RANGE_UNIT_DEFAULT = String.valueOf(MeasurementUtility.UNIT_HOURS);
String RESULT_SEVERITY = "severities";
String RESULT_SORT_ORDER = "RESULT_SORT_ORDER";
String RESULT_SORT_PRIORITY = "sort.priority";
@@ -75,6 +77,8 @@ public class PortletConfigurationEditorComponent {
CONFIG_PROPERTY_INITIALIZATION.put(Constant.METRIC_RANGE_BEGIN_END_FLAG, String.valueOf(false));
//whether in simple mode. Ex. 8 hrs. Defaults to 8
CONFIG_PROPERTY_INITIALIZATION.put(Constant.METRIC_RANGE_LASTN, Constant.METRIC_RANGE_LASTN_DEFAULT);
+ //whether in simple mode. Ex. 8 hrs. Defaults to 8
+ CONFIG_PROPERTY_INITIALIZATION.put(Constant.METRIC_RANGE_UNIT, Constant.METRIC_RANGE_UNIT_DEFAULT);
//operation status, if empty initialize to "" i.e. all stati
CONFIG_PROPERTY_INITIALIZATION.put(Constant.OPERATION_STATUS, "");
}
diff --git a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages.properties b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages.properties
index 2e37d6c..aebcd71 100644
--- a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages.properties
+++ b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages.properties
@@ -1472,7 +1472,7 @@ view_portlet_defaultName_resource_pkg_hisory = Resource: Package History
view_portlet_help_autodiscovery = This portlet allows import or ignore of newly discovered resources. Imported resources are added to inventory for monitoring and management. Ignored resources are not imported and are hidden from view unless explicitly unignored.
view_portlet_help_bundle_deps = This portlet shows relevant bundle deployments based on display criteria configured.
-view_portlet_help_eventcounts = This portlet displays Event counts based consistent with display criteria configured.
+view_portlet_help_eventcounts = This portlet displays Event counts consistent with display criteria configured.
view_portlet_help_favoriteResources = This portlet displays the current user''s favorite resources.
view_portlet_help_graph = This portlet displays the resource metric graph.
view_portlet_help_inventorySummary = This portlet displays a short summary of the current user''s viewable inventory and metric collection rate.
commit 4fc496a1cf495e44ed2cd19a21f2d69998c23031
Author: Simeon Pinder <spinder(a)redhat.com>
Date: Sat Mar 19 19:28:35 2011 -0400
define default portlet ordering for res and group portlets.
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/summary/ActivityView2.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/summary/ActivityView2.java
index 5f2de37..af8d09c 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/summary/ActivityView2.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/summary/ActivityView2.java
@@ -18,6 +18,7 @@
*/
package org.rhq.enterprise.gui.coregui.client.inventory.groups.detail.summary;
+import java.util.HashMap;
import java.util.Set;
import com.google.gwt.user.client.rpc.AsyncCallback;
@@ -45,7 +46,10 @@ import org.rhq.enterprise.gui.coregui.client.PermissionsLoader;
import org.rhq.enterprise.gui.coregui.client.UserSessionManager;
import org.rhq.enterprise.gui.coregui.client.dashboard.DashboardContainer;
import org.rhq.enterprise.gui.coregui.client.dashboard.DashboardView;
-import org.rhq.enterprise.gui.coregui.client.dashboard.portlets.util.MessagePortlet;
+import org.rhq.enterprise.gui.coregui.client.dashboard.PortletFactory;
+import org.rhq.enterprise.gui.coregui.client.dashboard.portlets.groups.GroupAlertsPortlet;
+import org.rhq.enterprise.gui.coregui.client.dashboard.portlets.groups.GroupMetricsPortlet;
+import org.rhq.enterprise.gui.coregui.client.dashboard.portlets.groups.GroupOperationsPortlet;
import org.rhq.enterprise.gui.coregui.client.gwt.DashboardGWTServiceAsync;
import org.rhq.enterprise.gui.coregui.client.gwt.GWTServiceLookup;
import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableIButton;
@@ -180,25 +184,52 @@ public class ActivityView2 extends LocatableVLayout implements DashboardContaine
dashboard.setGroup(group);
dashboard.setColumns(2);
- // TODO, add real portlets
// set leftmost column and let the rest be equally divided
dashboard.setColumnWidths("40%");
dashboard.getConfiguration().put(new PropertySimple(Dashboard.CFG_BACKGROUND, "#F1F2F3"));
- // Left Column
- // DashboardPortlet dummyLeft = new DashboardPortlet(MessagePortlet.NAME, MessagePortlet.KEY, 220);
- // dummyLeft.getConfiguration().put(new PropertySimple("message", "<br/>Coming Soon... :-)"));
- // dashboard.addPortlet(dummyLeft, 0, 0);
-
- // DashboardPortlet groupAlerts = new DashboardPortlet(GroupAlertsPortlet3.NAME, GroupAlertsPortlet3.KEY, 220);
- // groupAlerts.getConfiguration().put(new PropertySimple("message", "<br/>Coming Soon... :-)"));
- // dashboard.addPortlet(groupAlerts, 0, 0);
+ //figure out which portlets to display and how
+ HashMap<String, String> groupKeyNameMap = PortletFactory.getRegisteredGroupPortletNameMap();
+ groupKeyNameMap = DashboardView.processPortletNameMapForGroup(groupKeyNameMap, groupComposite);
+ int colLeft = 0;
+ int colRight = 1;
+ int rowLeft = 0;
+ int rowRight = 0;
+ //Left Column
+ if (groupKeyNameMap.containsKey(GroupMetricsPortlet.KEY)) {//measurments top left if available
+ DashboardPortlet measurements = new DashboardPortlet(GroupMetricsPortlet.NAME, GroupMetricsPortlet.KEY, 220);
+ dashboard.addPortlet(measurements, colLeft, rowLeft++);
+ groupKeyNameMap.remove(GroupMetricsPortlet.KEY);
+ }
- // right Column
- DashboardPortlet dummyRight = new DashboardPortlet(MessagePortlet.NAME, MessagePortlet.KEY, 220);
- dummyRight.getConfiguration().put(new PropertySimple("message", "<br/>Coming Soon... :-)"));
- dashboard.addPortlet(dummyRight, 1, 0);
+ // right Column(approx 60%. As larger more room to display table and N rows.)
+ if (groupKeyNameMap.containsKey(GroupAlertsPortlet.KEY)) {//alerts top right if available
+ DashboardPortlet alerts = new DashboardPortlet(GroupAlertsPortlet.NAME, GroupAlertsPortlet.KEY, 220);
+ dashboard.addPortlet(alerts, colRight, rowRight++);
+ groupKeyNameMap.remove(GroupAlertsPortlet.KEY);
+ }
+ if (groupKeyNameMap.containsKey(GroupOperationsPortlet.KEY)) {//operations if available
+ DashboardPortlet ops = new DashboardPortlet(GroupOperationsPortlet.NAME, GroupOperationsPortlet.KEY, 220);
+ dashboard.addPortlet(ops, colRight, rowRight++);
+ groupKeyNameMap.remove(GroupOperationsPortlet.KEY);
+ }
+ //Fill out left column(typically smaller portlets) then alternate cols with remaining
+ boolean displayLeft = false;
+ for (String key : groupKeyNameMap.keySet()) {
+ DashboardPortlet portlet = new DashboardPortlet(groupKeyNameMap.get(key), key, 100);
+ if (rowLeft < 4) {
+ dashboard.addPortlet(portlet, colLeft, rowLeft++);
+ } else {//alternate
+ if (!displayLeft) {
+ dashboard.addPortlet(portlet, colRight, rowRight++);
+ } else {
+ dashboard.addPortlet(portlet, colLeft, rowLeft++);
+ }
+ //toggle
+ displayLeft = !displayLeft;
+ }
+ }
return dashboard;
}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/Activity2View.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/Activity2View.java
index 20b5e65..ad6e607 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/Activity2View.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/Activity2View.java
@@ -1,5 +1,6 @@
package org.rhq.enterprise.gui.coregui.client.inventory.resource.detail.summary;
+import java.util.HashMap;
import java.util.Set;
import com.google.gwt.user.client.rpc.AsyncCallback;
@@ -27,7 +28,10 @@ import org.rhq.enterprise.gui.coregui.client.PermissionsLoader;
import org.rhq.enterprise.gui.coregui.client.UserSessionManager;
import org.rhq.enterprise.gui.coregui.client.dashboard.DashboardContainer;
import org.rhq.enterprise.gui.coregui.client.dashboard.DashboardView;
-import org.rhq.enterprise.gui.coregui.client.dashboard.portlets.util.MessagePortlet;
+import org.rhq.enterprise.gui.coregui.client.dashboard.PortletFactory;
+import org.rhq.enterprise.gui.coregui.client.dashboard.portlets.resource.ResourceAlertsPortlet;
+import org.rhq.enterprise.gui.coregui.client.dashboard.portlets.resource.ResourceMetricsPortlet;
+import org.rhq.enterprise.gui.coregui.client.dashboard.portlets.resource.ResourceOperationsPortlet;
import org.rhq.enterprise.gui.coregui.client.gwt.DashboardGWTServiceAsync;
import org.rhq.enterprise.gui.coregui.client.gwt.GWTServiceLookup;
import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableIButton;
@@ -167,15 +171,50 @@ public class Activity2View extends LocatableVLayout implements DashboardContaine
dashboard.setColumnWidths("40%");
dashboard.getConfiguration().put(new PropertySimple(Dashboard.CFG_BACKGROUND, "#F1F2F3"));
- // Left Column
- DashboardPortlet dummyLeft = new DashboardPortlet(MessagePortlet.NAME, MessagePortlet.KEY, 220);
- dummyLeft.getConfiguration().put(new PropertySimple("message", "<br/>Coming Soon... :-)"));
- dashboard.addPortlet(dummyLeft, 0, 0);
+ //figure out which portlets to display and how
+ HashMap<String, String> resKeyNameMap = PortletFactory.getRegisteredResourcePortletNameMap();
+ resKeyNameMap = DashboardView.processPortletNameMapForResource(resKeyNameMap, resourceComposite);
+ int colLeft = 0;
+ int colRight = 1;
+ int rowLeft = 0;
+ int rowRight = 0;
+ //Left Column
+ if (resKeyNameMap.containsKey(ResourceMetricsPortlet.KEY)) {//measurments top left if available
+ DashboardPortlet measurements = new DashboardPortlet(ResourceMetricsPortlet.NAME,
+ ResourceMetricsPortlet.KEY, 220);
+ dashboard.addPortlet(measurements, colLeft, rowLeft++);
+ resKeyNameMap.remove(ResourceMetricsPortlet.KEY);
+ }
+
+ // right Column(approx 60%. As larger more room to display table and N rows.)
+ if (resKeyNameMap.containsKey(ResourceAlertsPortlet.KEY)) {//alerts top right if available
+ DashboardPortlet alerts = new DashboardPortlet(ResourceAlertsPortlet.NAME, ResourceAlertsPortlet.KEY, 220);
+ dashboard.addPortlet(alerts, colRight, rowRight++);
+ resKeyNameMap.remove(ResourceAlertsPortlet.KEY);
+ }
+ if (resKeyNameMap.containsKey(ResourceOperationsPortlet.KEY)) {//operations if available
+ DashboardPortlet ops = new DashboardPortlet(ResourceOperationsPortlet.NAME, ResourceOperationsPortlet.KEY,
+ 220);
+ dashboard.addPortlet(ops, colRight, rowRight++);
+ resKeyNameMap.remove(ResourceOperationsPortlet.KEY);
+ }
- // right Column
- DashboardPortlet dummyRight = new DashboardPortlet(MessagePortlet.NAME, MessagePortlet.KEY, 220);
- dummyRight.getConfiguration().put(new PropertySimple("message", "<br/>Coming Soon... :-)"));
- dashboard.addPortlet(dummyRight, 1, 0);
+ //Fill out left column(typically smaller portlets) then alternate cols with remaining
+ boolean displayLeft = false;
+ for (String key : resKeyNameMap.keySet()) {
+ DashboardPortlet portlet = new DashboardPortlet(resKeyNameMap.get(key), key, 100);
+ if (rowLeft < 4) {
+ dashboard.addPortlet(portlet, colLeft, rowLeft++);
+ } else {//alternate
+ if (!displayLeft) {
+ dashboard.addPortlet(portlet, colRight, rowRight++);
+ } else {
+ dashboard.addPortlet(portlet, colLeft, rowLeft++);
+ }
+ //toggle
+ displayLeft = !displayLeft;
+ }
+ }
return dashboard;
}
commit a5993d8891b49bbba0d897f8d44b0e3b1609b9d9
Author: Simeon Pinder <spinder(a)redhat.com>
Date: Sat Mar 19 18:45:35 2011 -0400
i)conditionally render available dash portlets based on group/resource
ii)groupEvents portlet refresh issue
iii)groupOperationsPortlet null link fix.
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/DashboardView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/DashboardView.java
index 25923ba..1d17199 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/DashboardView.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/DashboardView.java
@@ -23,6 +23,7 @@ import java.util.HashSet;
import java.util.Set;
import java.util.TreeMap;
+import com.allen_sauer.gwt.log.client.Log;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.smartgwt.client.types.Overflow;
import com.smartgwt.client.widgets.AnimationCallback;
@@ -48,14 +49,32 @@ import com.smartgwt.client.widgets.menu.events.MenuItemClickEvent;
import org.rhq.core.domain.auth.Subject;
import org.rhq.core.domain.authz.Permission;
import org.rhq.core.domain.configuration.PropertySimple;
+import org.rhq.core.domain.criteria.ResourceGroupCriteria;
import org.rhq.core.domain.dashboard.Dashboard;
import org.rhq.core.domain.dashboard.DashboardPortlet;
import org.rhq.core.domain.resource.Resource;
+import org.rhq.core.domain.resource.ResourceCategory;
+import org.rhq.core.domain.resource.ResourceTypeFacet;
+import org.rhq.core.domain.resource.composite.ResourceComposite;
+import org.rhq.core.domain.resource.group.GroupCategory;
import org.rhq.core.domain.resource.group.ResourceGroup;
+import org.rhq.core.domain.resource.group.composite.ResourceGroupComposite;
+import org.rhq.core.domain.util.PageControl;
+import org.rhq.core.domain.util.PageList;
import org.rhq.enterprise.gui.coregui.client.CoreGUI;
import org.rhq.enterprise.gui.coregui.client.ImageManager;
import org.rhq.enterprise.gui.coregui.client.UserSessionManager;
import org.rhq.enterprise.gui.coregui.client.components.form.ColorButtonItem;
+import org.rhq.enterprise.gui.coregui.client.dashboard.portlets.groups.GroupBundleDeploymentsPortlet;
+import org.rhq.enterprise.gui.coregui.client.dashboard.portlets.groups.GroupMetricsPortlet;
+import org.rhq.enterprise.gui.coregui.client.dashboard.portlets.groups.GroupOobsPortlet;
+import org.rhq.enterprise.gui.coregui.client.dashboard.portlets.groups.GroupOperationsPortlet;
+import org.rhq.enterprise.gui.coregui.client.dashboard.portlets.groups.GroupPkgHistoryPortlet;
+import org.rhq.enterprise.gui.coregui.client.dashboard.portlets.resource.ResourceBundleDeploymentsPortlet;
+import org.rhq.enterprise.gui.coregui.client.dashboard.portlets.resource.ResourceEventsPortlet;
+import org.rhq.enterprise.gui.coregui.client.dashboard.portlets.resource.ResourceMetricsPortlet;
+import org.rhq.enterprise.gui.coregui.client.dashboard.portlets.resource.ResourceOperationsPortlet;
+import org.rhq.enterprise.gui.coregui.client.dashboard.portlets.resource.ResourcePkgHistoryPortlet;
import org.rhq.enterprise.gui.coregui.client.gwt.GWTServiceLookup;
import org.rhq.enterprise.gui.coregui.client.util.message.Message;
import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableDynamicForm;
@@ -94,8 +113,10 @@ public class DashboardView extends LocatableVLayout {
private int refreshInterval = 0;
private LocatableIMenuButton refreshMenuButton;
private HashMap<String, PortletViewFactory> portletMap = null;
- private ResourceGroup focusGroup = null;
- private Resource focusResource = null;
+ private ResourceGroup group = null;
+ private ResourceGroupComposite groupComposite = null;
+ private Resource resource = null;
+ private ResourceComposite resourceComposite = null;
// this is used to prevent an odd smartgwt problem where onInit() can get called multiple times if
// the view is set to a Tab's pane.
@@ -109,10 +130,16 @@ public class DashboardView extends LocatableVLayout {
}
public DashboardView(String locatorId, DashboardContainer dashboardContainer, Dashboard storedDashboard,
- ResourceGroup group, Resource resource) {
+ ResourceGroupComposite groupCompositeValue, ResourceComposite resourceCompositeValue) {
this(locatorId, dashboardContainer, storedDashboard);
- this.focusGroup = group;
- this.focusResource = resource;
+ groupComposite = groupCompositeValue;
+ if (groupComposite != null) {
+ group = groupCompositeValue.getResourceGroup();
+ }
+ resourceComposite = resourceCompositeValue;
+ if (resourceComposite != null) {
+ resource = resourceComposite.getResource();
+ }
}
@Override
@@ -167,10 +194,62 @@ public class DashboardView extends LocatableVLayout {
private DynamicForm buildEditForm() {
editForm = new LocatableDynamicForm(extendLocatorId("Editor"));
+ final HashMap<String, String> groupKeyNameMap = PortletFactory.getRegisteredGroupPortletNameMap();
+ //remove BundleDeployment and add back later if relevant.
+ groupKeyNameMap.remove(GroupBundleDeploymentsPortlet.KEY);
+ //if group, need to do asynch check for bundlePortlet to ensure only Platform members
+ if (groupComposite != null) {
+ final ResourceGroup group = groupComposite.getResourceGroup();
+ ResourceGroupCriteria criteria = new ResourceGroupCriteria();
+ criteria.addFilterId(group.getId());
+ criteria.fetchExplicitResources(true);
+ criteria.setPageControl(new PageControl(0, 1));
+ GWTServiceLookup.getResourceGroupService().findResourceGroupsByCriteria(criteria,
+ new AsyncCallback<PageList<ResourceGroup>>() {
+ @Override
+ public void onSuccess(PageList<ResourceGroup> results) {
+ if (!results.isEmpty()) {
+ ResourceGroup grp = results.get(0);
+ Set<Resource> explicitMembers = grp.getExplicitResources();
+ Resource[] currentResources = new Resource[explicitMembers.size()];
+ explicitMembers.toArray(currentResources);
+ //membership dynamically determined if all platforms then will be compatible.
+ if (group.getGroupCategory().equals(GroupCategory.COMPATIBLE)) {
+ if (currentResources[0].getResourceType().getCategory().equals(
+ ResourceCategory.PLATFORM)) {
+ //this portlet allowed to add bundle portlet monitoring
+ groupKeyNameMap.put(GroupBundleDeploymentsPortlet.KEY,
+ GroupBundleDeploymentsPortlet.NAME);
+ }
+ }
+ }
+ //now complet populating of portlet edit form.
+ populateBuildEditForm(groupKeyNameMap);
+ }
+
+ @Override
+ public void onFailure(Throwable caught) {
+ Log.debug("Error retrieving information for group [" + group.getId() + "]:"
+ + caught.getMessage());
+ }
+ });
+
+ } else {//otherwise default groupKeyNameMap is sufficient as won't be used.
+ populateBuildEditForm(groupKeyNameMap);
+ }
+
+ return editForm;
+ }
+
+ /** Responsible for populating the edit form widget.
+ * groupKepNameMap is updated for bundles.
+ *
+ * @param groupKeyNameMap
+ */
+ private void populateBuildEditForm(HashMap<String, String> groupKeyNameMap) {
editForm.setMargin(5);
editForm.setAutoWidth();
editForm.setNumCols(canEditName() ? 12 : 10);
-
TextItem nameItem = null;
if (dashboardContainer.supportsDashboardNameEdit()) {
@@ -232,47 +311,40 @@ public class DashboardView extends LocatableVLayout {
}
});
- Menu addPortletMenu = new LocatableMenu(editForm.extendLocatorId("PortletMenu"));
+ final Menu addPortletMenu = new LocatableMenu(editForm.extendLocatorId("PortletMenu"));
HashMap<String, String> keyNameMap = PortletFactory.getRegisteredPortletNameMap();
// the assumption here is that the portlet names are unique. we want a sorted menu here, so create a
// sorted map from portlet name to portlet key and use that to generate the menu. It would be nice if you
// could just call Menu.sort() but it's not supported (yet?).
- TreeMap<String, String> nameKeyMap = new TreeMap<String, String>();
+ final TreeMap<String, String> nameKeyMap = new TreeMap<String, String>();
for (String portletKey : keyNameMap.keySet()) {
nameKeyMap.put(keyNameMap.get(portletKey), portletKey);
}
- //if resourceGroup passed in then add additional portlets to list
- if (this.focusGroup != null) {
- HashMap<String, String> groupKeyNameMap = PortletFactory.getRegisteredGroupPortletNameMap();
- // //find current list of portlets already stored. Exclude them
- // for (DashboardPortlet currentPortlet : storedDashboard.getPortlets()) {
- // if (groupKeyNameMap.containsKey(currentPortlet.getPortletKey())) {
- // groupKeyNameMap.remove(currentPortlet.getPortletKey());
- // }
- // }
-
- //TODO: spinder 3/16/11: still need to be done.
+
+ //if resourceGroup passed in then upate portlets list depending on grouptype and facets
+ if (this.group != null) {
+
//filter out portlets not relevent for group(compat|mixed) or facets
+ groupKeyNameMap = processPortletNameMapForGroup(groupKeyNameMap, this.groupComposite);
+
+ //add to default list of portlets.
for (String portletKey : groupKeyNameMap.keySet()) {
nameKeyMap.put(groupKeyNameMap.get(portletKey), portletKey);
}
}
+ HashMap<String, String> resourceKeyNameMap = PortletFactory.getRegisteredResourcePortletNameMap();
//if resource passed in then add additional portlets to list
- if (this.focusResource != null) {
- HashMap<String, String> resourceKeyNameMap = PortletFactory.getRegisteredResourcePortletNameMap();
- // //find current list of portlets already stored. Exclude them
- // for (DashboardPortlet currentPortlet : storedDashboard.getPortlets()) {
- // if (resourceKeyNameMap.containsKey(currentPortlet.getPortletKey())) {
- // resourceKeyNameMap.remove(currentPortlet.getPortletKey());
- // }
- // }
+ if (this.resource != null) {
+ //trim out portlets that should not be visible
+ resourceKeyNameMap = processPortletNameMapForResource(resourceKeyNameMap, this.resourceComposite);
for (String portletKey : resourceKeyNameMap.keySet()) {
nameKeyMap.put(resourceKeyNameMap.get(portletKey), portletKey);
}
}
+ //build the addPortlet Menu item
// now use the reversed map for the menu generation
for (String portletName : nameKeyMap.keySet()) {
MenuItem menuItem = new MenuItem(portletName);
@@ -387,8 +459,82 @@ public class DashboardView extends LocatableVLayout {
updateRefreshMenu();
this.refreshMenuButton.markForRedraw();
markForRedraw();
+ //attempt to initialize
+ editForm.show();
+ editForm.markForRedraw();
+ markForRedraw();
+ }
- return editForm;
+ /**Process the portletName map to exclude portlets that should not be visible for this
+ * resource.
+ */
+ public static HashMap<String, String> processPortletNameMapForResource(HashMap<String, String> resourceKeyNameMap,
+ ResourceComposite composite) {
+ if ((composite != null) && (composite.getResource() != null) && (resourceKeyNameMap != null)
+ && !resourceKeyNameMap.isEmpty()) {
+ Resource resource = composite.getResource();
+ //filter out portlets not relevent for facets
+ Set<ResourceTypeFacet> facets = composite.getResourceFacets().getFacets();
+ //Operation related portlets
+ if (!facets.contains(ResourceTypeFacet.OPERATION)) {
+ resourceKeyNameMap.remove(ResourceOperationsPortlet.KEY);
+ }
+ //MEASUREMENT related portlets(METRICS)
+ if (!facets.contains(ResourceTypeFacet.MEASUREMENT)) {
+ resourceKeyNameMap.remove(ResourceMetricsPortlet.KEY);
+ resourceKeyNameMap.remove(ResourceMetricsPortlet.KEY);
+ }
+ //Content related portlets
+ if (!facets.contains(ResourceTypeFacet.CONTENT)) {
+ resourceKeyNameMap.remove(ResourcePkgHistoryPortlet.KEY);
+ }
+ //Event related portlets
+ if (!facets.contains(ResourceTypeFacet.EVENT)) {
+ resourceKeyNameMap.remove(ResourceEventsPortlet.KEY);
+ }
+ //Bundle related portlet
+ if (!resource.getResourceType().getCategory().equals(ResourceCategory.PLATFORM)) {
+ resourceKeyNameMap.remove(ResourceBundleDeploymentsPortlet.KEY);
+ }
+ }
+ return resourceKeyNameMap;
+ }
+
+ /**Process the portletName map to exclude portlets that should not be visible for this
+ * group. All except BundleDeployment visibility is handled here. Bundle requires runtime check.
+ */
+ public static HashMap<String, String> processPortletNameMapForGroup(HashMap<String, String> groupKeyNameMap,
+ ResourceGroupComposite composite) {
+ if ((composite != null) && (composite.getResourceGroup() != null) && (groupKeyNameMap != null)
+ && !groupKeyNameMap.isEmpty()) {
+
+ //filter out portlets not relevent for facets
+ Set<ResourceTypeFacet> facets = composite.getResourceFacets().getFacets();
+ GroupCategory groupCategory = composite.getResourceGroup().getGroupCategory();
+ // ResourceGroup group = composite.getResourceGroup();
+ //compatible if not a compatible group may need to do some pruning.
+ if (groupCategory != GroupCategory.COMPATIBLE) {
+ //Operations related portlets(Config,PkgHistory)
+ if (!facets.contains(ResourceTypeFacet.OPERATION)) {
+ groupKeyNameMap.remove(GroupOperationsPortlet.KEY);
+ }
+ //MEASUREMENT related portlets(METRICS)
+ if (!facets.contains(ResourceTypeFacet.MEASUREMENT)) {
+ groupKeyNameMap.remove(GroupMetricsPortlet.KEY);
+ groupKeyNameMap.remove(GroupOobsPortlet.KEY);
+ }
+ //CONTENT related portlets(CONTENT)
+ if (!facets.contains(ResourceTypeFacet.CONTENT)) {
+ groupKeyNameMap.remove(GroupPkgHistoryPortlet.KEY);
+ }
+ // //EVENT related portlets
+ // if (!facets.contains(ResourceTypeFacet.EVENT)) {
+ // groupKeyNameMap.remove(GroupEventsPortlet.KEY);
+ // }
+
+ }
+ }
+ return groupKeyNameMap;
}
private void loadPortletWindows() {
@@ -671,6 +817,7 @@ public class DashboardView extends LocatableVLayout {
this.editMode = editMode;
if (editMode) {
this.editForm.show();
+ //
} else {
this.editForm.hide();
}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/groups/GroupEventsPortlet.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/groups/GroupEventsPortlet.java
index 636a844..2ee782e 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/groups/GroupEventsPortlet.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/groups/GroupEventsPortlet.java
@@ -266,6 +266,7 @@ public class GroupEventsPortlet extends LocatableVLayout implements CustomSettin
}
recentEventsContent.addChild(column);
recentEventsContent.markForRedraw();
+ markForRedraw();
}
});
}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/groups/GroupOperationsPortlet.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/groups/GroupOperationsPortlet.java
index d840bcc..0e2e00c 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/groups/GroupOperationsPortlet.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/groups/GroupOperationsPortlet.java
@@ -348,10 +348,13 @@ public class GroupOperationsPortlet extends LocatableVLayout implements CustomSe
*/
class GroupOperationsCriteriaHistoryListView extends GroupOperationHistoryListView {
+ private ResourceGroupComposite composite;
+
public GroupOperationsCriteriaHistoryListView(String locatorId, AbstractOperationHistoryDataSource dataSource,
String title, Criteria criteria, ResourceGroupComposite composite) {
super(locatorId, composite);
setDataSource(dataSource);
+ this.composite = composite;
setShowFooterRefresh(false); //disable footer refresh
}
@@ -368,6 +371,11 @@ class GroupOperationsCriteriaHistoryListView extends GroupOperationHistoryListVi
MSG.view_table_matchingRows(String.valueOf(getListGrid().getTotalRows()), String.valueOf(count)));
}
}
+
+ @Override
+ protected String getBasePath() {
+ return "ResourceGroup/" + composite.getResourceGroup().getId() + "/Operations/History";
+ }
}
/** Provide implementation of GroupOperationHistoryDataSource that dynamically
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/resource/ResourceBundleDeploymentsPortlet.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/resource/ResourceBundleDeploymentsPortlet.java
index 3ce4561..3cb8256 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/resource/ResourceBundleDeploymentsPortlet.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/resource/ResourceBundleDeploymentsPortlet.java
@@ -163,6 +163,7 @@ public class ResourceBundleDeploymentsPortlet extends GroupBundleDeploymentsPort
for (Canvas child : recentBundleDeployContent.getChildren()) {
child.destroy();
}
+ column.markForRedraw();
recentBundleDeployContent.addChild(column);
recentBundleDeployContent.markForRedraw();
markForRedraw();
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/detail/summary/AbstractActivityView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/detail/summary/AbstractActivityView.java
index f9fae66..c67dce9 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/detail/summary/AbstractActivityView.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/detail/summary/AbstractActivityView.java
@@ -156,7 +156,6 @@ public abstract class AbstractActivityView extends LocatableVLayout implements R
Set<ResourceTypeFacet> resourceFacets = null;
if ((groupComposite != null) && (groupComposite.getResourceGroup() != null)) {
group = groupComposite.getResourceGroup();
- group = groupComposite.getResourceGroup();
groupCategory = groupComposite.getResourceGroup().getGroupCategory();
facets = groupComposite.getResourceFacets().getFacets();
}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/summary/ActivityView2.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/summary/ActivityView2.java
index c57b591..5f2de37 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/summary/ActivityView2.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/summary/ActivityView2.java
@@ -125,10 +125,8 @@ public class ActivityView2 extends LocatableVLayout implements DashboardContaine
private void setDashboard(Dashboard dashboard) {
Canvas[] members = getMembers();
removeMembers(members);
-
//pass in the group information
- dashboardView = new DashboardView(extendLocatorId(dashboard.getName()), this, dashboard, this.groupComposite
- .getResourceGroup(), null);
+ dashboardView = new DashboardView(extendLocatorId(dashboard.getName()), this, dashboard, groupComposite, null);
addMember(dashboardView);
footer = new LocatableToolStrip(extendLocatorId("Footer"));
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/Activity2View.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/Activity2View.java
index 867251f..20b5e65 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/Activity2View.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/Activity2View.java
@@ -106,10 +106,9 @@ public class Activity2View extends LocatableVLayout implements DashboardContaine
private void setDashboard(Dashboard dashboard) {
Canvas[] members = getMembers();
removeMembers(members);
-
//pass in the resource information
dashboardView = new DashboardView(extendLocatorId(dashboard.getName()), this, dashboard, null,
- this.resourceComposite.getResource());
+ resourceComposite);
addMember(dashboardView);
footer = new LocatableToolStrip(extendLocatorId("Footer"));
diff --git a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages.properties b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages.properties
index 9d9da4f..2e37d6c 100644
--- a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages.properties
+++ b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages.properties
@@ -1459,13 +1459,13 @@ view_portlet_defaultName_group_alerts =Group: Alerts
view_portlet_defaultName_group_bundles = Group: Bundle Deployments
view_portlet_defaultName_group_events = Group: Event Counts
view_portlet_defaultName_group_metrics = Group: Metrics
-view_portlet_defaultName_group_oobs = Group: OOB Metrics
+view_portlet_defaultName_group_oobs = Group: OOB Conditions
view_portlet_defaultName_group_operations = Group: Operations
view_portlet_defaultName_group_pkg_hisory = Group: Package History
view_portlet_defaultName_resource_alerts = Resource: Alerts
view_portlet_defaultName_resource_bundles = Resource: Bundle Deployments
view_portlet_defaultName_resource_events = Resource: Event Counts
-view_portlet_defaultName_resource_metrics = Resource: Metrics
+view_portlet_defaultName_resource_metrics = Resource: Measurements
view_portlet_defaultName_resource_oobs = Resource: OOB Metrics
view_portlet_defaultName_resource_operations = Resource: Operations
view_portlet_defaultName_resource_pkg_hisory = Resource: Package History
commit d95526648b72a4f82620a1cda714e820dbba1dbf
Author: Simeon Pinder <spinder(a)redhat.com>
Date: Fri Mar 18 08:34:45 2011 -0400
some portlet cleanup.
i)get rid of (non-table) GroupAlerts portlet
ii)rename tabular GroupAlerts portlet
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/PortletFactory.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/PortletFactory.java
index aa63d77..b8d2ddc 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/PortletFactory.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/PortletFactory.java
@@ -24,7 +24,7 @@ import java.util.List;
import org.rhq.core.domain.dashboard.DashboardPortlet;
import org.rhq.enterprise.gui.coregui.client.ImageManager;
-import org.rhq.enterprise.gui.coregui.client.dashboard.portlets.groups.GroupAlertsPortlet2;
+import org.rhq.enterprise.gui.coregui.client.dashboard.portlets.groups.GroupAlertsPortlet;
import org.rhq.enterprise.gui.coregui.client.dashboard.portlets.groups.GroupBundleDeploymentsPortlet;
import org.rhq.enterprise.gui.coregui.client.dashboard.portlets.groups.GroupEventsPortlet;
import org.rhq.enterprise.gui.coregui.client.dashboard.portlets.groups.GroupMetricsPortlet;
@@ -104,8 +104,7 @@ public class PortletFactory {
//############## Group Activity Dashboard ############################################
//defines mapping for Group Activity Dashboard
registeredGroupPortletFactoryMap = new HashMap<String, PortletViewFactory>();
- // registeredGroupPortletFactoryMap.put(GroupAlertsPortlet.KEY, GroupAlertsPortlet.Factory.INSTANCE);
- registeredGroupPortletFactoryMap.put(GroupAlertsPortlet2.KEY, GroupAlertsPortlet2.Factory.INSTANCE);
+ registeredGroupPortletFactoryMap.put(GroupAlertsPortlet.KEY, GroupAlertsPortlet.Factory.INSTANCE);
registeredGroupPortletFactoryMap.put(GroupMetricsPortlet.KEY, GroupMetricsPortlet.Factory.INSTANCE);
registeredGroupPortletFactoryMap.put(GroupOobsPortlet.KEY, GroupOobsPortlet.Factory.INSTANCE);
registeredGroupPortletFactoryMap.put(GroupEventsPortlet.KEY, GroupEventsPortlet.Factory.INSTANCE);
@@ -116,8 +115,7 @@ public class PortletFactory {
//register group portlet names
registeredGroupPortletNameMap = new HashMap<String, String>(registeredGroupPortletFactoryMap.size());
- // registeredGroupPortletNameMap.put(GroupAlertsPortlet.KEY, GroupAlertsPortlet.NAME);
- registeredGroupPortletNameMap.put(GroupAlertsPortlet2.KEY, GroupAlertsPortlet2.NAME);
+ registeredGroupPortletNameMap.put(GroupAlertsPortlet.KEY, GroupAlertsPortlet.NAME);
registeredGroupPortletNameMap.put(GroupMetricsPortlet.KEY, GroupMetricsPortlet.NAME);
registeredGroupPortletNameMap.put(GroupOobsPortlet.KEY, GroupOobsPortlet.NAME);
registeredGroupPortletNameMap.put(GroupEventsPortlet.KEY, GroupEventsPortlet.NAME);
@@ -153,8 +151,7 @@ public class PortletFactory {
//############## Portlet icon mappings ############################################
//register portlet names
registeredPortletIconMap = new HashMap<String, String>(registeredPortletFactoryMap.size());
- // registeredPortletIconMap.put(GroupAlertsPortlet.KEY, ImageManager.getAlertIcon());
- registeredPortletIconMap.put(GroupAlertsPortlet2.KEY, ImageManager.getAlertIcon());
+ registeredPortletIconMap.put(GroupAlertsPortlet.KEY, ImageManager.getAlertIcon());
registeredPortletIconMap.put(ResourceAlertsPortlet.KEY, ImageManager.getAlertIcon());
registeredPortletIconMap.put(GroupMetricsPortlet.KEY, ImageManager.getMonitorIcon());
registeredPortletIconMap.put(ResourceMetricsPortlet.KEY, ImageManager.getMonitorIcon());
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/groups/GroupAlertsPortlet.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/groups/GroupAlertsPortlet.java
index 483d858..120c974 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/groups/GroupAlertsPortlet.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/groups/GroupAlertsPortlet.java
@@ -18,35 +18,35 @@
*/
package org.rhq.enterprise.gui.coregui.client.dashboard.portlets.groups;
-import java.util.List;
+import java.util.HashMap;
+import java.util.Set;
-import com.allen_sauer.gwt.log.client.Log;
import com.google.gwt.user.client.History;
import com.google.gwt.user.client.Timer;
-import com.google.gwt.user.client.rpc.AsyncCallback;
+import com.smartgwt.client.types.Overflow;
import com.smartgwt.client.widgets.Canvas;
import com.smartgwt.client.widgets.HTMLFlow;
+import com.smartgwt.client.widgets.events.DoubleClickEvent;
+import com.smartgwt.client.widgets.events.DoubleClickHandler;
import com.smartgwt.client.widgets.form.DynamicForm;
import com.smartgwt.client.widgets.form.events.SubmitValuesEvent;
import com.smartgwt.client.widgets.form.events.SubmitValuesHandler;
-import com.smartgwt.client.widgets.form.fields.CheckboxItem;
-import com.smartgwt.client.widgets.form.fields.FormItem;
-import com.smartgwt.client.widgets.form.fields.LinkItem;
import com.smartgwt.client.widgets.form.fields.SelectItem;
-import com.smartgwt.client.widgets.form.fields.StaticTextItem;
-import com.smartgwt.client.widgets.layout.VLayout;
+import com.smartgwt.client.widgets.grid.CellFormatter;
+import com.smartgwt.client.widgets.grid.ListGrid;
+import com.smartgwt.client.widgets.grid.ListGridRecord;
-import org.rhq.core.domain.alert.Alert;
-import org.rhq.core.domain.alert.AlertPriority;
+import org.rhq.core.domain.authz.Permission;
import org.rhq.core.domain.configuration.Configuration;
import org.rhq.core.domain.configuration.PropertySimple;
-import org.rhq.core.domain.criteria.AlertCriteria;
import org.rhq.core.domain.dashboard.DashboardPortlet;
-import org.rhq.core.domain.util.PageControl;
-import org.rhq.core.domain.util.PageList;
-import org.rhq.core.domain.util.PageOrdering;
-import org.rhq.enterprise.gui.coregui.client.ImageManager;
+import org.rhq.core.domain.resource.ResourceType;
+import org.rhq.enterprise.gui.coregui.client.CoreGUI;
+import org.rhq.enterprise.gui.coregui.client.LinkManager;
+import org.rhq.enterprise.gui.coregui.client.Messages;
import org.rhq.enterprise.gui.coregui.client.UserSessionManager;
+import org.rhq.enterprise.gui.coregui.client.alert.AlertHistoryView;
+import org.rhq.enterprise.gui.coregui.client.alert.AlertPortletConfigurationDataSource;
import org.rhq.enterprise.gui.coregui.client.components.measurement.CustomConfigMeasurementRangeEditor;
import org.rhq.enterprise.gui.coregui.client.dashboard.AutoRefreshPortlet;
import org.rhq.enterprise.gui.coregui.client.dashboard.CustomSettingsPortlet;
@@ -54,68 +54,80 @@ import org.rhq.enterprise.gui.coregui.client.dashboard.Portlet;
import org.rhq.enterprise.gui.coregui.client.dashboard.PortletViewFactory;
import org.rhq.enterprise.gui.coregui.client.dashboard.PortletWindow;
import org.rhq.enterprise.gui.coregui.client.dashboard.portlets.PortletConfigurationEditorComponent;
-import org.rhq.enterprise.gui.coregui.client.dashboard.portlets.PortletConfigurationEditorComponent.Constant;
-import org.rhq.enterprise.gui.coregui.client.gwt.AlertGWTServiceAsync;
-import org.rhq.enterprise.gui.coregui.client.gwt.GWTServiceLookup;
+import org.rhq.enterprise.gui.coregui.client.dashboard.portlets.recent.alerts.PortletAlertSelector;
import org.rhq.enterprise.gui.coregui.client.inventory.common.detail.summary.AbstractActivityView;
-import org.rhq.enterprise.gui.coregui.client.resource.disambiguation.ReportDecorator;
-import org.rhq.enterprise.gui.coregui.client.util.GwtRelativeDurationConverter;
import org.rhq.enterprise.gui.coregui.client.util.MeasurementUtility;
-import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableCanvas;
import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableDynamicForm;
import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableVLayout;
+import org.rhq.enterprise.gui.coregui.client.util.selenium.SeleniumUtility;
-/**This portlet allows the end user to customize the:
- * i)range
- * ii)priority
- * iii)etc.
- * of alerts to display for the given group
- *
+/**
* @author Simeon Pinder
*/
-public class GroupAlertsPortlet extends LocatableVLayout implements CustomSettingsPortlet, AutoRefreshPortlet {
- private int groupId = -1;
- protected LocatableCanvas recentAlertsContent = new LocatableCanvas(extendLocatorId("RecentAlerts"));
- private static AlertGWTServiceAsync alertService = GWTServiceLookup.getAlertService();
- private boolean currentlyLoading = false;
- private Configuration portletConfig = null;
- private DashboardPortlet storedPortlet;
+public class GroupAlertsPortlet extends AlertHistoryView implements CustomSettingsPortlet, AutoRefreshPortlet {
+
+ // A non-displayed, persisted identifier for the portlet
+ public static final String KEY = "GroupAlerts";
+ // A default displayed, persisted name for the portlet
+ public static final String NAME = MSG.view_portlet_defaultName_group_alerts();
+
+ public static final String ALERT_RANGE_RESOURCES_VALUE = "alert-range-resource-value";
+ public static final String ALERT_RANGE_RESOURCE_IDS = "alert-range-resource-ids";
+ public static final String RESOURCES_ALL = MSG.common_label_all_resources();
+ public static final String RESOURCES_SELECTED = MSG.common_label_selected_resources();
+ public static final String defaultResourceValue = RESOURCES_ALL;
+ public static final String ID = "id";
+
+ // set on initial configuration, the window for this portlet view.
+ protected PortletWindow portletWindow;
+
+ //shared private UI elements
+ protected AlertResourceSelectorRegion resourceSelector;
+
+ protected AlertPortletConfigurationDataSource dataSource;
+ //instance ui widgets
+ protected Canvas containerCanvas;
+
+ protected Timer refreshTimer;
+ protected DashboardPortlet storedPortlet;
+ protected Configuration portletConfig;
+ private int groupId;
+ protected boolean portletConfigInitialized = false;
+
+ protected static HashMap<String, String> updatedMapping = new HashMap<String, String>();
+ static {
+ updatedMapping.putAll(PortletConfigurationEditorComponent.CONFIG_PROPERTY_INITIALIZATION);
+ //Key, default
+ updatedMapping.put(ALERT_RANGE_RESOURCES_VALUE, RESOURCES_ALL);
+ updatedMapping.put(ALERT_RANGE_RESOURCE_IDS, RESOURCES_ALL);
+ }
public GroupAlertsPortlet(String locatorId) {
super(locatorId);
+
+ //override the shared datasource
//figure out which page we're loading
String currentPage = History.getToken();
String[] elements = currentPage.split("/");
- int currentGroupIdentifier = Integer.valueOf(elements[1]);
- this.groupId = currentGroupIdentifier;
- initializeUi();
- }
+ this.groupId = Integer.valueOf(elements[1]);
- @Override
- protected void onInit() {
- super.onInit();
- loadData();
+ setShowFilterForm(false); //disable filter form for portlet
+ setOverflow(Overflow.VISIBLE);
}
- /**Defines layout for the Activity page.
+ /**Defines layout for the portlet page.
*/
protected void initializeUi() {
- setPadding(5);
- setMembersMargin(5);
- addMember(recentAlertsContent);
- }
+ //initalize the datasource
+ this.dataSource = new AlertPortletConfigurationDataSource(storedPortlet, portletConfig, this.groupId, null);
+ setDataSource(this.dataSource);
- // A non-displayed, persisted identifier for the portlet
- public static final String KEY = "GroupAlerts";
- // A default displayed, persisted name for the portlet
- public static final String NAME = "Group: Alerts";
- public static final String ID = "id";
+ setShowHeader(false);
+ setShowFooter(true);
+ setShowFooterRefresh(false); //disable footer refresh
- // set on initial configuration, the window for this portlet view.
- private PortletWindow portletWindow;
- //instance ui widgets
-
- private Timer refreshTimer;
+ getListGrid().setEmptyMessage(MSG.view_portlet_results_empty());
+ }
/** Responsible for initialization and lazy configuration of the portlet values
*/
@@ -131,6 +143,12 @@ public class GroupAlertsPortlet extends LocatableVLayout implements CustomSettin
this.storedPortlet = storedPortlet;
portletConfig = storedPortlet.getConfiguration();
+ if (!portletConfigInitialized) {
+ this.dataSource = new AlertPortletConfigurationDataSource(storedPortlet, portletConfig, this.groupId, null);
+ setDataSource(this.dataSource);
+ portletConfigInitialized = true;
+ }
+
//lazy init any elements not yet configured.
for (String key : PortletConfigurationEditorComponent.CONFIG_PROPERTY_INITIALIZATION.keySet()) {
if (portletConfig.getSimple(key) == null) {
@@ -138,137 +156,33 @@ public class GroupAlertsPortlet extends LocatableVLayout implements CustomSettin
PortletConfigurationEditorComponent.CONFIG_PROPERTY_INITIALIZATION.get(key)));
}
}
- }
- public Canvas getHelpCanvas() {
- return new HTMLFlow(MSG.view_portlet_help_recentAlerts());
- }
-
- public static final class Factory implements PortletViewFactory {
- public static PortletViewFactory INSTANCE = new Factory();
+ //resource ids to be conditionally included in the query
+ Integer[] filterResourceIds = null;
+ filterResourceIds = getDataSource().extractFilterResourceIds(storedPortlet, filterResourceIds);
+ //no defaults
- public final Portlet getInstance(String locatorId) {
- return new GroupAlertsPortlet(locatorId);
+ if (filterResourceIds != null) {
+ getDataSource().setAlertFilterResourceId(filterResourceIds);
}
- }
- /** Fetches alerts and updates the DynamicForm instance with the latest
- * alert information.
- */
- private void getRecentAlerts() {
- final int groupId = this.groupId;
- currentlyLoading = false;
- //fetches last five alerts for this resource
- AlertCriteria criteria = new AlertCriteria();
- //filter priority
- PropertySimple property = portletConfig.getSimple(Constant.ALERT_PRIORITY);
- if (property != null) {
- String currentSetting = property.getStringValue();
- String[] parsedValues = currentSetting.trim().split(",");
- if (currentSetting.trim().isEmpty() || parsedValues.length == 3) {
- //all alert priorities assumed
- } else {
- AlertPriority[] filterPriorities = new AlertPriority[parsedValues.length];
- int indx = 0;
- for (String priority : parsedValues) {
- AlertPriority p = AlertPriority.valueOf(priority);
- filterPriorities[indx++] = p;
- }
- criteria.addFilterPriorities(filterPriorities);
- }
- }
- PageControl pc = new PageControl();
- //result sort order
- property = portletConfig.getSimple(Constant.RESULT_SORT_ORDER);
- if (property != null) {
- String currentSetting = property.getStringValue();
- if (currentSetting.trim().isEmpty() || currentSetting.equalsIgnoreCase(PageOrdering.DESC.name())) {
- criteria.addSortCtime(PageOrdering.DESC);
- pc.setPrimarySortOrder(PageOrdering.DESC);
- } else {
- criteria.addSortCtime(PageOrdering.ASC);
- pc.setPrimarySortOrder(PageOrdering.ASC);
+ //conditionally display the selected resources ui
+ if (containerCanvas != null) {
+ //empty out earlier canvas
+ for (Canvas c : containerCanvas.getChildren()) {
+ c.destroy();
}
- }
- //result timeframe if enabled
- property = portletConfig.getSimple(Constant.METRIC_RANGE_ENABLE);
- if (Boolean.valueOf(property.getBooleanValue())) {//then proceed setting
- property = portletConfig.getSimple(Constant.METRIC_RANGE);
- if (property != null) {
- String currentSetting = property.getStringValue();
- String[] range = currentSetting.split(",");
- criteria.addFilterStartTime(Long.valueOf(range[0]));
- criteria.addFilterEndTime(Long.valueOf(range[1]));
- }
- }
-
- //result count
- property = portletConfig.getSimple(Constant.RESULT_COUNT);
- if (property != null) {
- String currentSetting = property.getStringValue();
- if (currentSetting.trim().isEmpty() || currentSetting.equalsIgnoreCase("5")) {
- PageControl pageControl = new PageControl(0, 5);
- pc.setPageSize(5);
+ if ((resourceSelector != null) && getDataSource().getAlertResourcesToUse().equals(RESOURCES_SELECTED)) {
+ containerCanvas.addChild(resourceSelector.getCanvas());
} else {
- PageControl pageControl = new PageControl(0, Integer.valueOf(currentSetting));
- pc.setPageSize(Integer.valueOf(currentSetting));
+ containerCanvas.addChild(new Canvas());
}
}
- criteria.setPageControl(pc);
- criteria.addFilterResourceGroupIds(groupId);
- alertService.findAlertsByCriteria(criteria, new AsyncCallback<PageList<Alert>>() {
- @Override
- public void onSuccess(PageList<Alert> result) {
- VLayout column = new VLayout();
- column.setHeight(10);
- if (!result.isEmpty()) {
- int rowNum = 0;
- for (Alert alert : result) {
- // alert history records do not have a usable locatorId, we'll use rownum, which is unique and
- // may be repeatable.
- LocatableDynamicForm row = new LocatableDynamicForm(recentAlertsContent.extendLocatorId(String
- .valueOf(rowNum++)));
- row.setNumCols(3);
-
- StaticTextItem iconItem = AbstractActivityView.newTextItemIcon(ImageManager.getAlertIcon(alert
- .getAlertDefinition().getPriority()), alert.getAlertDefinition().getPriority()
- .getDisplayName());
- LinkItem link = AbstractActivityView.newLinkItem(alert.getAlertDefinition().getName() + ": ",
- ReportDecorator.GWT_GROUP_URL + groupId + "/Alerts/History/" + alert.getId());
- StaticTextItem time = AbstractActivityView.newTextItem(GwtRelativeDurationConverter
- .format(alert.getCtime()));
- row.setItems(iconItem, link, time);
-
- column.addMember(row);
- }
- //link to more details
- LocatableDynamicForm row = new LocatableDynamicForm(recentAlertsContent.extendLocatorId(String
- .valueOf(rowNum++)));
- AbstractActivityView.addSeeMoreLink(row, ReportDecorator.GWT_GROUP_URL + groupId
- + "/Alerts/History/", column);
- } else {
- LocatableDynamicForm row = AbstractActivityView.createEmptyDisplayRow(recentAlertsContent
- // .extendLocatorId("None"), AbstractActivityView.RECENT_ALERTS_NONE);
- .extendLocatorId("None"), "No results found using criteria specified.");
- column.addMember(row);
- }
- for (Canvas child : recentAlertsContent.getChildren()) {
- child.destroy();
- }
- recentAlertsContent.addChild(column);
- recentAlertsContent.markForRedraw();
- }
- @Override
- public void onFailure(Throwable caught) {
- Log.debug("Error retrieving recent alerts for group [" + groupId + "]:" + caught.getMessage());
- }
- });
}
- protected void loadData() {
- currentlyLoading = true;
- getRecentAlerts();
+ public Canvas getHelpCanvas() {
+ return new HTMLFlow(MSG.view_portlet_help_recentAlerts());
}
@Override
@@ -289,11 +203,11 @@ public class GroupAlertsPortlet extends LocatableVLayout implements CustomSettin
// .getResulSortOrderEditor(portletConfig);
//add result count selector
final SelectItem resultCountSelector = PortletConfigurationEditorComponent.getResultCountEditor(portletConfig);
+
//add range selector
final CustomConfigMeasurementRangeEditor measurementRangeEditor = PortletConfigurationEditorComponent
.getMeasurementRangeEditor(portletConfig);
- //TODO: spinder 3/10/11 renable sort selector once it's working in criteria
- // form.setItems(alertPrioritySelector, resultSortSelector, resultCountSelector);
+
form.setItems(alertPrioritySelector, resultCountSelector);
//submit handler
@@ -301,13 +215,10 @@ public class GroupAlertsPortlet extends LocatableVLayout implements CustomSettin
@Override
public void onSubmitValues(SubmitValuesEvent event) {
+ String selectedValue;
//alert severity
- String selectedValue = alertPrioritySelector.getValue().toString();
- if ((selectedValue.trim().isEmpty()) || (selectedValue.split(",").length == 3)) {//then no alertPriority specified
- portletConfig.put(new PropertySimple(Constant.ALERT_PRIORITY, ""));
- } else {//some subset of available alertPriorities will be used
- portletConfig.put(new PropertySimple(Constant.ALERT_PRIORITY, selectedValue));
- }
+ portletConfig = AbstractActivityView.saveAlertPrioritySettings(alertPrioritySelector, portletConfig);
+
// //result sort order
// selectedValue = resultSortSelector.getValue().toString();
// if ((selectedValue.trim().isEmpty()) || (selectedValue.equalsIgnoreCase(PageOrdering.DESC.name()))) {//then desc
@@ -316,37 +227,16 @@ public class GroupAlertsPortlet extends LocatableVLayout implements CustomSettin
// portletConfig.put(new PropertySimple(Constant.RESULT_SORT_ORDER, PageOrdering.ASC));
// }
//result count
- selectedValue = resultCountSelector.getValue().toString();
- if ((selectedValue.trim().isEmpty()) || (selectedValue.equalsIgnoreCase(Constant.RESULT_COUNT_DEFAULT))) {//then 5
- portletConfig.put(new PropertySimple(Constant.RESULT_COUNT, Constant.RESULT_COUNT_DEFAULT));
- } else {
- portletConfig.put(new PropertySimple(Constant.RESULT_COUNT, selectedValue));
- }
-
- //alert time range filter. Check for enabled and then persist property. Dealing with compound widget.
- FormItem item = measurementRangeEditor.getItem(CustomConfigMeasurementRangeEditor.ENABLE_RANGE_ITEM);
- CheckboxItem itemC = (CheckboxItem) item;
- selectedValue = String.valueOf(itemC.getValueAsBoolean());
- if (!selectedValue.trim().isEmpty()) {//then call
- portletConfig.put(new PropertySimple(Constant.METRIC_RANGE_ENABLE, selectedValue));
- }
-
- //alert time advanced time filter enabled.
- selectedValue = String.valueOf(measurementRangeEditor.isAdvanced());
- if ((selectedValue != null) && (!selectedValue.trim().isEmpty())) {
- portletConfig.put(new PropertySimple(Constant.METRIC_RANGE_BEGIN_END_FLAG, selectedValue));
- }
+ portletConfig = AbstractActivityView.saveResultCounterSettings(resultCountSelector, portletConfig);
- //alert time frame
- List<Long> begEnd = measurementRangeEditor.getBeginEndTimes();
- if (begEnd.get(0) != 0) {//advanced settings
- portletConfig.put(new PropertySimple(Constant.METRIC_RANGE, (begEnd.get(0) + "," + begEnd.get(1))));
- }
+ //time range settings
+ portletConfig = AbstractActivityView.saveMeasurementRangeEditorSettings(measurementRangeEditor,
+ portletConfig);
- //persist
+ //persist and reload portlet
storedPortlet.setConfiguration(portletConfig);
configure(portletWindow, storedPortlet);
- loadData();
+ refresh();
}
});
form.markForRedraw();
@@ -356,6 +246,19 @@ public class GroupAlertsPortlet extends LocatableVLayout implements CustomSettin
return customSettings;
}
+ public AlertPortletConfigurationDataSource getDataSource() {
+ return dataSource;
+ }
+
+ public static final class Factory implements PortletViewFactory {
+ public static PortletViewFactory INSTANCE = new Factory();
+
+ public final Portlet getInstance(String locatorId) {
+
+ return new GroupAlertsPortlet(locatorId);
+ }
+ }
+
@Override
public void startRefreshCycle() {
//current setting
@@ -370,10 +273,8 @@ public class GroupAlertsPortlet extends LocatableVLayout implements CustomSettin
refreshTimer = new Timer() {
public void run() {
- if (!currentlyLoading) {
- loadData();
- redraw();
- }
+
+ redraw();
}
};
@@ -384,15 +285,110 @@ public class GroupAlertsPortlet extends LocatableVLayout implements CustomSettin
@Override
protected void onDestroy() {
if (refreshTimer != null) {
-
refreshTimer.cancel();
}
+
super.onDestroy();
}
@Override
- public void redraw() {
- super.redraw();
- loadData();
+ protected void setupTableInteractions(boolean hasWriteAccess) {
+ // The portlet is a "subsystem" view. Meaning the alerts displayed can be from any accessible group for
+ // the user. This means the user can have varying permissions on the underlying groups and/or resources,
+ // which makes button enablement tricky. So, for the portlet don't even show the buttons unless the user
+ // is inventory manager. Other users will just have to navigate to the alert in question in order to
+ // manipulate it.
+
+ //determine if the user is inventory manager and if so render the buttons
+ Set<Permission> permissions = this.portletWindow.getGlobalPermissions();
+ if ((null != permissions) && permissions.contains(Permission.MANAGE_INVENTORY)) {
+ super.setupTableInteractions(true);
+ }
+ }
+
+ protected CellFormatter getDetailsLinkColumnCellFormatter() {
+ return new CellFormatter() {
+ public String format(Object value, ListGridRecord record, int i, int i1) {
+ Integer recordId = getId(record);
+ Integer resourceId = record.getAttributeAsInt("resourceId");
+ String detailsUrl = LinkManager.getSubsystemAlertHistoryLink(resourceId, recordId);
+ return SeleniumUtility.getLocatableHref(detailsUrl, value.toString(), null);
+ }
+ };
+ }
+
+ @Override
+ protected void configureTable() {
+ super.configureTable();
+
+ setListGridDoubleClickHandler(new DoubleClickHandler() {
+ @Override
+ public void onDoubleClick(DoubleClickEvent event) {
+ ListGrid listGrid = (ListGrid) event.getSource();
+ ListGridRecord[] selectedRows = listGrid.getSelection();
+ if (selectedRows != null && selectedRows.length == 1) {
+ Integer recordId = getId(selectedRows[0]);
+ Integer resourceId = selectedRows[0].getAttributeAsInt("resourceId");
+ CoreGUI.goToView(LinkManager.getSubsystemAlertHistoryLink(resourceId, recordId));
+ }
+ }
+ });
+ }
+
+ @Override
+ protected void onInit() {
+ super.onInit();
+ initializeUi();
+ // getListGrid().setEmptyMessage(MSG.view_portlet_results_empty());
+ }
+
+ @Override
+ protected void refreshTableInfo() {
+ super.refreshTableInfo();
+ if (getTableInfo() != null) {
+ int count = getListGrid().getSelection().length;
+ getTableInfo().setContents(
+ MSG.view_table_matchingRows(String.valueOf(getListGrid().getTotalRows()), String.valueOf(count)));
+ }
+ }
+}
+
+/** Bundles a ResourceSelector instance with labeling in Canvas for display.
+ * Also modifies the AssignedGrid to listen for AvailbleGrid completion and act accordingly.
+ */
+//class AlertResourceSelectorRegion extends LocatableVLayout {
+final class AlertResourceSelectorRegion extends LocatableVLayout {
+ public AlertResourceSelectorRegion(String locatorId, Integer[] assigned) {
+ super(locatorId);
+ this.currentlyAssignedIds = assigned;
+ }
+
+ private static final Messages MSG = CoreGUI.getMessages();
+ private PortletAlertSelector selector = null;
+
+ private Integer[] currentlyAssignedIds;
+
+ public Integer[] getCurrentlyAssignedIds() {
+ return currentlyAssignedIds;
+ }
+
+ public Integer[] getListGridValues() {
+ Integer[] listGridValues = new Integer[0];
+ if (null != selector) {
+ listGridValues = selector.getAssignedListGridValues();
+ }
+ return listGridValues;
+ }
+
+ public Canvas getCanvas() {
+ if (selector == null) {
+ selector = new PortletAlertSelector(extendLocatorId("AlertSelector"), this.currentlyAssignedIds,
+ ResourceType.ANY_PLATFORM_TYPE, false);
+ }
+ return selector;
+ }
+
+ public void setCurrentlyAssignedIds(Integer[] currentlyAssignedIds) {
+ this.currentlyAssignedIds = currentlyAssignedIds;
}
}
\ No newline at end of file
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/groups/GroupAlertsPortlet2.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/groups/GroupAlertsPortlet2.java
deleted file mode 100644
index 565b46b..0000000
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/groups/GroupAlertsPortlet2.java
+++ /dev/null
@@ -1,394 +0,0 @@
-/*
- * RHQ Management Platform
- * Copyright (C) 2005-2010 Red Hat, Inc.
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-package org.rhq.enterprise.gui.coregui.client.dashboard.portlets.groups;
-
-import java.util.HashMap;
-import java.util.Set;
-
-import com.google.gwt.user.client.History;
-import com.google.gwt.user.client.Timer;
-import com.smartgwt.client.types.Overflow;
-import com.smartgwt.client.widgets.Canvas;
-import com.smartgwt.client.widgets.HTMLFlow;
-import com.smartgwt.client.widgets.events.DoubleClickEvent;
-import com.smartgwt.client.widgets.events.DoubleClickHandler;
-import com.smartgwt.client.widgets.form.DynamicForm;
-import com.smartgwt.client.widgets.form.events.SubmitValuesEvent;
-import com.smartgwt.client.widgets.form.events.SubmitValuesHandler;
-import com.smartgwt.client.widgets.form.fields.SelectItem;
-import com.smartgwt.client.widgets.grid.CellFormatter;
-import com.smartgwt.client.widgets.grid.ListGrid;
-import com.smartgwt.client.widgets.grid.ListGridRecord;
-
-import org.rhq.core.domain.authz.Permission;
-import org.rhq.core.domain.configuration.Configuration;
-import org.rhq.core.domain.configuration.PropertySimple;
-import org.rhq.core.domain.dashboard.DashboardPortlet;
-import org.rhq.core.domain.resource.ResourceType;
-import org.rhq.enterprise.gui.coregui.client.CoreGUI;
-import org.rhq.enterprise.gui.coregui.client.LinkManager;
-import org.rhq.enterprise.gui.coregui.client.Messages;
-import org.rhq.enterprise.gui.coregui.client.UserSessionManager;
-import org.rhq.enterprise.gui.coregui.client.alert.AlertHistoryView;
-import org.rhq.enterprise.gui.coregui.client.alert.AlertPortletConfigurationDataSource;
-import org.rhq.enterprise.gui.coregui.client.components.measurement.CustomConfigMeasurementRangeEditor;
-import org.rhq.enterprise.gui.coregui.client.dashboard.AutoRefreshPortlet;
-import org.rhq.enterprise.gui.coregui.client.dashboard.CustomSettingsPortlet;
-import org.rhq.enterprise.gui.coregui.client.dashboard.Portlet;
-import org.rhq.enterprise.gui.coregui.client.dashboard.PortletViewFactory;
-import org.rhq.enterprise.gui.coregui.client.dashboard.PortletWindow;
-import org.rhq.enterprise.gui.coregui.client.dashboard.portlets.PortletConfigurationEditorComponent;
-import org.rhq.enterprise.gui.coregui.client.dashboard.portlets.recent.alerts.PortletAlertSelector;
-import org.rhq.enterprise.gui.coregui.client.inventory.common.detail.summary.AbstractActivityView;
-import org.rhq.enterprise.gui.coregui.client.util.MeasurementUtility;
-import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableDynamicForm;
-import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableVLayout;
-import org.rhq.enterprise.gui.coregui.client.util.selenium.SeleniumUtility;
-
-/**
- * @author Simeon Pinder
- */
-public class GroupAlertsPortlet2 extends AlertHistoryView implements CustomSettingsPortlet, AutoRefreshPortlet {
-
- // A non-displayed, persisted identifier for the portlet
- public static final String KEY = "GroupAlerts";
- // A default displayed, persisted name for the portlet
- public static final String NAME = MSG.view_portlet_defaultName_group_alerts();
-
- public static final String ALERT_RANGE_RESOURCES_VALUE = "alert-range-resource-value";
- public static final String ALERT_RANGE_RESOURCE_IDS = "alert-range-resource-ids";
- public static final String RESOURCES_ALL = MSG.common_label_all_resources();
- public static final String RESOURCES_SELECTED = MSG.common_label_selected_resources();
- public static final String defaultResourceValue = RESOURCES_ALL;
- public static final String ID = "id";
-
- // set on initial configuration, the window for this portlet view.
- protected PortletWindow portletWindow;
-
- //shared private UI elements
- protected AlertResourceSelectorRegion resourceSelector;
-
- protected AlertPortletConfigurationDataSource dataSource;
- //instance ui widgets
- protected Canvas containerCanvas;
-
- protected Timer refreshTimer;
- protected DashboardPortlet storedPortlet;
- protected Configuration portletConfig;
- private int groupId;
- protected boolean portletConfigInitialized = false;
-
- protected static HashMap<String, String> updatedMapping = new HashMap<String, String>();
- static {
- updatedMapping.putAll(PortletConfigurationEditorComponent.CONFIG_PROPERTY_INITIALIZATION);
- //Key, default
- updatedMapping.put(ALERT_RANGE_RESOURCES_VALUE, RESOURCES_ALL);
- updatedMapping.put(ALERT_RANGE_RESOURCE_IDS, RESOURCES_ALL);
- }
-
- public GroupAlertsPortlet2(String locatorId) {
- super(locatorId);
-
- //override the shared datasource
- //figure out which page we're loading
- String currentPage = History.getToken();
- String[] elements = currentPage.split("/");
- this.groupId = Integer.valueOf(elements[1]);
-
- setShowFilterForm(false); //disable filter form for portlet
- setOverflow(Overflow.VISIBLE);
- }
-
- /**Defines layout for the portlet page.
- */
- protected void initializeUi() {
- //initalize the datasource
- this.dataSource = new AlertPortletConfigurationDataSource(storedPortlet, portletConfig, this.groupId, null);
- setDataSource(this.dataSource);
-
- setShowHeader(false);
- setShowFooter(true);
- setShowFooterRefresh(false); //disable footer refresh
-
- getListGrid().setEmptyMessage(MSG.view_portlet_results_empty());
- }
-
- /** Responsible for initialization and lazy configuration of the portlet values
- */
- public void configure(PortletWindow portletWindow, DashboardPortlet storedPortlet) {
- //populate portlet configuration details
- if (null == this.portletWindow && null != portletWindow) {
- this.portletWindow = portletWindow;
- }
-
- if ((null == storedPortlet) || (null == storedPortlet.getConfiguration())) {
- return;
- }
- this.storedPortlet = storedPortlet;
- portletConfig = storedPortlet.getConfiguration();
-
- if (!portletConfigInitialized) {
- this.dataSource = new AlertPortletConfigurationDataSource(storedPortlet, portletConfig, this.groupId, null);
- setDataSource(this.dataSource);
- portletConfigInitialized = true;
- }
-
- //lazy init any elements not yet configured.
- for (String key : PortletConfigurationEditorComponent.CONFIG_PROPERTY_INITIALIZATION.keySet()) {
- if (portletConfig.getSimple(key) == null) {
- portletConfig.put(new PropertySimple(key,
- PortletConfigurationEditorComponent.CONFIG_PROPERTY_INITIALIZATION.get(key)));
- }
- }
-
- //resource ids to be conditionally included in the query
- Integer[] filterResourceIds = null;
- filterResourceIds = getDataSource().extractFilterResourceIds(storedPortlet, filterResourceIds);
- //no defaults
-
- if (filterResourceIds != null) {
- getDataSource().setAlertFilterResourceId(filterResourceIds);
- }
-
- //conditionally display the selected resources ui
- if (containerCanvas != null) {
- //empty out earlier canvas
- for (Canvas c : containerCanvas.getChildren()) {
- c.destroy();
- }
- if ((resourceSelector != null) && getDataSource().getAlertResourcesToUse().equals(RESOURCES_SELECTED)) {
- containerCanvas.addChild(resourceSelector.getCanvas());
- } else {
- containerCanvas.addChild(new Canvas());
- }
- }
-
- }
-
- public Canvas getHelpCanvas() {
- return new HTMLFlow(MSG.view_portlet_help_recentAlerts());
- }
-
- @Override
- public DynamicForm getCustomSettingsForm() {
- LocatableDynamicForm customSettings = new LocatableDynamicForm(extendLocatorId("customSettings"));
- LocatableVLayout page = new LocatableVLayout(customSettings.extendLocatorId("page"));
- //build editor form container
- final LocatableDynamicForm form = new LocatableDynamicForm(page.extendLocatorId("alert-filter"));
- form.setMargin(5);
-
- //add label about what configuration affects
-
- //add alert priority selector
- final SelectItem alertPrioritySelector = PortletConfigurationEditorComponent
- .getAlertPriorityEditor(portletConfig);
- //add sort priority selector
- // final SelectItem resultSortSelector = PortletConfigurationEditorComponent
- // .getResulSortOrderEditor(portletConfig);
- //add result count selector
- final SelectItem resultCountSelector = PortletConfigurationEditorComponent.getResultCountEditor(portletConfig);
-
- //add range selector
- final CustomConfigMeasurementRangeEditor measurementRangeEditor = PortletConfigurationEditorComponent
- .getMeasurementRangeEditor(portletConfig);
-
- form.setItems(alertPrioritySelector, resultCountSelector);
-
- //submit handler
- customSettings.addSubmitValuesHandler(new SubmitValuesHandler() {
-
- @Override
- public void onSubmitValues(SubmitValuesEvent event) {
- String selectedValue;
- //alert severity
- portletConfig = AbstractActivityView.saveAlertPrioritySettings(alertPrioritySelector, portletConfig);
-
- // //result sort order
- // selectedValue = resultSortSelector.getValue().toString();
- // if ((selectedValue.trim().isEmpty()) || (selectedValue.equalsIgnoreCase(PageOrdering.DESC.name()))) {//then desc
- // portletConfig.put(new PropertySimple(Constant.RESULT_SORT_ORDER, PageOrdering.DESC));
- // } else {
- // portletConfig.put(new PropertySimple(Constant.RESULT_SORT_ORDER, PageOrdering.ASC));
- // }
- //result count
- portletConfig = AbstractActivityView.saveResultCounterSettings(resultCountSelector, portletConfig);
-
- //time range settings
- portletConfig = AbstractActivityView.saveMeasurementRangeEditorSettings(measurementRangeEditor,
- portletConfig);
-
- //persist and reload portlet
- storedPortlet.setConfiguration(portletConfig);
- configure(portletWindow, storedPortlet);
- refresh();
- }
- });
- form.markForRedraw();
- page.addMember(measurementRangeEditor);
- page.addMember(form);
- customSettings.addChild(page);
- return customSettings;
- }
-
- public AlertPortletConfigurationDataSource getDataSource() {
- return dataSource;
- }
-
- public static final class Factory implements PortletViewFactory {
- public static PortletViewFactory INSTANCE = new Factory();
-
- public final Portlet getInstance(String locatorId) {
-
- return new GroupAlertsPortlet2(locatorId);
- }
- }
-
- @Override
- public void startRefreshCycle() {
- //current setting
- final int refreshInterval = UserSessionManager.getUserPreferences().getPageRefreshInterval();
-
- //cancel any existing timer
- if (refreshTimer != null) {
- refreshTimer.cancel();
- }
-
- if (refreshInterval >= MeasurementUtility.MINUTES) {
-
- refreshTimer = new Timer() {
- public void run() {
-
- redraw();
- }
- };
-
- refreshTimer.scheduleRepeating(refreshInterval);
- }
- }
-
- @Override
- protected void onDestroy() {
- if (refreshTimer != null) {
- refreshTimer.cancel();
- }
-
- super.onDestroy();
- }
-
- @Override
- protected void setupTableInteractions(boolean hasWriteAccess) {
- // The portlet is a "subsystem" view. Meaning the alerts displayed can be from any accessible group for
- // the user. This means the user can have varying permissions on the underlying groups and/or resources,
- // which makes button enablement tricky. So, for the portlet don't even show the buttons unless the user
- // is inventory manager. Other users will just have to navigate to the alert in question in order to
- // manipulate it.
-
- //determine if the user is inventory manager and if so render the buttons
- Set<Permission> permissions = this.portletWindow.getGlobalPermissions();
- if ((null != permissions) && permissions.contains(Permission.MANAGE_INVENTORY)) {
- super.setupTableInteractions(true);
- }
- }
-
- protected CellFormatter getDetailsLinkColumnCellFormatter() {
- return new CellFormatter() {
- public String format(Object value, ListGridRecord record, int i, int i1) {
- Integer recordId = getId(record);
- Integer resourceId = record.getAttributeAsInt("resourceId");
- String detailsUrl = LinkManager.getSubsystemAlertHistoryLink(resourceId, recordId);
- return SeleniumUtility.getLocatableHref(detailsUrl, value.toString(), null);
- }
- };
- }
-
- @Override
- protected void configureTable() {
- super.configureTable();
-
- setListGridDoubleClickHandler(new DoubleClickHandler() {
- @Override
- public void onDoubleClick(DoubleClickEvent event) {
- ListGrid listGrid = (ListGrid) event.getSource();
- ListGridRecord[] selectedRows = listGrid.getSelection();
- if (selectedRows != null && selectedRows.length == 1) {
- Integer recordId = getId(selectedRows[0]);
- Integer resourceId = selectedRows[0].getAttributeAsInt("resourceId");
- CoreGUI.goToView(LinkManager.getSubsystemAlertHistoryLink(resourceId, recordId));
- }
- }
- });
- }
-
- @Override
- protected void onInit() {
- super.onInit();
- initializeUi();
- // getListGrid().setEmptyMessage(MSG.view_portlet_results_empty());
- }
-
- @Override
- protected void refreshTableInfo() {
- super.refreshTableInfo();
- if (getTableInfo() != null) {
- int count = getListGrid().getSelection().length;
- getTableInfo().setContents(
- MSG.view_table_matchingRows(String.valueOf(getListGrid().getTotalRows()), String.valueOf(count)));
- }
- }
-}
-
-/** Bundles a ResourceSelector instance with labeling in Canvas for display.
- * Also modifies the AssignedGrid to listen for AvailbleGrid completion and act accordingly.
- */
-//class AlertResourceSelectorRegion extends LocatableVLayout {
-final class AlertResourceSelectorRegion extends LocatableVLayout {
- public AlertResourceSelectorRegion(String locatorId, Integer[] assigned) {
- super(locatorId);
- this.currentlyAssignedIds = assigned;
- }
-
- private static final Messages MSG = CoreGUI.getMessages();
- private PortletAlertSelector selector = null;
-
- private Integer[] currentlyAssignedIds;
-
- public Integer[] getCurrentlyAssignedIds() {
- return currentlyAssignedIds;
- }
-
- public Integer[] getListGridValues() {
- Integer[] listGridValues = new Integer[0];
- if (null != selector) {
- listGridValues = selector.getAssignedListGridValues();
- }
- return listGridValues;
- }
-
- public Canvas getCanvas() {
- if (selector == null) {
- selector = new PortletAlertSelector(extendLocatorId("AlertSelector"), this.currentlyAssignedIds,
- ResourceType.ANY_PLATFORM_TYPE, false);
- }
- return selector;
- }
-
- public void setCurrentlyAssignedIds(Integer[] currentlyAssignedIds) {
- this.currentlyAssignedIds = currentlyAssignedIds;
- }
-}
\ No newline at end of file
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/groups/GroupAlertsPortlet3.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/groups/GroupAlertsPortlet3.java
new file mode 100644
index 0000000..7c166ad
--- /dev/null
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/groups/GroupAlertsPortlet3.java
@@ -0,0 +1,398 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2010 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+package org.rhq.enterprise.gui.coregui.client.dashboard.portlets.groups;
+
+import java.util.List;
+
+import com.allen_sauer.gwt.log.client.Log;
+import com.google.gwt.user.client.History;
+import com.google.gwt.user.client.Timer;
+import com.google.gwt.user.client.rpc.AsyncCallback;
+import com.smartgwt.client.widgets.Canvas;
+import com.smartgwt.client.widgets.HTMLFlow;
+import com.smartgwt.client.widgets.form.DynamicForm;
+import com.smartgwt.client.widgets.form.events.SubmitValuesEvent;
+import com.smartgwt.client.widgets.form.events.SubmitValuesHandler;
+import com.smartgwt.client.widgets.form.fields.CheckboxItem;
+import com.smartgwt.client.widgets.form.fields.FormItem;
+import com.smartgwt.client.widgets.form.fields.LinkItem;
+import com.smartgwt.client.widgets.form.fields.SelectItem;
+import com.smartgwt.client.widgets.form.fields.StaticTextItem;
+import com.smartgwt.client.widgets.layout.VLayout;
+
+import org.rhq.core.domain.alert.Alert;
+import org.rhq.core.domain.alert.AlertPriority;
+import org.rhq.core.domain.configuration.Configuration;
+import org.rhq.core.domain.configuration.PropertySimple;
+import org.rhq.core.domain.criteria.AlertCriteria;
+import org.rhq.core.domain.dashboard.DashboardPortlet;
+import org.rhq.core.domain.util.PageControl;
+import org.rhq.core.domain.util.PageList;
+import org.rhq.core.domain.util.PageOrdering;
+import org.rhq.enterprise.gui.coregui.client.ImageManager;
+import org.rhq.enterprise.gui.coregui.client.UserSessionManager;
+import org.rhq.enterprise.gui.coregui.client.components.measurement.CustomConfigMeasurementRangeEditor;
+import org.rhq.enterprise.gui.coregui.client.dashboard.AutoRefreshPortlet;
+import org.rhq.enterprise.gui.coregui.client.dashboard.CustomSettingsPortlet;
+import org.rhq.enterprise.gui.coregui.client.dashboard.Portlet;
+import org.rhq.enterprise.gui.coregui.client.dashboard.PortletViewFactory;
+import org.rhq.enterprise.gui.coregui.client.dashboard.PortletWindow;
+import org.rhq.enterprise.gui.coregui.client.dashboard.portlets.PortletConfigurationEditorComponent;
+import org.rhq.enterprise.gui.coregui.client.dashboard.portlets.PortletConfigurationEditorComponent.Constant;
+import org.rhq.enterprise.gui.coregui.client.gwt.AlertGWTServiceAsync;
+import org.rhq.enterprise.gui.coregui.client.gwt.GWTServiceLookup;
+import org.rhq.enterprise.gui.coregui.client.inventory.common.detail.summary.AbstractActivityView;
+import org.rhq.enterprise.gui.coregui.client.resource.disambiguation.ReportDecorator;
+import org.rhq.enterprise.gui.coregui.client.util.GwtRelativeDurationConverter;
+import org.rhq.enterprise.gui.coregui.client.util.MeasurementUtility;
+import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableCanvas;
+import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableDynamicForm;
+import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableVLayout;
+
+/**This portlet allows the end user to customize the:
+ * i)range
+ * ii)priority
+ * iii)etc.
+ * of alerts to display for the given group
+ *
+ * @author Simeon Pinder
+ */
+public class GroupAlertsPortlet3 extends LocatableVLayout implements CustomSettingsPortlet, AutoRefreshPortlet {
+ private int groupId = -1;
+ protected LocatableCanvas recentAlertsContent = new LocatableCanvas(extendLocatorId("RecentAlerts"));
+ private static AlertGWTServiceAsync alertService = GWTServiceLookup.getAlertService();
+ private boolean currentlyLoading = false;
+ private Configuration portletConfig = null;
+ private DashboardPortlet storedPortlet;
+
+ public GroupAlertsPortlet3(String locatorId) {
+ super(locatorId);
+ //figure out which page we're loading
+ String currentPage = History.getToken();
+ String[] elements = currentPage.split("/");
+ int currentGroupIdentifier = Integer.valueOf(elements[1]);
+ this.groupId = currentGroupIdentifier;
+ initializeUi();
+ }
+
+ @Override
+ protected void onInit() {
+ super.onInit();
+ loadData();
+ }
+
+ /**Defines layout for the Activity page.
+ */
+ protected void initializeUi() {
+ setPadding(5);
+ setMembersMargin(5);
+ addMember(recentAlertsContent);
+ }
+
+ // A non-displayed, persisted identifier for the portlet
+ public static final String KEY = "GroupAlerts";
+ // A default displayed, persisted name for the portlet
+ public static final String NAME = "Group: Alerts";
+ public static final String ID = "id";
+
+ // set on initial configuration, the window for this portlet view.
+ private PortletWindow portletWindow;
+ //instance ui widgets
+
+ private Timer refreshTimer;
+
+ /** Responsible for initialization and lazy configuration of the portlet values
+ */
+ public void configure(PortletWindow portletWindow, DashboardPortlet storedPortlet) {
+ //populate portlet configuration details
+ if (null == this.portletWindow && null != portletWindow) {
+ this.portletWindow = portletWindow;
+ }
+
+ if ((null == storedPortlet) || (null == storedPortlet.getConfiguration())) {
+ return;
+ }
+ this.storedPortlet = storedPortlet;
+ portletConfig = storedPortlet.getConfiguration();
+
+ //lazy init any elements not yet configured.
+ for (String key : PortletConfigurationEditorComponent.CONFIG_PROPERTY_INITIALIZATION.keySet()) {
+ if (portletConfig.getSimple(key) == null) {
+ portletConfig.put(new PropertySimple(key,
+ PortletConfigurationEditorComponent.CONFIG_PROPERTY_INITIALIZATION.get(key)));
+ }
+ }
+ }
+
+ public Canvas getHelpCanvas() {
+ return new HTMLFlow(MSG.view_portlet_help_recentAlerts());
+ }
+
+ public static final class Factory implements PortletViewFactory {
+ public static PortletViewFactory INSTANCE = new Factory();
+
+ public final Portlet getInstance(String locatorId) {
+ return new GroupAlertsPortlet3(locatorId);
+ }
+ }
+
+ /** Fetches alerts and updates the DynamicForm instance with the latest
+ * alert information.
+ */
+ private void getRecentAlerts() {
+ final int groupId = this.groupId;
+ currentlyLoading = false;
+ //fetches last five alerts for this resource
+ AlertCriteria criteria = new AlertCriteria();
+ //filter priority
+ PropertySimple property = portletConfig.getSimple(Constant.ALERT_PRIORITY);
+ if (property != null) {
+ String currentSetting = property.getStringValue();
+ String[] parsedValues = currentSetting.trim().split(",");
+ if (currentSetting.trim().isEmpty() || parsedValues.length == 3) {
+ //all alert priorities assumed
+ } else {
+ AlertPriority[] filterPriorities = new AlertPriority[parsedValues.length];
+ int indx = 0;
+ for (String priority : parsedValues) {
+ AlertPriority p = AlertPriority.valueOf(priority);
+ filterPriorities[indx++] = p;
+ }
+ criteria.addFilterPriorities(filterPriorities);
+ }
+ }
+ PageControl pc = new PageControl();
+ //result sort order
+ property = portletConfig.getSimple(Constant.RESULT_SORT_ORDER);
+ if (property != null) {
+ String currentSetting = property.getStringValue();
+ if (currentSetting.trim().isEmpty() || currentSetting.equalsIgnoreCase(PageOrdering.DESC.name())) {
+ criteria.addSortCtime(PageOrdering.DESC);
+ pc.setPrimarySortOrder(PageOrdering.DESC);
+ } else {
+ criteria.addSortCtime(PageOrdering.ASC);
+ pc.setPrimarySortOrder(PageOrdering.ASC);
+ }
+ }
+ //result timeframe if enabled
+ property = portletConfig.getSimple(Constant.METRIC_RANGE_ENABLE);
+ if (Boolean.valueOf(property.getBooleanValue())) {//then proceed setting
+ property = portletConfig.getSimple(Constant.METRIC_RANGE);
+ if (property != null) {
+ String currentSetting = property.getStringValue();
+ String[] range = currentSetting.split(",");
+ criteria.addFilterStartTime(Long.valueOf(range[0]));
+ criteria.addFilterEndTime(Long.valueOf(range[1]));
+ }
+ }
+
+ //result count
+ property = portletConfig.getSimple(Constant.RESULT_COUNT);
+ if (property != null) {
+ String currentSetting = property.getStringValue();
+ if (currentSetting.trim().isEmpty() || currentSetting.equalsIgnoreCase("5")) {
+ PageControl pageControl = new PageControl(0, 5);
+ pc.setPageSize(5);
+ } else {
+ PageControl pageControl = new PageControl(0, Integer.valueOf(currentSetting));
+ pc.setPageSize(Integer.valueOf(currentSetting));
+ }
+ }
+ criteria.setPageControl(pc);
+ criteria.addFilterResourceGroupIds(groupId);
+ alertService.findAlertsByCriteria(criteria, new AsyncCallback<PageList<Alert>>() {
+ @Override
+ public void onSuccess(PageList<Alert> result) {
+ VLayout column = new VLayout();
+ column.setHeight(10);
+ if (!result.isEmpty()) {
+ int rowNum = 0;
+ for (Alert alert : result) {
+ // alert history records do not have a usable locatorId, we'll use rownum, which is unique and
+ // may be repeatable.
+ LocatableDynamicForm row = new LocatableDynamicForm(recentAlertsContent.extendLocatorId(String
+ .valueOf(rowNum++)));
+ row.setNumCols(3);
+
+ StaticTextItem iconItem = AbstractActivityView.newTextItemIcon(ImageManager.getAlertIcon(alert
+ .getAlertDefinition().getPriority()), alert.getAlertDefinition().getPriority()
+ .getDisplayName());
+ LinkItem link = AbstractActivityView.newLinkItem(alert.getAlertDefinition().getName() + ": ",
+ ReportDecorator.GWT_GROUP_URL + groupId + "/Alerts/History/" + alert.getId());
+ StaticTextItem time = AbstractActivityView.newTextItem(GwtRelativeDurationConverter
+ .format(alert.getCtime()));
+ row.setItems(iconItem, link, time);
+
+ column.addMember(row);
+ }
+ //link to more details
+ LocatableDynamicForm row = new LocatableDynamicForm(recentAlertsContent.extendLocatorId(String
+ .valueOf(rowNum++)));
+ AbstractActivityView.addSeeMoreLink(row, ReportDecorator.GWT_GROUP_URL + groupId
+ + "/Alerts/History/", column);
+ } else {
+ LocatableDynamicForm row = AbstractActivityView.createEmptyDisplayRow(recentAlertsContent
+ // .extendLocatorId("None"), AbstractActivityView.RECENT_ALERTS_NONE);
+ .extendLocatorId("None"), "No results found using criteria specified.");
+ column.addMember(row);
+ }
+ for (Canvas child : recentAlertsContent.getChildren()) {
+ child.destroy();
+ }
+ recentAlertsContent.addChild(column);
+ recentAlertsContent.markForRedraw();
+ }
+
+ @Override
+ public void onFailure(Throwable caught) {
+ Log.debug("Error retrieving recent alerts for group [" + groupId + "]:" + caught.getMessage());
+ }
+ });
+ }
+
+ protected void loadData() {
+ currentlyLoading = true;
+ getRecentAlerts();
+ }
+
+ @Override
+ public DynamicForm getCustomSettingsForm() {
+ LocatableDynamicForm customSettings = new LocatableDynamicForm(extendLocatorId("customSettings"));
+ LocatableVLayout page = new LocatableVLayout(customSettings.extendLocatorId("page"));
+ //build editor form container
+ final LocatableDynamicForm form = new LocatableDynamicForm(page.extendLocatorId("alert-filter"));
+ form.setMargin(5);
+
+ //add label about what configuration affects
+
+ //add alert priority selector
+ final SelectItem alertPrioritySelector = PortletConfigurationEditorComponent
+ .getAlertPriorityEditor(portletConfig);
+ //add sort priority selector
+ // final SelectItem resultSortSelector = PortletConfigurationEditorComponent
+ // .getResulSortOrderEditor(portletConfig);
+ //add result count selector
+ final SelectItem resultCountSelector = PortletConfigurationEditorComponent.getResultCountEditor(portletConfig);
+ //add range selector
+ final CustomConfigMeasurementRangeEditor measurementRangeEditor = PortletConfigurationEditorComponent
+ .getMeasurementRangeEditor(portletConfig);
+ //TODO: spinder 3/10/11 renable sort selector once it's working in criteria
+ // form.setItems(alertPrioritySelector, resultSortSelector, resultCountSelector);
+ form.setItems(alertPrioritySelector, resultCountSelector);
+
+ //submit handler
+ customSettings.addSubmitValuesHandler(new SubmitValuesHandler() {
+
+ @Override
+ public void onSubmitValues(SubmitValuesEvent event) {
+ //alert severity
+ String selectedValue = alertPrioritySelector.getValue().toString();
+ if ((selectedValue.trim().isEmpty()) || (selectedValue.split(",").length == 3)) {//then no alertPriority specified
+ portletConfig.put(new PropertySimple(Constant.ALERT_PRIORITY, ""));
+ } else {//some subset of available alertPriorities will be used
+ portletConfig.put(new PropertySimple(Constant.ALERT_PRIORITY, selectedValue));
+ }
+ // //result sort order
+ // selectedValue = resultSortSelector.getValue().toString();
+ // if ((selectedValue.trim().isEmpty()) || (selectedValue.equalsIgnoreCase(PageOrdering.DESC.name()))) {//then desc
+ // portletConfig.put(new PropertySimple(Constant.RESULT_SORT_ORDER, PageOrdering.DESC));
+ // } else {
+ // portletConfig.put(new PropertySimple(Constant.RESULT_SORT_ORDER, PageOrdering.ASC));
+ // }
+ //result count
+ selectedValue = resultCountSelector.getValue().toString();
+ if ((selectedValue.trim().isEmpty()) || (selectedValue.equalsIgnoreCase(Constant.RESULT_COUNT_DEFAULT))) {//then 5
+ portletConfig.put(new PropertySimple(Constant.RESULT_COUNT, Constant.RESULT_COUNT_DEFAULT));
+ } else {
+ portletConfig.put(new PropertySimple(Constant.RESULT_COUNT, selectedValue));
+ }
+
+ //alert time range filter. Check for enabled and then persist property. Dealing with compound widget.
+ FormItem item = measurementRangeEditor.getItem(CustomConfigMeasurementRangeEditor.ENABLE_RANGE_ITEM);
+ CheckboxItem itemC = (CheckboxItem) item;
+ selectedValue = String.valueOf(itemC.getValueAsBoolean());
+ if (!selectedValue.trim().isEmpty()) {//then call
+ portletConfig.put(new PropertySimple(Constant.METRIC_RANGE_ENABLE, selectedValue));
+ }
+
+ //alert time advanced time filter enabled.
+ selectedValue = String.valueOf(measurementRangeEditor.isAdvanced());
+ if ((selectedValue != null) && (!selectedValue.trim().isEmpty())) {
+ portletConfig.put(new PropertySimple(Constant.METRIC_RANGE_BEGIN_END_FLAG, selectedValue));
+ }
+
+ //alert time frame
+ List<Long> begEnd = measurementRangeEditor.getBeginEndTimes();
+ if (begEnd.get(0) != 0) {//advanced settings
+ portletConfig.put(new PropertySimple(Constant.METRIC_RANGE, (begEnd.get(0) + "," + begEnd.get(1))));
+ }
+
+ //persist
+ storedPortlet.setConfiguration(portletConfig);
+ configure(portletWindow, storedPortlet);
+ loadData();
+ }
+ });
+ form.markForRedraw();
+ page.addMember(measurementRangeEditor);
+ page.addMember(form);
+ customSettings.addChild(page);
+ return customSettings;
+ }
+
+ @Override
+ public void startRefreshCycle() {
+ //current setting
+ final int refreshInterval = UserSessionManager.getUserPreferences().getPageRefreshInterval();
+
+ //cancel any existing timer
+ if (refreshTimer != null) {
+ refreshTimer.cancel();
+ }
+
+ if (refreshInterval >= MeasurementUtility.MINUTES) {
+
+ refreshTimer = new Timer() {
+ public void run() {
+ if (!currentlyLoading) {
+ loadData();
+ redraw();
+ }
+ }
+ };
+
+ refreshTimer.scheduleRepeating(refreshInterval);
+ }
+ }
+
+ @Override
+ protected void onDestroy() {
+ if (refreshTimer != null) {
+
+ refreshTimer.cancel();
+ }
+ super.onDestroy();
+ }
+
+ @Override
+ public void redraw() {
+ super.redraw();
+ loadData();
+ }
+}
\ No newline at end of file
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/resource/ResourceAlertsPortlet.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/resource/ResourceAlertsPortlet.java
index 53ba926..c79b9f9 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/resource/ResourceAlertsPortlet.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/resource/ResourceAlertsPortlet.java
@@ -36,14 +36,14 @@ import org.rhq.enterprise.gui.coregui.client.dashboard.Portlet;
import org.rhq.enterprise.gui.coregui.client.dashboard.PortletViewFactory;
import org.rhq.enterprise.gui.coregui.client.dashboard.PortletWindow;
import org.rhq.enterprise.gui.coregui.client.dashboard.portlets.PortletConfigurationEditorComponent;
-import org.rhq.enterprise.gui.coregui.client.dashboard.portlets.groups.GroupAlertsPortlet2;
+import org.rhq.enterprise.gui.coregui.client.dashboard.portlets.groups.GroupAlertsPortlet;
import org.rhq.enterprise.gui.coregui.client.dashboard.portlets.recent.alerts.PortletAlertSelector;
import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableVLayout;
/**
* @author Simeon Pinder
*/
-public class ResourceAlertsPortlet extends GroupAlertsPortlet2 {
+public class ResourceAlertsPortlet extends GroupAlertsPortlet {
// A non-displayed, persisted identifier for the portlet
public static final String KEY = "ResourceAlerts";
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/summary/ActivityView2.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/summary/ActivityView2.java
index d819d8b..c57b591 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/summary/ActivityView2.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/summary/ActivityView2.java
@@ -45,7 +45,6 @@ import org.rhq.enterprise.gui.coregui.client.PermissionsLoader;
import org.rhq.enterprise.gui.coregui.client.UserSessionManager;
import org.rhq.enterprise.gui.coregui.client.dashboard.DashboardContainer;
import org.rhq.enterprise.gui.coregui.client.dashboard.DashboardView;
-import org.rhq.enterprise.gui.coregui.client.dashboard.portlets.groups.GroupAlertsPortlet;
import org.rhq.enterprise.gui.coregui.client.dashboard.portlets.util.MessagePortlet;
import org.rhq.enterprise.gui.coregui.client.gwt.DashboardGWTServiceAsync;
import org.rhq.enterprise.gui.coregui.client.gwt.GWTServiceLookup;
@@ -193,9 +192,9 @@ public class ActivityView2 extends LocatableVLayout implements DashboardContaine
// dummyLeft.getConfiguration().put(new PropertySimple("message", "<br/>Coming Soon... :-)"));
// dashboard.addPortlet(dummyLeft, 0, 0);
- DashboardPortlet groupAlerts = new DashboardPortlet(GroupAlertsPortlet.NAME, GroupAlertsPortlet.KEY, 220);
+ // DashboardPortlet groupAlerts = new DashboardPortlet(GroupAlertsPortlet3.NAME, GroupAlertsPortlet3.KEY, 220);
// groupAlerts.getConfiguration().put(new PropertySimple("message", "<br/>Coming Soon... :-)"));
- dashboard.addPortlet(groupAlerts, 0, 0);
+ // dashboard.addPortlet(groupAlerts, 0, 0);
// right Column
DashboardPortlet dummyRight = new DashboardPortlet(MessagePortlet.NAME, MessagePortlet.KEY, 220);
commit fc6850969088d587f4cf8faee4a7b7bc73ec7cdb
Author: Simeon Pinder <spinder(a)redhat.com>
Date: Fri Mar 18 08:25:05 2011 -0400
i)fix problem with time range not reloading settings correctly
ii)enable duplicate portlets on dashboard.
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/measurement/AbstractMeasurementRangeEditor.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/measurement/AbstractMeasurementRangeEditor.java
index 82be574..d8c69b8 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/measurement/AbstractMeasurementRangeEditor.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/measurement/AbstractMeasurementRangeEditor.java
@@ -48,9 +48,9 @@ import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableDynamicForm;
public abstract class AbstractMeasurementRangeEditor extends LocatableDynamicForm implements TableWidget {
//keyed map of translated date units Ex. minutes,hours,days
- private static LinkedHashMap<String, String> lastUnits;
+ protected static LinkedHashMap<String, String> lastUnits;
//array of values available for displaying/selecting 'last N hours|minutes|days'.
- private static String[] lastValues;
+ protected static String[] lastValues;
protected boolean advanced;
private ButtonItem advancedSimpleButton;
@@ -222,7 +222,7 @@ public abstract class AbstractMeasurementRangeEditor extends LocatableDynamicFor
}
}
- private void update() {
+ protected void update() {
if (advanced) {
advancedSimpleButton.setTitle(MSG.view_measureRange_simple());
showItem("start");
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/measurement/CustomConfigMeasurementRangeEditor.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/measurement/CustomConfigMeasurementRangeEditor.java
index f4e9a0e..01794cb 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/measurement/CustomConfigMeasurementRangeEditor.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/measurement/CustomConfigMeasurementRangeEditor.java
@@ -19,6 +19,7 @@
package org.rhq.enterprise.gui.coregui.client.components.measurement;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
import org.rhq.core.domain.configuration.Configuration;
@@ -59,6 +60,8 @@ public class CustomConfigMeasurementRangeEditor extends AbstractMeasurementRange
} else {
int lastN = Integer.valueOf(simpleLastValuesItem.getValueAsString());
String unit = simpleLastUnitsItem.getValueAsString();
+ measurementPrefs.metricRangePreferences.lastN = lastN;
+ measurementPrefs.metricRangePreferences.unit = Integer.valueOf(unit);
return MeasurementUtility.calculateTimeFrame(lastN, Integer.valueOf(unit));
}
}
@@ -108,7 +111,11 @@ public class CustomConfigMeasurementRangeEditor extends AbstractMeasurementRange
config.getSimple(PREF_METRIC_RANGE_BEGIN_END_FLAG).getStringValue()).booleanValue();
//check to display advanced settings widget components
if (metricRangePreferences.explicitBeginEnd == false) {
+ //retrieve lastN
metricRangePreferences.lastN = config.getSimple(PREF_METRIC_RANGE_LASTN).getIntegerValue();
+ //retrieve lastN units
+ metricRangePreferences.unit = config.getSimple(PREF_METRIC_RANGE_UNIT).getIntegerValue();
+
List<Long> range = MeasurementUtility.calculateTimeFrame(metricRangePreferences.lastN,
metricRangePreferences.unit);
metricRangePreferences.begin = range.get(0);
@@ -170,10 +177,21 @@ public class CustomConfigMeasurementRangeEditor extends AbstractMeasurementRange
enableRangeItem.setValue(false);
enableMeasurementRange(true);
}
- //AlertMetric rangeValues
- cp = measurementPrefs.configuration.getSimple(PREF_METRIC_RANGE);
- if ((cp != null) && (!cp.getStringValue().trim().isEmpty())) {
- String metricRange = cp.getStringValue();
+ //is advanced
+ boolean advanced = measurementPrefs.metricRangePreferences.explicitBeginEnd;
+ if (advanced) {
+ ArrayList<Long> beginEnd = measurementPrefs.metricRangePreferences.getBeginEndTimes();
+ if ((beginEnd != null) && (!beginEnd.isEmpty())) {
+ advancedStartItem.setValue(beginEnd.get(0));
+ advancedEndItem.setValue(beginEnd.get(1));
+ }
+ } else {//simple: set LastN and Units
+ if (lastUnits.containsKey(String.valueOf(measurementPrefs.metricRangePreferences.unit))) {
+ simpleLastUnitsItem.setValue(String.valueOf(measurementPrefs.metricRangePreferences.unit));
+ }
+ if (Arrays.asList(lastValues).contains(String.valueOf(measurementPrefs.metricRangePreferences.lastN))) {
+ simpleLastValuesItem.setValue(String.valueOf(measurementPrefs.metricRangePreferences.lastN));
+ }
}
}
}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/DashboardView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/DashboardView.java
index 384895d..25923ba 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/DashboardView.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/DashboardView.java
@@ -244,12 +244,12 @@ public class DashboardView extends LocatableVLayout {
//if resourceGroup passed in then add additional portlets to list
if (this.focusGroup != null) {
HashMap<String, String> groupKeyNameMap = PortletFactory.getRegisteredGroupPortletNameMap();
- //find current list of portlets already stored. Exclude them
- for (DashboardPortlet currentPortlet : storedDashboard.getPortlets()) {
- if (groupKeyNameMap.containsKey(currentPortlet.getPortletKey())) {
- groupKeyNameMap.remove(currentPortlet.getPortletKey());
- }
- }
+ // //find current list of portlets already stored. Exclude them
+ // for (DashboardPortlet currentPortlet : storedDashboard.getPortlets()) {
+ // if (groupKeyNameMap.containsKey(currentPortlet.getPortletKey())) {
+ // groupKeyNameMap.remove(currentPortlet.getPortletKey());
+ // }
+ // }
//TODO: spinder 3/16/11: still need to be done.
//filter out portlets not relevent for group(compat|mixed) or facets
@@ -261,12 +261,12 @@ public class DashboardView extends LocatableVLayout {
//if resource passed in then add additional portlets to list
if (this.focusResource != null) {
HashMap<String, String> resourceKeyNameMap = PortletFactory.getRegisteredResourcePortletNameMap();
- //find current list of portlets already stored. Exclude them
- for (DashboardPortlet currentPortlet : storedDashboard.getPortlets()) {
- if (resourceKeyNameMap.containsKey(currentPortlet.getPortletKey())) {
- resourceKeyNameMap.remove(currentPortlet.getPortletKey());
- }
- }
+ // //find current list of portlets already stored. Exclude them
+ // for (DashboardPortlet currentPortlet : storedDashboard.getPortlets()) {
+ // if (resourceKeyNameMap.containsKey(currentPortlet.getPortletKey())) {
+ // resourceKeyNameMap.remove(currentPortlet.getPortletKey());
+ // }
+ // }
for (String portletKey : resourceKeyNameMap.keySet()) {
nameKeyMap.put(resourceKeyNameMap.get(portletKey), portletKey);
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/groups/GroupOperationsPortlet.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/groups/GroupOperationsPortlet.java
index 072d82c..d840bcc 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/groups/GroupOperationsPortlet.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/groups/GroupOperationsPortlet.java
@@ -59,11 +59,10 @@ import org.rhq.enterprise.gui.coregui.client.dashboard.portlets.PortletConfigura
import org.rhq.enterprise.gui.coregui.client.dashboard.portlets.PortletConfigurationEditorComponent.Constant;
import org.rhq.enterprise.gui.coregui.client.gwt.GWTServiceLookup;
import org.rhq.enterprise.gui.coregui.client.inventory.common.detail.operation.history.AbstractOperationHistoryDataSource;
-import org.rhq.enterprise.gui.coregui.client.inventory.common.detail.operation.history.AbstractOperationHistoryListView;
import org.rhq.enterprise.gui.coregui.client.inventory.common.detail.summary.AbstractActivityView;
import org.rhq.enterprise.gui.coregui.client.inventory.groups.detail.ResourceGroupDetailView;
import org.rhq.enterprise.gui.coregui.client.inventory.groups.detail.operation.history.GroupOperationHistoryDataSource;
-import org.rhq.enterprise.gui.coregui.client.inventory.groups.detail.operation.history.GroupOperationHistoryDetailsView;
+import org.rhq.enterprise.gui.coregui.client.inventory.groups.detail.operation.history.GroupOperationHistoryListView;
import org.rhq.enterprise.gui.coregui.client.util.MeasurementUtility;
import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableCanvas;
import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableDynamicForm;
@@ -347,36 +346,17 @@ public class GroupOperationsPortlet extends LocatableVLayout implements CustomSe
*
* @author spinder
*/
-class GroupOperationsCriteriaHistoryListView extends AbstractOperationHistoryListView {
-
- private AbstractOperationHistoryDataSource datasource;
+class GroupOperationsCriteriaHistoryListView extends GroupOperationHistoryListView {
public GroupOperationsCriteriaHistoryListView(String locatorId, AbstractOperationHistoryDataSource dataSource,
String title, Criteria criteria, ResourceGroupComposite composite) {
- super(locatorId, dataSource, title, criteria);
- this.datasource = dataSource;
- this.groupComposite = composite;
+ super(locatorId, composite);
+ setDataSource(dataSource);
setShowFooterRefresh(false); //disable footer refresh
}
- private ResourceGroupComposite groupComposite;
-
- @Override
- protected boolean hasControlPermission() {
- return this.groupComposite.getResourcePermission().isControl();
- }
-
- @Override
- public Canvas getDetailsView(int id) {
- return new GroupOperationHistoryDetailsView(extendLocatorId("DetailsView"), this.groupComposite);
- }
-
- public AbstractOperationHistoryDataSource getDatasource() {
- return datasource;
- }
-
public void setDatasource(AbstractOperationHistoryDataSource datasource) {
- this.datasource = datasource;
+ setDataSource(datasource);
}
@Override
@@ -405,8 +385,10 @@ class GroupOperationsCriteriaDataSource extends GroupOperationHistoryDataSource
@Override
protected void executeFetch(final DSRequest request, final DSResponse response) {
+ //initialize criteria
GroupOperationHistoryCriteria criteria = new GroupOperationHistoryCriteria();
+ //retrieve group identifier
if (request.getCriteria().getValues().containsKey(CriteriaField.GROUP_ID)) {
int groupId = Integer.parseInt((String) request.getCriteria().getValues().get(CriteriaField.GROUP_ID));
criteria.addFilterResourceGroupIds(Arrays.asList(groupId));
@@ -431,12 +413,34 @@ class GroupOperationsCriteriaDataSource extends GroupOperationHistoryDataSource
//result timeframe if enabled
property = portletConfig.getSimple(Constant.METRIC_RANGE_ENABLE);
if (Boolean.valueOf(property.getBooleanValue())) {//then proceed setting
- property = portletConfig.getSimple(Constant.METRIC_RANGE);
+
+ boolean isAdvanced = false;
+ //detect type of widget[Simple|Advanced]
+ property = portletConfig.getSimple(Constant.METRIC_RANGE_BEGIN_END_FLAG);
if (property != null) {
- String currentSetting = property.getStringValue();
- String[] range = currentSetting.split(",");
- criteria.addFilterStartTime(Long.valueOf(range[0]));
- criteria.addFilterEndTime(Long.valueOf(range[1]));
+ isAdvanced = property.getBooleanValue();
+ }
+ if (isAdvanced) {
+ //Advanced time settings
+ property = portletConfig.getSimple(Constant.METRIC_RANGE);
+ if (property != null) {
+ String currentSetting = property.getStringValue();
+ String[] range = currentSetting.split(",");
+ criteria.addFilterStartTime(Long.valueOf(range[0]));
+ criteria.addFilterEndTime(Long.valueOf(range[1]));
+ }
+ } else {
+ //Simple time settings
+ property = portletConfig.getSimple(Constant.METRIC_RANGE_LASTN);
+ if (property != null) {
+ int lastN = property.getIntegerValue();
+ property = portletConfig.getSimple(Constant.METRIC_RANGE_UNIT);
+ int lastUnits = property.getIntegerValue();
+ ArrayList<Long> beginEnd = MeasurementUtility.calculateTimeFrame(lastN, Integer
+ .valueOf(lastUnits));
+ criteria.addFilterStartTime(Long.valueOf(beginEnd.get(0)));
+ criteria.addFilterEndTime(Long.valueOf(beginEnd.get(1)));
+ }
}
}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/detail/summary/AbstractActivityView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/detail/summary/AbstractActivityView.java
index 37b0052..f9fae66 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/detail/summary/AbstractActivityView.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/detail/summary/AbstractActivityView.java
@@ -524,15 +524,23 @@ public abstract class AbstractActivityView extends LocatableVLayout implements R
}
//time advanced time filter enabled.
+ boolean isAdvanceTimeSetting = false;
selectedValue = String.valueOf(measurementRangeEditor.isAdvanced());
if ((selectedValue != null) && (!selectedValue.trim().isEmpty())) {
portletConfig.put(new PropertySimple(Constant.METRIC_RANGE_BEGIN_END_FLAG, selectedValue));
+ isAdvanceTimeSetting = Boolean.valueOf(selectedValue);
}
//time frame
List<Long> begEnd = measurementRangeEditor.getBeginEndTimes();
- if (begEnd.get(0) != 0) {//advanced settings
+ if (isAdvanceTimeSetting) {//advanced settings
portletConfig.put(new PropertySimple(Constant.METRIC_RANGE, (begEnd.get(0) + "," + begEnd.get(1))));
+ } else {
+ //save not advanced time range
+ portletConfig.put(new PropertySimple(Constant.METRIC_RANGE_LASTN, measurementRangeEditor
+ .getMetricRangePreferences().lastN));
+ portletConfig.put(new PropertySimple(Constant.METRIC_RANGE_UNIT, measurementRangeEditor
+ .getMetricRangePreferences().unit));
}
}
return portletConfig;
commit f5920e31ffb0e47f5113679938029d1fe240279d
Author: Simeon Pinder <spinder(a)redhat.com>
Date: Thu Mar 17 16:46:35 2011 -0400
i)D12N problem with Group alerts portlet.
ii)Have GroupOperationsPortlet fill it's portlet.
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/AlertPortletConfigurationDataSource.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/AlertPortletConfigurationDataSource.java
index 8ebfed5..39f2f52 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/AlertPortletConfigurationDataSource.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/AlertPortletConfigurationDataSource.java
@@ -26,6 +26,7 @@ import com.smartgwt.client.rpc.RPCResponse;
import org.rhq.core.domain.alert.Alert;
import org.rhq.core.domain.alert.AlertPriority;
+import org.rhq.core.domain.common.EntityContext;
import org.rhq.core.domain.configuration.Configuration;
import org.rhq.core.domain.configuration.Property;
import org.rhq.core.domain.configuration.PropertyList;
@@ -53,6 +54,7 @@ public class AlertPortletConfigurationDataSource extends AlertDataSource {
private Integer groupId = null;
private Integer[] resourceIds = null;
private String alertResourcesToUse;
+ private EntityContext entityContext;
public AlertPortletConfigurationDataSource() {
super();
@@ -65,6 +67,11 @@ public class AlertPortletConfigurationDataSource extends AlertDataSource {
this.configuration = configuration;
this.groupId = groupId;
this.resourceIds = resourceIds;
+ if (groupId != null) {
+ entityContext = EntityContext.forGroup(groupId);
+ } else if ((resourceIds != null) && (resourceIds.length > 0)) {
+ entityContext = EntityContext.forResource(resourceIds[0]);
+ }
}
/** Override the executeFetch for AlertPortlet to allow specifying smaller than total
@@ -155,9 +162,13 @@ public class AlertPortletConfigurationDataSource extends AlertDataSource {
public void onSuccess(PageList<Alert> result) {
long fetchTime = System.currentTimeMillis() - start;
Log.info(result.size() + " alerts fetched in: " + fetchTime + "ms");
- response.setData(buildRecords(result));
- response.setTotalRows(result.size());
- processResponse(request.getRequestId(), response);
+ if (entityContext.type != EntityContext.Type.Resource) {
+ dataRetrieved(result, response, request);
+ } else {
+ response.setData(buildRecords(result));
+ response.setTotalRows(result.size());
+ processResponse(request.getRequestId(), response);
+ }
}
});
}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/groups/GroupOperationsPortlet.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/groups/GroupOperationsPortlet.java
index 0a7bc76..072d82c 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/groups/GroupOperationsPortlet.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/groups/GroupOperationsPortlet.java
@@ -190,8 +190,10 @@ public class GroupOperationsPortlet extends LocatableVLayout implements CustomSe
protected void initializeUi() {
setPadding(5);
setMembersMargin(5);
- setHeight100();
+ setHeight("*");
setWidth100();
+ //tell canvas to fill it's component
+ recentOperationsContent.setHeight100();
addMember(recentOperationsContent);
markForRedraw();
}
13 years, 3 months
[rhq] modules/enterprise
by mazz
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/Footer.java | 25 ++
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/message/MessageCenterView.java | 89 ++--------
2 files changed, 43 insertions(+), 71 deletions(-)
New commits:
commit 2e233f7d30e19118e7052a36443d35d9d7032873
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Fri Mar 18 17:13:06 2011 -0400
reuse the message center window - don't keep re-creating it.
this avoids selenium ID conflicts and is much snappier when clicking the message center button
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/Footer.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/Footer.java
index c61ff23..2f31bb8 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/Footer.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/Footer.java
@@ -38,7 +38,9 @@ import org.rhq.enterprise.gui.coregui.client.report.ReportTopView;
import org.rhq.enterprise.gui.coregui.client.util.message.MessageBar;
import org.rhq.enterprise.gui.coregui.client.util.message.MessageCenterView;
import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableHLayout;
+import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableIButton;
import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableLabel;
+import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableVLayout;
/**
* @author Greg Hinkle
@@ -82,13 +84,34 @@ public class Footer extends LocatableHLayout {
favoritesLayout.addMember(favoritesButton);
addMember(favoritesLayout);
- addMember(messageCenter.getMessageCenterButton());
+ addMember(getMessageCenterButton());
addMember(createHSpacer(0));
alertsMessage.schedule(60000);
}
+ private LocatableVLayout getMessageCenterButton() {
+ LocatableVLayout layout = new LocatableVLayout(extendLocatorId("layout"));
+ layout.setMembersMargin(5);
+ layout.setHeight100();
+ layout.setAlign(Alignment.CENTER);
+ layout.setAutoWidth();
+
+ LocatableIButton button = new LocatableIButton(extendLocatorId("button"), MSG.view_messageCenter_messageTitle());
+ button.setAlign(Alignment.CENTER);
+ button.setAutoFit(true);
+ button.addClickHandler(new com.smartgwt.client.widgets.events.ClickHandler() {
+ @Override
+ public void onClick(ClickEvent event) {
+ messageCenter.showMessageCenterWindow();
+ }
+ });
+
+ layout.addMember(button);
+ return layout;
+ }
+
public abstract static class RefreshableLabel extends LocatableLabel {
public RefreshableLabel(String locatorId) {
super(locatorId);
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/message/MessageCenterView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/message/MessageCenterView.java
index cdf116b..df35e27 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/message/MessageCenterView.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/message/MessageCenterView.java
@@ -31,10 +31,7 @@ import com.smartgwt.client.types.SelectionStyle;
import com.smartgwt.client.types.SortDirection;
import com.smartgwt.client.types.TimeFormatter;
import com.smartgwt.client.types.VerticalAlignment;
-import com.smartgwt.client.widgets.Canvas;
-import com.smartgwt.client.widgets.IButton;
import com.smartgwt.client.widgets.Window;
-import com.smartgwt.client.widgets.events.ClickEvent;
import com.smartgwt.client.widgets.events.CloseClickHandler;
import com.smartgwt.client.widgets.events.CloseClientEvent;
import com.smartgwt.client.widgets.events.DoubleClickEvent;
@@ -47,7 +44,6 @@ import com.smartgwt.client.widgets.grid.ListGrid;
import com.smartgwt.client.widgets.grid.ListGridField;
import com.smartgwt.client.widgets.grid.ListGridRecord;
import com.smartgwt.client.widgets.grid.SortNormalizer;
-import com.smartgwt.client.widgets.layout.Layout;
import org.rhq.enterprise.gui.coregui.client.CoreGUI;
import org.rhq.enterprise.gui.coregui.client.components.table.AbstractTableAction;
@@ -55,8 +51,6 @@ import org.rhq.enterprise.gui.coregui.client.components.table.Table;
import org.rhq.enterprise.gui.coregui.client.components.table.TableActionEnablement;
import org.rhq.enterprise.gui.coregui.client.util.message.Message.Severity;
import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableDynamicForm;
-import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableIButton;
-import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableVLayout;
import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableWindow;
/**
@@ -65,10 +59,6 @@ import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableWindow;
* also be displayed in its own non-modal dialog window. If you want this table
* shown in a dialog window, call {@link #showMessageCenterWindow()}.
*
- * This Table also can provide a standalone button that you can add to any layout,
- * see {@link #getMessageCenterButton()}. The button, when pressed, will popup
- * the dialog message window as explained above.
- *
* Note: this class has to be very careful about catching any and all exceptions.
* Otherwise, an uncaught exception will cause a flooding of global exception
* messages (since the unhandled exception handler in CoreGUI will recursively
@@ -87,12 +77,11 @@ public class MessageCenterView extends Table implements MessageCenter.MessageLis
private static final String FIELD_CONCISEMESSAGE = "conciseMessage";
private static final String FIELD_OBJECT = "object";
- private Layout messageCenterButton;
private MessageCenterWindow window;
public MessageCenterView(String locatorId) {
- super(locatorId, MSG.view_messageCenter_messageTitle(), new SortSpecifier[] { new SortSpecifier(FIELD_TIME,
- SortDirection.DESCENDING) });
+ super(locatorId, MSG.view_messageCenter_messageTitle(), null, new SortSpecifier[] { new SortSpecifier(
+ FIELD_TIME, SortDirection.DESCENDING) }, null, false);
CoreGUI.getMessageCenter().addMessageListener(this);
}
@@ -107,38 +96,6 @@ public class MessageCenterView extends Table implements MessageCenter.MessageLis
}
}
- /**
- * Returns a button enclosed in a layout. When the button is pressed, the
- * Message Center non-modal dialog window will popup.
- *
- * To press the button programmatically (i.e. to popup the message center window),
- * call {@link #showMessageCenterWindow()}.
- *
- * @return layout enclosing the button to popup the message center window
- */
- public Layout getMessageCenterButton() {
- if (messageCenterButton == null) {
- messageCenterButton = new LocatableVLayout(extendLocatorId("layout"));
- messageCenterButton.setMembersMargin(5);
- messageCenterButton.setHeight100();
- messageCenterButton.setAlign(Alignment.CENTER);
- messageCenterButton.setAutoWidth();
-
- IButton button = new LocatableIButton(extendLocatorId("button"), MSG.view_messageCenter_messageTitle());
- button.setAlign(Alignment.CENTER);
- button.setAutoFit(true);
- button.addClickHandler(new com.smartgwt.client.widgets.events.ClickHandler() {
- @Override
- public void onClick(ClickEvent event) {
- showMessageCenterWindow();
- }
- });
-
- messageCenterButton.addMember(button);
- }
- return messageCenterButton;
- }
-
private Window createWindow() {
if (window == null) {
window = new MessageCenterWindow("MessageCenterViewWindow");
@@ -147,17 +104,9 @@ public class MessageCenterView extends Table implements MessageCenter.MessageLis
@Override
public void onCloseClick(CloseClientEvent event) {
try {
- // try really really hard to make selenium ID generation happy (TODO: it still doesn't)
- Canvas[] members = MessageCenterView.this.getMembers();
- for (Canvas member : members) {
- member.destroy();
- }
- MessageCenterView.this.destroy();
- window.destroy();
+ window.hide();
} catch (Throwable e) {
Log.warn("Cannot destroy message center", e);
- } finally {
- window = null;
}
}
});
@@ -296,7 +245,7 @@ public class MessageCenterView extends Table implements MessageCenter.MessageLis
maxMessagesMap.put("50", Integer.valueOf("50"));
maxMessagesMap.put("100", Integer.valueOf("100"));
maxMessagesMap.put("200", Integer.valueOf("200"));
- addTableAction(extendLocatorId("maxMessageMeny"), MSG.view_messageCenter_maxMessages(), null, maxMessagesMap,
+ addTableAction(extendLocatorId("maxMessageMenu"), MSG.view_messageCenter_maxMessages(), null, maxMessagesMap,
new AbstractTableAction(TableActionEnablement.ALWAYS) {
@Override
public void executeAction(ListGridRecord[] selection, Object actionValue) {
@@ -317,7 +266,7 @@ public class MessageCenterView extends Table implements MessageCenter.MessageLis
new AbstractTableAction(TableActionEnablement.ALWAYS) {
@Override
public void executeAction(ListGridRecord[] selection, Object actionValue) {
- for (Severity severity : EnumSet.allOf(Severity.class)) {
+ for (Severity severity : java.util.EnumSet.allOf(Severity.class)) {
Message m = new Message(severity.name() + ':' + System.currentTimeMillis(), severity);
CoreGUI.getMessageCenter().notify(m);
}
@@ -389,22 +338,22 @@ public class MessageCenterView extends Table implements MessageCenter.MessageLis
form.setItems(title, severity, date, detail);
- final Window window = new LocatableWindow(this.extendLocatorId("MessageWindow"));
- window.setTitle(MSG.common_title_message());
- window.setWidth(600);
- window.setHeight(400);
- window.setIsModal(true);
- window.setShowModalMask(true);
- window.setCanDragResize(true);
- window.setShowMaximizeButton(true);
- window.setShowMinimizeButton(false);
- window.centerInPage();
- window.addItem(form);
- window.show();
- window.addCloseClickHandler(new CloseClickHandler() {
+ final Window dialogWin = new LocatableWindow(this.extendLocatorId("MessageWindow"));
+ dialogWin.setTitle(MSG.common_title_message());
+ dialogWin.setWidth(600);
+ dialogWin.setHeight(400);
+ dialogWin.setIsModal(true);
+ dialogWin.setShowModalMask(true);
+ dialogWin.setCanDragResize(true);
+ dialogWin.setShowMaximizeButton(true);
+ dialogWin.setShowMinimizeButton(false);
+ dialogWin.centerInPage();
+ dialogWin.addItem(form);
+ dialogWin.show();
+ dialogWin.addCloseClickHandler(new CloseClickHandler() {
@Override
public void onCloseClick(CloseClientEvent event) {
- window.destroy();
+ dialogWin.destroy();
}
});
}
13 years, 3 months
[rhq] modules/enterprise
by mazz
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/CoreGUI.java | 9
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/Footer.java | 9
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/message/Message.java | 1
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/message/MessageCenter.java | 26
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/message/MessageCenterView.java | 433 ++++++++--
modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages.properties | 7
6 files changed, 398 insertions(+), 87 deletions(-)
New commits:
commit f40a6a433eadce7ba15f5a7213e3d64eb3d84b4c
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Fri Mar 18 16:17:24 2011 -0400
BZ 681355 new window message center
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/CoreGUI.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/CoreGUI.java
index 41af140..3fe259e 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/CoreGUI.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/CoreGUI.java
@@ -143,6 +143,15 @@ public class CoreGUI implements EntryPoint, ValueChangeHandler<String> {
}
});
+ KeyIdentifier messageCenterWindowKey = new KeyIdentifier();
+ messageCenterWindowKey.setCtrlKey(true);
+ messageCenterWindowKey.setKeyName("M");
+ Page.registerKey(messageCenterWindowKey, new KeyCallback() {
+ public void execute(String keyName) {
+ footer.getMessageCenter().showMessageCenterWindow();
+ }
+ });
+
GWT.setUncaughtExceptionHandler(new GWT.UncaughtExceptionHandler() {
public void onUncaughtException(Throwable e) {
getErrorHandler().handleError(MSG.view_core_uncaught(), e);
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/Footer.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/Footer.java
index 1cfdd50..c61ff23 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/Footer.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/Footer.java
@@ -48,6 +48,7 @@ public class Footer extends LocatableHLayout {
private static final String LOCATOR_ID = "CoreFooter";
private MessageBar messageBar;
+ private MessageCenterView messageCenter;
public Footer() {
super(LOCATOR_ID);
@@ -62,7 +63,7 @@ public class Footer extends LocatableHLayout {
protected void onDraw() {
super.onDraw();
- final MessageCenterView messageCenter = new MessageCenterView(extendLocatorId(MessageCenterView.LOCATOR_ID));
+ messageCenter = new MessageCenterView(extendLocatorId(MessageCenterView.LOCATOR_ID));
final FavoritesButton favoritesButton = new FavoritesButton(extendLocatorId("Favorites"));
final AlertsMessage alertsMessage = new AlertsMessage(extendLocatorId("Alerts"));
messageBar = new MessageBar();
@@ -81,7 +82,7 @@ public class Footer extends LocatableHLayout {
favoritesLayout.addMember(favoritesButton);
addMember(favoritesLayout);
- addMember(messageCenter);
+ addMember(messageCenter.getMessageCenterButton());
addMember(createHSpacer(0));
@@ -171,6 +172,10 @@ public class Footer extends LocatableHLayout {
return messageBar;
}
+ public MessageCenterView getMessageCenter() {
+ return messageCenter;
+ }
+
private HLayout createHSpacer(int width) {
HLayout spacer = new HLayout();
spacer.setWidth(width);
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/message/Message.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/message/Message.java
index 96e1740..91ae345 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/message/Message.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/message/Message.java
@@ -38,6 +38,7 @@ public class Message {
// TODO: Add Debug severity?
public enum Severity {
+ // keep the order - the ordinals are sorted least severe to highest severe
Blank("InfoBlank", "info/icn_info_blank.png"), //
Info("InfoBlock", "info/icn_info_blue.png"), //
Warning("WarnBlock", "info/icn_info_orange.png"), //
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/message/MessageCenter.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/message/MessageCenter.java
index 1a4845d..d9fba53 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/message/MessageCenter.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/message/MessageCenter.java
@@ -32,14 +32,15 @@ public class MessageCenter {
private LinkedList<Message> messages = new LinkedList<Message>();
private List<MessageListener> listeners = new ArrayList<MessageListener>();
- private static final int MAX_MESSAGES = 50;
+ private int maxMessages = 50;
public void notify(Message message) {
log(message);
if (!message.isTransient()) {
- this.messages.add(message);
- if (messages.size() > MAX_MESSAGES) {
- messages.removeFirst();
+ // put the newest messages up front; old messages are at the end
+ this.messages.addFirst(message);
+ if (messages.size() > maxMessages) {
+ messages.removeLast(); // we should only have 1 extra, so removeLast should remove all extras
}
}
for (MessageListener listener : listeners) {
@@ -51,6 +52,18 @@ public class MessageCenter {
this.listeners.add(listener);
}
+ public int getMaxMessages() {
+ return maxMessages;
+ }
+
+ public void setMaxMessages(int max) {
+ // if we are shrinking the list, clip the extra, older, messages
+ if (max < this.maxMessages && messages.size() > max) {
+ messages.subList(max, messages.size()).clear();
+ }
+ this.maxMessages = max;
+ }
+
/**
* Returns a list of recently published non-transient messages.
*
@@ -65,7 +78,8 @@ public class MessageCenter {
}
private void log(Message message) {
- String formattedMessage = "On " + message.getFired() + ", MessageCenter received " + message.getConciseMessage();
+ String formattedMessage = "At [" + message.getFired() + "] MessageCenter received: "
+ + message.getConciseMessage();
if (message.severity == Message.Severity.Info) {
Log.info(formattedMessage);
} else if (message.severity == Message.Severity.Warning) {
@@ -78,5 +92,5 @@ public class MessageCenter {
Log.debug(formattedMessage);
}
}
-
+
}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/message/MessageCenterView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/message/MessageCenterView.java
index 1891bd4..cdf116b 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/message/MessageCenterView.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/message/MessageCenterView.java
@@ -18,110 +18,352 @@
*/
package org.rhq.enterprise.gui.coregui.client.util.message;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.List;
+
+import com.allen_sauer.gwt.log.client.Log;
+import com.google.gwt.user.client.Timer;
+import com.smartgwt.client.data.SortSpecifier;
import com.smartgwt.client.types.Alignment;
+import com.smartgwt.client.types.ListGridFieldType;
+import com.smartgwt.client.types.SelectionStyle;
+import com.smartgwt.client.types.SortDirection;
+import com.smartgwt.client.types.TimeFormatter;
import com.smartgwt.client.types.VerticalAlignment;
+import com.smartgwt.client.widgets.Canvas;
+import com.smartgwt.client.widgets.IButton;
import com.smartgwt.client.widgets.Window;
+import com.smartgwt.client.widgets.events.ClickEvent;
import com.smartgwt.client.widgets.events.CloseClickHandler;
import com.smartgwt.client.widgets.events.CloseClientEvent;
+import com.smartgwt.client.widgets.events.DoubleClickEvent;
+import com.smartgwt.client.widgets.events.DoubleClickHandler;
import com.smartgwt.client.widgets.form.DynamicForm;
import com.smartgwt.client.widgets.form.fields.FormItemIcon;
import com.smartgwt.client.widgets.form.fields.StaticTextItem;
-import com.smartgwt.client.widgets.menu.IMenuButton;
-import com.smartgwt.client.widgets.menu.Menu;
-import com.smartgwt.client.widgets.menu.MenuItem;
-import com.smartgwt.client.widgets.menu.events.ClickHandler;
-import com.smartgwt.client.widgets.menu.events.MenuItemClickEvent;
+import com.smartgwt.client.widgets.grid.HoverCustomizer;
+import com.smartgwt.client.widgets.grid.ListGrid;
+import com.smartgwt.client.widgets.grid.ListGridField;
+import com.smartgwt.client.widgets.grid.ListGridRecord;
+import com.smartgwt.client.widgets.grid.SortNormalizer;
+import com.smartgwt.client.widgets.layout.Layout;
import org.rhq.enterprise.gui.coregui.client.CoreGUI;
+import org.rhq.enterprise.gui.coregui.client.components.table.AbstractTableAction;
+import org.rhq.enterprise.gui.coregui.client.components.table.Table;
+import org.rhq.enterprise.gui.coregui.client.components.table.TableActionEnablement;
+import org.rhq.enterprise.gui.coregui.client.util.message.Message.Severity;
import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableDynamicForm;
-import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableIMenuButton;
-import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableMenu;
+import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableIButton;
import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableVLayout;
import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableWindow;
/**
- * @author Greg Hinkle
+ * Message Center view that shows the latest messages generated by the app.
+ * This is a Table and can therefore be a member to any layout. However, it can
+ * also be displayed in its own non-modal dialog window. If you want this table
+ * shown in a dialog window, call {@link #showMessageCenterWindow()}.
+ *
+ * This Table also can provide a standalone button that you can add to any layout,
+ * see {@link #getMessageCenterButton()}. The button, when pressed, will popup
+ * the dialog message window as explained above.
+ *
+ * Note: this class has to be very careful about catching any and all exceptions.
+ * Otherwise, an uncaught exception will cause a flooding of global exception
+ * messages (since the unhandled exception handler in CoreGUI will recursively
+ * call into this message center).
+ *
+ * @author John Mazzitelli
*/
-public class MessageCenterView extends LocatableVLayout implements MessageCenter.MessageListener {
+@SuppressWarnings("unchecked")
+public class MessageCenterView extends Table implements MessageCenter.MessageListener {
public static final String LOCATOR_ID = "MessageCenter";
+ public static final String TABLE_TITLE = MSG.view_messageCenter_messageTitle();
+
+ private static final String FIELD_TIME = "time";
+ private static final String FIELD_SEVERITY = "severity";
+ private static final String FIELD_CONCISEMESSAGE = "conciseMessage";
+ private static final String FIELD_OBJECT = "object";
- private Menu messagesMenu;
- private IMenuButton messageCenterButton;
- private int messageCount;
+ private Layout messageCenterButton;
+ private MessageCenterWindow window;
public MessageCenterView(String locatorId) {
- super(locatorId, 5);
- setHeight100();
- setAlign(Alignment.CENTER);
- setAutoWidth();
+ super(locatorId, MSG.view_messageCenter_messageTitle(), new SortSpecifier[] { new SortSpecifier(FIELD_TIME,
+ SortDirection.DESCENDING) });
+ CoreGUI.getMessageCenter().addMessageListener(this);
}
- @Override
- protected void onDraw() {
- super.onDraw();
-
- messagesMenu = new LocatableMenu(this.extendLocatorId("Messages"));
+ /**
+ * This will popup a non-modal dialog window with the messages in a list.
+ */
+ public void showMessageCenterWindow() {
+ try {
+ createWindow().show();
+ } catch (Throwable e) {
+ Log.error("Cannot show message center window", e);
+ }
+ }
- messageCenterButton = new LocatableIMenuButton(extendLocatorId("RecentEvents"), MSG
- .view_messageCenter_messageTitle(), messagesMenu);
- messageCenterButton.setAutoFit(true);
+ /**
+ * Returns a button enclosed in a layout. When the button is pressed, the
+ * Message Center non-modal dialog window will popup.
+ *
+ * To press the button programmatically (i.e. to popup the message center window),
+ * call {@link #showMessageCenterWindow()}.
+ *
+ * @return layout enclosing the button to popup the message center window
+ */
+ public Layout getMessageCenterButton() {
+ if (messageCenterButton == null) {
+ messageCenterButton = new LocatableVLayout(extendLocatorId("layout"));
+ messageCenterButton.setMembersMargin(5);
+ messageCenterButton.setHeight100();
+ messageCenterButton.setAlign(Alignment.CENTER);
+ messageCenterButton.setAutoWidth();
- emptyMenu();
- addMember(messageCenterButton);
+ IButton button = new LocatableIButton(extendLocatorId("button"), MSG.view_messageCenter_messageTitle());
+ button.setAlign(Alignment.CENTER);
+ button.setAutoFit(true);
+ button.addClickHandler(new com.smartgwt.client.widgets.events.ClickHandler() {
+ @Override
+ public void onClick(ClickEvent event) {
+ showMessageCenterWindow();
+ }
+ });
- CoreGUI.getMessageCenter().addMessageListener(this);
+ messageCenterButton.addMember(button);
+ }
+ return messageCenterButton;
}
- public void onMessage(final Message message) {
- if (!message.isTransient()) {
- if (messageCount == 0) {
- addClearMenuItem();
- }
- messageCount++;
-
- MenuItem messageItem = new MenuItem(message.conciseMessage, getSeverityIcon(message.severity));
- messageItem.addClickHandler(new ClickHandler() {
+ private Window createWindow() {
+ if (window == null) {
+ window = new MessageCenterWindow("MessageCenterViewWindow");
+ window.addItem(this);
+ window.addCloseClickHandler(new CloseClickHandler() {
@Override
- public void onClick(MenuItemClickEvent event) {
- showDetails(message);
+ public void onCloseClick(CloseClientEvent event) {
+ try {
+ // try really really hard to make selenium ID generation happy (TODO: it still doesn't)
+ Canvas[] members = MessageCenterView.this.getMembers();
+ for (Canvas member : members) {
+ member.destroy();
+ }
+ MessageCenterView.this.destroy();
+ window.destroy();
+ } catch (Throwable e) {
+ Log.warn("Cannot destroy message center", e);
+ } finally {
+ window = null;
+ }
}
});
- messagesMenu.addItem(messageItem, 2); // put this just below the "clear all msgs" item and the separator
-
- // to avoid flooding the message center, clip old messages
- final int maxMessages = 25;
- if (messageCount > maxMessages) {
- MenuItem[] items = messagesMenu.getItems();
- MenuItem[] clippedItems = new MenuItem[maxMessages + 2]; // +2 to take into account the Clear All Messages item and the separator
- System.arraycopy(items, 0, clippedItems, 0, clippedItems.length);
- messagesMenu.setItems(clippedItems);
+ }
+
+ return window;
+ }
+
+ @Override
+ public void onMessage(final Message message) {
+ try {
+ if (!message.isTransient()) {
+ refresh();
+ if (window != null) {
+ window.blink();
+ }
}
+ } catch (Throwable e) {
+ Log.error("Cannot process message", e);
}
}
- private void addClearMenuItem() {
- MenuItem clearItem = new MenuItem(MSG.view_messageCenter_clearAllMessages());
- clearItem.addClickHandler(new com.smartgwt.client.widgets.menu.events.ClickHandler() {
+ @Override
+ protected void configureTable() {
+ getListGrid().setEmptyMessage(MSG.view_messageCenter_noRecentMessages());
+
+ setTableTitle(MSG.view_messageCenter_lastNMessages(String.valueOf(CoreGUI.getMessageCenter().getMaxMessages())));
+
+ ListGridField severityField = new ListGridField(FIELD_SEVERITY);
+ severityField.setType(ListGridFieldType.ICON);
+ severityField.setAlign(Alignment.CENTER);
+ severityField.setShowValueIconOnly(true);
+ HashMap<String, String> severityIcons = new HashMap<String, String>(5);
+ severityIcons.put(Severity.Blank.name(), getSeverityIcon(Severity.Blank));
+ severityIcons.put(Severity.Info.name(), getSeverityIcon(Severity.Info));
+ severityIcons.put(Severity.Warning.name(), getSeverityIcon(Severity.Warning));
+ severityIcons.put(Severity.Error.name(), getSeverityIcon(Severity.Error));
+ severityIcons.put(Severity.Fatal.name(), getSeverityIcon(Severity.Fatal));
+ severityField.setValueIcons(severityIcons);
+ severityField.setShowHover(true);
+ severityField.setHoverCustomizer(new HoverCustomizer() {
+ @Override
+ public String hoverHTML(Object value, ListGridRecord record, int rowNum, int colNum) {
+ try {
+ Severity severity = ((Message) record.getAttributeAsObject(FIELD_OBJECT)).getSeverity();
+ switch (severity) {
+ case Info:
+ return MSG.common_severity_info();
+ case Warning:
+ return MSG.common_severity_warn();
+ case Error:
+ return MSG.common_severity_error();
+ case Fatal:
+ return MSG.common_severity_fatal();
+ }
+ } catch (Throwable e) {
+ Log.error("Cannot get severity hover", e);
+ }
+ return null;
+ }
+ });
+ severityField.setSortNormalizer(new SortNormalizer() {
+ @Override
+ public Object normalize(ListGridRecord record, String fieldName) {
+ try {
+ Severity severity = ((Message) record.getAttributeAsObject(FIELD_OBJECT)).getSeverity();
+ return Integer.valueOf(severity.ordinal());
+ } catch (Throwable e) {
+ Log.error("Cannot get sort nomalizer", e);
+ }
+ return Integer.valueOf(0);
+ }
+ });
+
+ ListGridField timeField = new ListGridField(FIELD_TIME, MSG.view_messageCenter_messageTime());
+ timeField.setType(ListGridFieldType.TIME);
+ timeField.setAttribute("displayFormat", TimeFormatter.TOPADDEDTIME);
+ timeField.setAlign(Alignment.LEFT);
+
+ ListGridField messageField = new ListGridField(FIELD_CONCISEMESSAGE, MSG.common_title_message());
+
+ severityField.setWidth(25);
+ timeField.setWidth("15%");
+ messageField.setWidth("*");
+
+ getListGrid().setFields(severityField, timeField, messageField);
+
+ setListGridDoubleClickHandler(new DoubleClickHandler() {
@Override
- public void onClick(MenuItemClickEvent event) {
- emptyMenu();
+ public void onDoubleClick(DoubleClickEvent event) {
+ try {
+ ListGrid listGrid = (ListGrid) event.getSource();
+ ListGridRecord[] selectedRows = listGrid.getSelection();
+ if (selectedRows != null && selectedRows.length > 0) {
+ Message message = (Message) selectedRows[0].getAttributeAsObject(FIELD_OBJECT); // show the first selected
+ showDetails(message);
+ }
+ } catch (Throwable e) {
+ Log.error("Cannot show details for message", e);
+ }
}
});
- messagesMenu.setItems(clearItem); // setItems making this the only item in the menu
- MenuItem separator = new MenuItem();
- separator.setIsSeparator(true);
- messagesMenu.addItem(separator);
+ addTableAction(extendLocatorId("delete"), MSG.common_button_delete(), MSG.common_msg_areYouSure(),
+ new AbstractTableAction(TableActionEnablement.ANY) {
+ @Override
+ public void executeAction(ListGridRecord[] selection, Object actionValue) {
+ try {
+ for (ListGridRecord record : selection) {
+ Object doomed = record.getAttributeAsObject(FIELD_OBJECT);
+ CoreGUI.getMessageCenter().getMessages().remove(doomed);
+ }
+ refresh();
+ } catch (Throwable e) {
+ Log.error("Cannot delete messages", e);
+ }
+ }
+ });
+
+ addTableAction(extendLocatorId("deleteAll"), MSG.common_button_delete_all(), MSG.common_msg_areYouSure(),
+ new AbstractTableAction(TableActionEnablement.ALWAYS) {
+ @Override
+ public void executeAction(ListGridRecord[] selection, Object actionValue) {
+ try {
+ CoreGUI.getMessageCenter().getMessages().clear();
+ refresh();
+ } catch (Throwable e) {
+ Log.error("Cannot delete all messages", e);
+ }
+ }
+ });
+
+ LinkedHashMap<String, Integer> maxMessagesMap = new LinkedHashMap<String, Integer>();
+ maxMessagesMap.put("10", Integer.valueOf("10"));
+ maxMessagesMap.put("25", Integer.valueOf("25"));
+ maxMessagesMap.put("50", Integer.valueOf("50"));
+ maxMessagesMap.put("100", Integer.valueOf("100"));
+ maxMessagesMap.put("200", Integer.valueOf("200"));
+ addTableAction(extendLocatorId("maxMessageMeny"), MSG.view_messageCenter_maxMessages(), null, maxMessagesMap,
+ new AbstractTableAction(TableActionEnablement.ALWAYS) {
+ @Override
+ public void executeAction(ListGridRecord[] selection, Object actionValue) {
+ try {
+ Integer maxSize = (Integer) actionValue;
+ CoreGUI.getMessageCenter().setMaxMessages(maxSize.intValue());
+ setTableTitle(MSG.view_messageCenter_lastNMessages(maxSize.toString()));
+ refresh();
+ } catch (Throwable e) {
+ Log.error("Cannot set max messages", e);
+ }
+ }
+ });
+
+ /*
+ // TODO only for testing, remove this when done testing
+ addTableAction(extendLocatorId("test"), "TEST MSG", null,
+ new AbstractTableAction(TableActionEnablement.ALWAYS) {
+ @Override
+ public void executeAction(ListGridRecord[] selection, Object actionValue) {
+ for (Severity severity : EnumSet.allOf(Severity.class)) {
+ Message m = new Message(severity.name() + ':' + System.currentTimeMillis(), severity);
+ CoreGUI.getMessageCenter().notify(m);
+ }
+ }
+ });
+ */
- markForRedraw();
+ // initial population of the list with current messages
+ try {
+ refresh();
+ } catch (Throwable e) {
+ Log.error("Cannot perform initial refresh", e);
+ }
}
- private void emptyMenu() {
- CoreGUI.getMessageCenter().getMessages().clear();
- messageCount = 0;
- messagesMenu.setItems(new MenuItem(MSG.view_messageCenter_noRecentMessages()));
- markForRedraw();
+ @Override
+ protected SelectionStyle getDefaultSelectionStyle() {
+ return SelectionStyle.MULTIPLE;
+ }
+
+ @Override
+ public void refresh() {
+ try {
+ super.refresh();
+ getListGrid().setRecords(transform(CoreGUI.getMessageCenter().getMessages()));
+ refreshTableInfo();
+ } catch (Throwable e) {
+ Log.error("Cannot refresh messages", e);
+ }
+ }
+
+ private ListGridRecord[] transform(List<Message> list) {
+ ListGridRecord[] results = new ListGridRecord[list.size()];
+ for (int i = 0; i < list.size(); i++) {
+ results[i] = transform(list.get(i));
+ }
+ return results;
+ }
+
+ private ListGridRecord transform(Message msg) {
+ ListGridRecord record = new ListGridRecord();
+ record.setAttribute(FIELD_TIME, msg.fired);
+ record.setAttribute(FIELD_SEVERITY, (msg.severity != null) ? msg.severity.name() : Severity.Info.name());
+ record.setAttribute(FIELD_CONCISEMESSAGE, msg.conciseMessage);
+ record.setAttribute(FIELD_OBJECT, msg);
+ return record;
}
private void showDetails(Message message) {
@@ -148,7 +390,7 @@ public class MessageCenterView extends LocatableVLayout implements MessageCenter
form.setItems(title, severity, date, detail);
final Window window = new LocatableWindow(this.extendLocatorId("MessageWindow"));
- window.setTitle(MSG.view_messageCenter_messageTitle());
+ window.setTitle(MSG.common_title_message());
window.setWidth(600);
window.setHeight(400);
window.setIsModal(true);
@@ -168,19 +410,58 @@ public class MessageCenterView extends LocatableVLayout implements MessageCenter
}
private String getSeverityIcon(Message.Severity severity) {
- String iconSrc = null;
- switch (severity) {
- case Info:
- iconSrc = "info/icn_info_blue.png";
- break;
- case Warning:
- iconSrc = "info/icn_info_orange.png";
- break;
- case Error:
- case Fatal:
- iconSrc = "info/icn_info_red.png";
- break;
+ if (severity == null) {
+ severity = Severity.Blank;
}
- return iconSrc;
+ return severity.getIcon();
}
+
+ static class MessageCenterWindow extends LocatableWindow {
+ private Timer blinkTimer;
+
+ public MessageCenterWindow(String locatorId) {
+ super(locatorId);
+ setTitle(TABLE_TITLE);
+ setShowMinimizeButton(true);
+ setShowMaximizeButton(true);
+ setShowCloseButton(true);
+ setIsModal(false);
+ setShowModalMask(false);
+ setWidth(700);
+ setHeight(300);
+ setShowResizer(true);
+ setCanDragResize(true);
+ centerInPage();
+
+ final String origColor = getBodyColor();
+ blinkTimer = new Timer() {
+ @Override
+ public void run() {
+ try {
+ setBodyColor(origColor);
+ setTitle(TABLE_TITLE);
+ redraw();
+ } catch (Throwable e) {
+ Log.error("Blink timer failed", e);
+ }
+ }
+ };
+ }
+
+ public void blink() {
+ try {
+ // window.flash() isn' t working so do it ourselves
+ if (getMinimized()) {
+ setTitle(TABLE_TITLE + " *");
+ } else {
+ setBodyColor(getHiliteBodyColor());
+ }
+ redraw();
+ blinkTimer.schedule(250);
+ } catch (Throwable e) {
+ Log.error("Cannot blink message center window", e);
+ }
+ }
+ }
+
}
diff --git a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages.properties b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages.properties
index b7bc5c4..9d9da4f 100644
--- a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages.properties
+++ b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages.properties
@@ -2085,11 +2085,12 @@ view_searchGUI_loginStatus = Unable to determine login status, check server stat
# Message Center
#--------------------------
-view_messageCenter_button_messages = Messages
+view_messageCenter_messageTitle = Message Center
view_messageCenter_noRecentMessages = No Recent Messages
+view_messageCenter_maxMessages = Max Messages
+view_messageCenter_lastNMessages = Last {0} Messages
view_messageCenter_clearAllMessages = Clear All Messages
-view_messageCenter_messageTitle = Message Center
-view_messageCenter_messageSeverity = Severity
view_messageCenter_messageTime = Time
+view_messageCenter_messageSeverity = Severity
view_messageCenter_messageDetail = Detail
view_messageCenter_stackTraceFollows = --- STACK TRACE FOLLOWS ---
13 years, 3 months
[rhq] modules/enterprise
by Jay Shaughnessy
modules/enterprise/gui/coregui/pom.xml | 4
modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/CoreGUI.gwt.xml | 7
modules/enterprise/gui/coregui/src/main/webapp/js/jquery-1.4.4.js | 7179 ----------
3 files changed, 9 insertions(+), 7181 deletions(-)
New commits:
commit b426b2e42cec8cbb9dfd1f396bac330b9db008db
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Fri Mar 18 13:43:33 2011 -0400
Re-establish working metric graphs in the GraphPortlet (SmallGraph)
- remove explicit provision of 1.4.4 jquery lib. jquery.sparkline requires
jquery but jquery is already embedded in the GFlot JAR (the charting
lib used for GraphPortlet). GFlot 1.0.0 requires/provides an older
version(1.3.2) that what is currently available, but fortunately
sparkline is compatible with this older version. We will need to provide
jquery explicitly if we remove GFlot.
diff --git a/modules/enterprise/gui/coregui/pom.xml b/modules/enterprise/gui/coregui/pom.xml
index 09c58dd..bf14b52 100644
--- a/modules/enterprise/gui/coregui/pom.xml
+++ b/modules/enterprise/gui/coregui/pom.xml
@@ -140,7 +140,9 @@
</dependency>
-->
- <!-- the GWT graphing library -->
+ <!-- the GWT graphing library (note, this provides jquery 1.3.2. If we get rid of GFlot we will need
+ to provide jquery explcitly for jquery.sparkline support. See CoreGUI.gwt.xml for the jquery.sparkline
+ declaration and coregui/webapp/js for the lib inclusion.) -->
<dependency>
<groupId>ca.nanometrics</groupId>
<artifactId>gflot</artifactId>
diff --git a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/CoreGUI.gwt.xml b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/CoreGUI.gwt.xml
index 980f9ca..3d1f770 100644
--- a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/CoreGUI.gwt.xml
+++ b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/CoreGUI.gwt.xml
@@ -64,7 +64,12 @@
</generate-with>
<!-- External javascript libraries -->
- <script src="/coregui/js/jquery-1.4.4.js"/>
+ <!-- jquery.sparkline requires jquery. We don't explicitly provide jquery here because it is already
+ embedded in the GFlot JAR (the charting lib used for GraphPortlet). Furthermore, GFlot 1.0.0 requires
+ its older, embedded version of jquery (1.3.2). Fortunately, sparkline is compatible with this older version.
+ We will need to provide jquery explicitly (like the commented version below) if we remove GFlot.
+ <script src="/coregui/js/jquery-1.4.4.js"/>
+ -->
<script src="/coregui/js/jquery.sparkline-1.6.js"/>
<!--
diff --git a/modules/enterprise/gui/coregui/src/main/webapp/js/jquery-1.4.4.js b/modules/enterprise/gui/coregui/src/main/webapp/js/jquery-1.4.4.js
deleted file mode 100644
index c53482c..0000000
--- a/modules/enterprise/gui/coregui/src/main/webapp/js/jquery-1.4.4.js
+++ /dev/null
@@ -1,7179 +0,0 @@
-/*!
- * jQuery JavaScript Library v1.4.4
- * http://jquery.com/
- *
- * Copyright 2010, John Resig
- * Dual licensed under the MIT or GPL Version 2 licenses.
- * http://jquery.org/license
- *
- * Includes Sizzle.js
- * http://sizzlejs.com/
- * Copyright 2010, The Dojo Foundation
- * Released under the MIT, BSD, and GPL Licenses.
- *
- * Date: Thu Nov 11 19:04:53 2010 -0500
- */
-(function( window, undefined ) {
-
-// Use the correct document accordingly with window argument (sandbox)
-var document = window.document;
-var jQuery = (function() {
-
-// Define a local copy of jQuery
-var jQuery = function( selector, context ) {
- // The jQuery object is actually just the init constructor 'enhanced'
- return new jQuery.fn.init( selector, context );
- },
-
- // Map over jQuery in case of overwrite
- _jQuery = window.jQuery,
-
- // Map over the $ in case of overwrite
- _$ = window.$,
-
- // A central reference to the root jQuery(document)
- rootjQuery,
-
- // A simple way to check for HTML strings or ID strings
- // (both of which we optimize for)
- quickExpr = /^(?:[^<]*(<[\w\W]+>)[^>]*$|#([\w\-]+)$)/,
-
- // Is it a simple selector
- isSimple = /^.[^:#\[\.,]*$/,
-
- // Check if a string has a non-whitespace character in it
- rnotwhite = /\S/,
- rwhite = /\s/,
-
- // Used for trimming whitespace
- trimLeft = /^\s+/,
- trimRight = /\s+$/,
-
- // Check for non-word characters
- rnonword = /\W/,
-
- // Check for digits
- rdigit = /\d/,
-
- // Match a standalone tag
- rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>)?$/,
-
- // JSON RegExp
- rvalidchars = /^[\],:{}\s]*$/,
- rvalidescape = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,
- rvalidtokens = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,
- rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g,
-
- // Useragent RegExp
- rwebkit = /(webkit)[ \/]([\w.]+)/,
- ropera = /(opera)(?:.*version)?[ \/]([\w.]+)/,
- rmsie = /(msie) ([\w.]+)/,
- rmozilla = /(mozilla)(?:.*? rv:([\w.]+))?/,
-
- // Keep a UserAgent string for use with jQuery.browser
- userAgent = navigator.userAgent,
-
- // For matching the engine and version of the browser
- browserMatch,
-
- // Has the ready events already been bound?
- readyBound = false,
-
- // The functions to execute on DOM ready
- readyList = [],
-
- // The ready event handler
- DOMContentLoaded,
-
- // Save a reference to some core methods
- toString = Object.prototype.toString,
- hasOwn = Object.prototype.hasOwnProperty,
- push = Array.prototype.push,
- slice = Array.prototype.slice,
- trim = String.prototype.trim,
- indexOf = Array.prototype.indexOf,
-
- // [[Class]] -> type pairs
- class2type = {};
-
-jQuery.fn = jQuery.prototype = {
- init: function( selector, context ) {
- var match, elem, ret, doc;
-
- // Handle $(""), $(null), or $(undefined)
- if ( !selector ) {
- return this;
- }
-
- // Handle $(DOMElement)
- if ( selector.nodeType ) {
- this.context = this[0] = selector;
- this.length = 1;
- return this;
- }
-
- // The body element only exists once, optimize finding it
- if ( selector === "body" && !context && document.body ) {
- this.context = document;
- this[0] = document.body;
- this.selector = "body";
- this.length = 1;
- return this;
- }
-
- // Handle HTML strings
- if ( typeof selector === "string" ) {
- // Are we dealing with HTML string or an ID?
- match = quickExpr.exec( selector );
-
- // Verify a match, and that no context was specified for #id
- if ( match && (match[1] || !context) ) {
-
- // HANDLE: $(html) -> $(array)
- if ( match[1] ) {
- doc = (context ? context.ownerDocument || context : document);
-
- // If a single string is passed in and it's a single tag
- // just do a createElement and skip the rest
- ret = rsingleTag.exec( selector );
-
- if ( ret ) {
- if ( jQuery.isPlainObject( context ) ) {
- selector = [ document.createElement( ret[1] ) ];
- jQuery.fn.attr.call( selector, context, true );
-
- } else {
- selector = [ doc.createElement( ret[1] ) ];
- }
-
- } else {
- ret = jQuery.buildFragment( [ match[1] ], [ doc ] );
- selector = (ret.cacheable ? ret.fragment.cloneNode(true) : ret.fragment).childNodes;
- }
-
- return jQuery.merge( this, selector );
-
- // HANDLE: $("#id")
- } else {
- elem = document.getElementById( match[2] );
-
- // Check parentNode to catch when Blackberry 4.6 returns
- // nodes that are no longer in the document #6963
- if ( elem && elem.parentNode ) {
- // Handle the case where IE and Opera return items
- // by name instead of ID
- if ( elem.id !== match[2] ) {
- return rootjQuery.find( selector );
- }
-
- // Otherwise, we inject the element directly into the jQuery object
- this.length = 1;
- this[0] = elem;
- }
-
- this.context = document;
- this.selector = selector;
- return this;
- }
-
- // HANDLE: $("TAG")
- } else if ( !context && !rnonword.test( selector ) ) {
- this.selector = selector;
- this.context = document;
- selector = document.getElementsByTagName( selector );
- return jQuery.merge( this, selector );
-
- // HANDLE: $(expr, $(...))
- } else if ( !context || context.jquery ) {
- return (context || rootjQuery).find( selector );
-
- // HANDLE: $(expr, context)
- // (which is just equivalent to: $(context).find(expr)
- } else {
- return jQuery( context ).find( selector );
- }
-
- // HANDLE: $(function)
- // Shortcut for document ready
- } else if ( jQuery.isFunction( selector ) ) {
- return rootjQuery.ready( selector );
- }
-
- if (selector.selector !== undefined) {
- this.selector = selector.selector;
- this.context = selector.context;
- }
-
- return jQuery.makeArray( selector, this );
- },
-
- // Start with an empty selector
- selector: "",
-
- // The current version of jQuery being used
- jquery: "1.4.4",
-
- // The default length of a jQuery object is 0
- length: 0,
-
- // The number of elements contained in the matched element set
- size: function() {
- return this.length;
- },
-
- toArray: function() {
- return slice.call( this, 0 );
- },
-
- // Get the Nth element in the matched element set OR
- // Get the whole matched element set as a clean array
- get: function( num ) {
- return num == null ?
-
- // Return a 'clean' array
- this.toArray() :
-
- // Return just the object
- ( num < 0 ? this.slice(num)[ 0 ] : this[ num ] );
- },
-
- // Take an array of elements and push it onto the stack
- // (returning the new matched element set)
- pushStack: function( elems, name, selector ) {
- // Build a new jQuery matched element set
- var ret = jQuery();
-
- if ( jQuery.isArray( elems ) ) {
- push.apply( ret, elems );
-
- } else {
- jQuery.merge( ret, elems );
- }
-
- // Add the old object onto the stack (as a reference)
- ret.prevObject = this;
-
- ret.context = this.context;
-
- if ( name === "find" ) {
- ret.selector = this.selector + (this.selector ? " " : "") + selector;
- } else if ( name ) {
- ret.selector = this.selector + "." + name + "(" + selector + ")";
- }
-
- // Return the newly-formed element set
- return ret;
- },
-
- // Execute a callback for every element in the matched set.
- // (You can seed the arguments with an array of args, but this is
- // only used internally.)
- each: function( callback, args ) {
- return jQuery.each( this, callback, args );
- },
-
- ready: function( fn ) {
- // Attach the listeners
- jQuery.bindReady();
-
- // If the DOM is already ready
- if ( jQuery.isReady ) {
- // Execute the function immediately
- fn.call( document, jQuery );
-
- // Otherwise, remember the function for later
- } else if ( readyList ) {
- // Add the function to the wait list
- readyList.push( fn );
- }
-
- return this;
- },
-
- eq: function( i ) {
- return i === -1 ?
- this.slice( i ) :
- this.slice( i, +i + 1 );
- },
-
- first: function() {
- return this.eq( 0 );
- },
-
- last: function() {
- return this.eq( -1 );
- },
-
- slice: function() {
- return this.pushStack( slice.apply( this, arguments ),
- "slice", slice.call(arguments).join(",") );
- },
-
- map: function( callback ) {
- return this.pushStack( jQuery.map(this, function( elem, i ) {
- return callback.call( elem, i, elem );
- }));
- },
-
- end: function() {
- return this.prevObject || jQuery(null);
- },
-
- // For internal use only.
- // Behaves like an Array's method, not like a jQuery method.
- push: push,
- sort: [].sort,
- splice: [].splice
-};
-
-// Give the init function the jQuery prototype for later instantiation
-jQuery.fn.init.prototype = jQuery.fn;
-
-jQuery.extend = jQuery.fn.extend = function() {
- var options, name, src, copy, copyIsArray, clone,
- target = arguments[0] || {},
- i = 1,
- length = arguments.length,
- deep = false;
-
- // Handle a deep copy situation
- if ( typeof target === "boolean" ) {
- deep = target;
- target = arguments[1] || {};
- // skip the boolean and the target
- i = 2;
- }
-
- // Handle case when target is a string or something (possible in deep copy)
- if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
- target = {};
- }
-
- // extend jQuery itself if only one argument is passed
- if ( length === i ) {
- target = this;
- --i;
- }
-
- for ( ; i < length; i++ ) {
- // Only deal with non-null/undefined values
- if ( (options = arguments[ i ]) != null ) {
- // Extend the base object
- for ( name in options ) {
- src = target[ name ];
- copy = options[ name ];
-
- // Prevent never-ending loop
- if ( target === copy ) {
- continue;
- }
-
- // Recurse if we're merging plain objects or arrays
- if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {
- if ( copyIsArray ) {
- copyIsArray = false;
- clone = src && jQuery.isArray(src) ? src : [];
-
- } else {
- clone = src && jQuery.isPlainObject(src) ? src : {};
- }
-
- // Never move original objects, clone them
- target[ name ] = jQuery.extend( deep, clone, copy );
-
- // Don't bring in undefined values
- } else if ( copy !== undefined ) {
- target[ name ] = copy;
- }
- }
- }
- }
-
- // Return the modified object
- return target;
-};
-
-jQuery.extend({
- noConflict: function( deep ) {
- window.$ = _$;
-
- if ( deep ) {
- window.jQuery = _jQuery;
- }
-
- return jQuery;
- },
-
- // Is the DOM ready to be used? Set to true once it occurs.
- isReady: false,
-
- // A counter to track how many items to wait for before
- // the ready event fires. See #6781
- readyWait: 1,
-
- // Handle when the DOM is ready
- ready: function( wait ) {
- // A third-party is pushing the ready event forwards
- if ( wait === true ) {
- jQuery.readyWait--;
- }
-
- // Make sure that the DOM is not already loaded
- if ( !jQuery.readyWait || (wait !== true && !jQuery.isReady) ) {
- // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
- if ( !document.body ) {
- return setTimeout( jQuery.ready, 1 );
- }
-
- // Remember that the DOM is ready
- jQuery.isReady = true;
-
- // If a normal DOM Ready event fired, decrement, and wait if need be
- if ( wait !== true && --jQuery.readyWait > 0 ) {
- return;
- }
-
- // If there are functions bound, to execute
- if ( readyList ) {
- // Execute all of them
- var fn,
- i = 0,
- ready = readyList;
-
- // Reset the list of functions
- readyList = null;
-
- while ( (fn = ready[ i++ ]) ) {
- fn.call( document, jQuery );
- }
-
- // Trigger any bound ready events
- if ( jQuery.fn.trigger ) {
- jQuery( document ).trigger( "ready" ).unbind( "ready" );
- }
- }
- }
- },
-
- bindReady: function() {
- if ( readyBound ) {
- return;
- }
-
- readyBound = true;
-
- // Catch cases where $(document).ready() is called after the
- // browser event has already occurred.
- if ( document.readyState === "complete" ) {
- // Handle it asynchronously to allow scripts the opportunity to delay ready
- return setTimeout( jQuery.ready, 1 );
- }
-
- // Mozilla, Opera and webkit nightlies currently support this event
- if ( document.addEventListener ) {
- // Use the handy event callback
- document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false );
-
- // A fallback to window.onload, that will always work
- window.addEventListener( "load", jQuery.ready, false );
-
- // If IE event model is used
- } else if ( document.attachEvent ) {
- // ensure firing before onload,
- // maybe late but safe also for iframes
- document.attachEvent("onreadystatechange", DOMContentLoaded);
-
- // A fallback to window.onload, that will always work
- window.attachEvent( "onload", jQuery.ready );
-
- // If IE and not a frame
- // continually check to see if the document is ready
- var toplevel = false;
-
- try {
- toplevel = window.frameElement == null;
- } catch(e) {}
-
- if ( document.documentElement.doScroll && toplevel ) {
- doScrollCheck();
- }
- }
- },
-
- // See test/unit/core.js for details concerning isFunction.
- // Since version 1.3, DOM methods and functions like alert
- // aren't supported. They return false on IE (#2968).
- isFunction: function( obj ) {
- return jQuery.type(obj) === "function";
- },
-
- isArray: Array.isArray || function( obj ) {
- return jQuery.type(obj) === "array";
- },
-
- // A crude way of determining if an object is a window
- isWindow: function( obj ) {
- return obj && typeof obj === "object" && "setInterval" in obj;
- },
-
- isNaN: function( obj ) {
- return obj == null || !rdigit.test( obj ) || isNaN( obj );
- },
-
- type: function( obj ) {
- return obj == null ?
- String( obj ) :
- class2type[ toString.call(obj) ] || "object";
- },
-
- isPlainObject: function( obj ) {
- // Must be an Object.
- // Because of IE, we also have to check the presence of the constructor property.
- // Make sure that DOM nodes and window objects don't pass through, as well
- if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
- return false;
- }
-
- // Not own constructor property must be Object
- if ( obj.constructor &&
- !hasOwn.call(obj, "constructor") &&
- !hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) {
- return false;
- }
-
- // Own properties are enumerated firstly, so to speed up,
- // if last one is own, then all properties are own.
-
- var key;
- for ( key in obj ) {}
-
- return key === undefined || hasOwn.call( obj, key );
- },
-
- isEmptyObject: function( obj ) {
- for ( var name in obj ) {
- return false;
- }
- return true;
- },
-
- error: function( msg ) {
- throw msg;
- },
-
- parseJSON: function( data ) {
- if ( typeof data !== "string" || !data ) {
- return null;
- }
-
- // Make sure leading/trailing whitespace is removed (IE can't handle it)
- data = jQuery.trim( data );
-
- // Make sure the incoming data is actual JSON
- // Logic borrowed from http://json.org/json2.js
- if ( rvalidchars.test(data.replace(rvalidescape, "@")
- .replace(rvalidtokens, "]")
- .replace(rvalidbraces, "")) ) {
-
- // Try to use the native JSON parser first
- return window.JSON && window.JSON.parse ?
- window.JSON.parse( data ) :
- (new Function("return " + data))();
-
- } else {
- jQuery.error( "Invalid JSON: " + data );
- }
- },
-
- noop: function() {},
-
- // Evalulates a script in a global context
- globalEval: function( data ) {
- if ( data && rnotwhite.test(data) ) {
- // Inspired by code by Andrea Giammarchi
- // http://webreflection.blogspot.com/2007/08/global-scope-evaluation-and-dom...
- var head = document.getElementsByTagName("head")[0] || document.documentElement,
- script = document.createElement("script");
-
- script.type = "text/javascript";
-
- if ( jQuery.support.scriptEval ) {
- script.appendChild( document.createTextNode( data ) );
- } else {
- script.text = data;
- }
-
- // Use insertBefore instead of appendChild to circumvent an IE6 bug.
- // This arises when a base node is used (#2709).
- head.insertBefore( script, head.firstChild );
- head.removeChild( script );
- }
- },
-
- nodeName: function( elem, name ) {
- return elem.nodeName && elem.nodeName.toUpperCase() === name.toUpperCase();
- },
-
- // args is for internal usage only
- each: function( object, callback, args ) {
- var name, i = 0,
- length = object.length,
- isObj = length === undefined || jQuery.isFunction(object);
-
- if ( args ) {
- if ( isObj ) {
- for ( name in object ) {
- if ( callback.apply( object[ name ], args ) === false ) {
- break;
- }
- }
- } else {
- for ( ; i < length; ) {
- if ( callback.apply( object[ i++ ], args ) === false ) {
- break;
- }
- }
- }
-
- // A special, fast, case for the most common use of each
- } else {
- if ( isObj ) {
- for ( name in object ) {
- if ( callback.call( object[ name ], name, object[ name ] ) === false ) {
- break;
- }
- }
- } else {
- for ( var value = object[0];
- i < length && callback.call( value, i, value ) !== false; value = object[++i] ) {}
- }
- }
-
- return object;
- },
-
- // Use native String.trim function wherever possible
- trim: trim ?
- function( text ) {
- return text == null ?
- "" :
- trim.call( text );
- } :
-
- // Otherwise use our own trimming functionality
- function( text ) {
- return text == null ?
- "" :
- text.toString().replace( trimLeft, "" ).replace( trimRight, "" );
- },
-
- // results is for internal usage only
- makeArray: function( array, results ) {
- var ret = results || [];
-
- if ( array != null ) {
- // The window, strings (and functions) also have 'length'
- // The extra typeof function check is to prevent crashes
- // in Safari 2 (See: #3039)
- // Tweaked logic slightly to handle Blackberry 4.7 RegExp issues #6930
- var type = jQuery.type(array);
-
- if ( array.length == null || type === "string" || type === "function" || type === "regexp" || jQuery.isWindow( array ) ) {
- push.call( ret, array );
- } else {
- jQuery.merge( ret, array );
- }
- }
-
- return ret;
- },
-
- inArray: function( elem, array ) {
- if ( array.indexOf ) {
- return array.indexOf( elem );
- }
-
- for ( var i = 0, length = array.length; i < length; i++ ) {
- if ( array[ i ] === elem ) {
- return i;
- }
- }
-
- return -1;
- },
-
- merge: function( first, second ) {
- var i = first.length,
- j = 0;
-
- if ( typeof second.length === "number" ) {
- for ( var l = second.length; j < l; j++ ) {
- first[ i++ ] = second[ j ];
- }
-
- } else {
- while ( second[j] !== undefined ) {
- first[ i++ ] = second[ j++ ];
- }
- }
-
- first.length = i;
-
- return first;
- },
-
- grep: function( elems, callback, inv ) {
- var ret = [], retVal;
- inv = !!inv;
-
- // Go through the array, only saving the items
- // that pass the validator function
- for ( var i = 0, length = elems.length; i < length; i++ ) {
- retVal = !!callback( elems[ i ], i );
- if ( inv !== retVal ) {
- ret.push( elems[ i ] );
- }
- }
-
- return ret;
- },
-
- // arg is for internal usage only
- map: function( elems, callback, arg ) {
- var ret = [], value;
-
- // Go through the array, translating each of the items to their
- // new value (or values).
- for ( var i = 0, length = elems.length; i < length; i++ ) {
- value = callback( elems[ i ], i, arg );
-
- if ( value != null ) {
- ret[ ret.length ] = value;
- }
- }
-
- return ret.concat.apply( [], ret );
- },
-
- // A global GUID counter for objects
- guid: 1,
-
- proxy: function( fn, proxy, thisObject ) {
- if ( arguments.length === 2 ) {
- if ( typeof proxy === "string" ) {
- thisObject = fn;
- fn = thisObject[ proxy ];
- proxy = undefined;
-
- } else if ( proxy && !jQuery.isFunction( proxy ) ) {
- thisObject = proxy;
- proxy = undefined;
- }
- }
-
- if ( !proxy && fn ) {
- proxy = function() {
- return fn.apply( thisObject || this, arguments );
- };
- }
-
- // Set the guid of unique handler to the same of original handler, so it can be removed
- if ( fn ) {
- proxy.guid = fn.guid = fn.guid || proxy.guid || jQuery.guid++;
- }
-
- // So proxy can be declared as an argument
- return proxy;
- },
-
- // Mutifunctional method to get and set values to a collection
- // The value/s can be optionally by executed if its a function
- access: function( elems, key, value, exec, fn, pass ) {
- var length = elems.length;
-
- // Setting many attributes
- if ( typeof key === "object" ) {
- for ( var k in key ) {
- jQuery.access( elems, k, key[k], exec, fn, value );
- }
- return elems;
- }
-
- // Setting one attribute
- if ( value !== undefined ) {
- // Optionally, function values get executed if exec is true
- exec = !pass && exec && jQuery.isFunction(value);
-
- for ( var i = 0; i < length; i++ ) {
- fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass );
- }
-
- return elems;
- }
-
- // Getting an attribute
- return length ? fn( elems[0], key ) : undefined;
- },
-
- now: function() {
- return (new Date()).getTime();
- },
-
- // Use of jQuery.browser is frowned upon.
- // More details: http://docs.jquery.com/Utilities/jQuery.browser
- uaMatch: function( ua ) {
- ua = ua.toLowerCase();
-
- var match = rwebkit.exec( ua ) ||
- ropera.exec( ua ) ||
- rmsie.exec( ua ) ||
- ua.indexOf("compatible") < 0 && rmozilla.exec( ua ) ||
- [];
-
- return { browser: match[1] || "", version: match[2] || "0" };
- },
-
- browser: {}
-});
-
-// Populate the class2type map
-jQuery.each("Boolean Number String Function Array Date RegExp Object".split(" "), function(i, name) {
- class2type[ "[object " + name + "]" ] = name.toLowerCase();
-});
-
-browserMatch = jQuery.uaMatch( userAgent );
-if ( browserMatch.browser ) {
- jQuery.browser[ browserMatch.browser ] = true;
- jQuery.browser.version = browserMatch.version;
-}
-
-// Deprecated, use jQuery.browser.webkit instead
-if ( jQuery.browser.webkit ) {
- jQuery.browser.safari = true;
-}
-
-if ( indexOf ) {
- jQuery.inArray = function( elem, array ) {
- return indexOf.call( array, elem );
- };
-}
-
-// Verify that \s matches non-breaking spaces
-// (IE fails on this test)
-if ( !rwhite.test( "\xA0" ) ) {
- trimLeft = /^[\s\xA0]+/;
- trimRight = /[\s\xA0]+$/;
-}
-
-// All jQuery objects should point back to these
-rootjQuery = jQuery(document);
-
-// Cleanup functions for the document ready method
-if ( document.addEventListener ) {
- DOMContentLoaded = function() {
- document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false );
- jQuery.ready();
- };
-
-} else if ( document.attachEvent ) {
- DOMContentLoaded = function() {
- // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
- if ( document.readyState === "complete" ) {
- document.detachEvent( "onreadystatechange", DOMContentLoaded );
- jQuery.ready();
- }
- };
-}
-
-// The DOM ready check for Internet Explorer
-function doScrollCheck() {
- if ( jQuery.isReady ) {
- return;
- }
-
- try {
- // If IE is used, use the trick by Diego Perini
- // http://javascript.nwbox.com/IEContentLoaded/
- document.documentElement.doScroll("left");
- } catch(e) {
- setTimeout( doScrollCheck, 1 );
- return;
- }
-
- // and execute any waiting functions
- jQuery.ready();
-}
-
-// Expose jQuery to the global object
-return (window.jQuery = window.$ = jQuery);
-
-})();
-
-
-(function() {
-
- jQuery.support = {};
-
- var root = document.documentElement,
- script = document.createElement("script"),
- div = document.createElement("div"),
- id = "script" + jQuery.now();
-
- div.style.display = "none";
- div.innerHTML = " <link/><table></table><a href='/a' style='color:red;float:left;opacity:.55;'>a</a><input type='checkbox'/>";
-
- var all = div.getElementsByTagName("*"),
- a = div.getElementsByTagName("a")[0],
- select = document.createElement("select"),
- opt = select.appendChild( document.createElement("option") );
-
- // Can't get basic test support
- if ( !all || !all.length || !a ) {
- return;
- }
-
- jQuery.support = {
- // IE strips leading whitespace when .innerHTML is used
- leadingWhitespace: div.firstChild.nodeType === 3,
-
- // Make sure that tbody elements aren't automatically inserted
- // IE will insert them into empty tables
- tbody: !div.getElementsByTagName("tbody").length,
-
- // Make sure that link elements get serialized correctly by innerHTML
- // This requires a wrapper element in IE
- htmlSerialize: !!div.getElementsByTagName("link").length,
-
- // Get the style information from getAttribute
- // (IE uses .cssText insted)
- style: /red/.test( a.getAttribute("style") ),
-
- // Make sure that URLs aren't manipulated
- // (IE normalizes it by default)
- hrefNormalized: a.getAttribute("href") === "/a",
-
- // Make sure that element opacity exists
- // (IE uses filter instead)
- // Use a regex to work around a WebKit issue. See #5145
- opacity: /^0.55$/.test( a.style.opacity ),
-
- // Verify style float existence
- // (IE uses styleFloat instead of cssFloat)
- cssFloat: !!a.style.cssFloat,
-
- // Make sure that if no value is specified for a checkbox
- // that it defaults to "on".
- // (WebKit defaults to "" instead)
- checkOn: div.getElementsByTagName("input")[0].value === "on",
-
- // Make sure that a selected-by-default option has a working selected property.
- // (WebKit defaults to false instead of true, IE too, if it's in an optgroup)
- optSelected: opt.selected,
-
- // Will be defined later
- deleteExpando: true,
- optDisabled: false,
- checkClone: false,
- scriptEval: false,
- noCloneEvent: true,
- boxModel: null,
- inlineBlockNeedsLayout: false,
- shrinkWrapBlocks: false,
- reliableHiddenOffsets: true
- };
-
- // Make sure that the options inside disabled selects aren't marked as disabled
- // (WebKit marks them as diabled)
- select.disabled = true;
- jQuery.support.optDisabled = !opt.disabled;
-
- script.type = "text/javascript";
- try {
- script.appendChild( document.createTextNode( "window." + id + "=1;" ) );
- } catch(e) {}
-
- root.insertBefore( script, root.firstChild );
-
- // Make sure that the execution of code works by injecting a script
- // tag with appendChild/createTextNode
- // (IE doesn't support this, fails, and uses .text instead)
- if ( window[ id ] ) {
- jQuery.support.scriptEval = true;
- delete window[ id ];
- }
-
- // Test to see if it's possible to delete an expando from an element
- // Fails in Internet Explorer
- try {
- delete script.test;
-
- } catch(e) {
- jQuery.support.deleteExpando = false;
- }
-
- root.removeChild( script );
-
- if ( div.attachEvent && div.fireEvent ) {
- div.attachEvent("onclick", function click() {
- // Cloning a node shouldn't copy over any
- // bound event handlers (IE does this)
- jQuery.support.noCloneEvent = false;
- div.detachEvent("onclick", click);
- });
- div.cloneNode(true).fireEvent("onclick");
- }
-
- div = document.createElement("div");
- div.innerHTML = "<input type='radio' name='radiotest' checked='checked'/>";
-
- var fragment = document.createDocumentFragment();
- fragment.appendChild( div.firstChild );
-
- // WebKit doesn't clone checked state correctly in fragments
- jQuery.support.checkClone = fragment.cloneNode(true).cloneNode(true).lastChild.checked;
-
- // Figure out if the W3C box model works as expected
- // document.body must exist before we can do this
- jQuery(function() {
- var div = document.createElement("div");
- div.style.width = div.style.paddingLeft = "1px";
-
- document.body.appendChild( div );
- jQuery.boxModel = jQuery.support.boxModel = div.offsetWidth === 2;
-
- if ( "zoom" in div.style ) {
- // Check if natively block-level elements act like inline-block
- // elements when setting their display to 'inline' and giving
- // them layout
- // (IE < 8 does this)
- div.style.display = "inline";
- div.style.zoom = 1;
- jQuery.support.inlineBlockNeedsLayout = div.offsetWidth === 2;
-
- // Check if elements with layout shrink-wrap their children
- // (IE 6 does this)
- div.style.display = "";
- div.innerHTML = "<div style='width:4px;'></div>";
- jQuery.support.shrinkWrapBlocks = div.offsetWidth !== 2;
- }
-
- div.innerHTML = "<table><tr><td style='padding:0;display:none'></td><td>t</td></tr></table>";
- var tds = div.getElementsByTagName("td");
-
- // Check if table cells still have offsetWidth/Height when they are set
- // to display:none and there are still other visible table cells in a
- // table row; if so, offsetWidth/Height are not reliable for use when
- // determining if an element has been hidden directly using
- // display:none (it is still safe to use offsets if a parent element is
- // hidden; don safety goggles and see bug #4512 for more information).
- // (only IE 8 fails this test)
- jQuery.support.reliableHiddenOffsets = tds[0].offsetHeight === 0;
-
- tds[0].style.display = "";
- tds[1].style.display = "none";
-
- // Check if empty table cells still have offsetWidth/Height
- // (IE < 8 fail this test)
- jQuery.support.reliableHiddenOffsets = jQuery.support.reliableHiddenOffsets && tds[0].offsetHeight === 0;
- div.innerHTML = "";
-
- document.body.removeChild( div ).style.display = "none";
- div = tds = null;
- });
-
- // Technique from Juriy Zaytsev
- // http://thinkweb2.com/projects/prototype/detecting-event-support-without-b...
- var eventSupported = function( eventName ) {
- var el = document.createElement("div");
- eventName = "on" + eventName;
-
- var isSupported = (eventName in el);
- if ( !isSupported ) {
- el.setAttribute(eventName, "return;");
- isSupported = typeof el[eventName] === "function";
- }
- el = null;
-
- return isSupported;
- };
-
- jQuery.support.submitBubbles = eventSupported("submit");
- jQuery.support.changeBubbles = eventSupported("change");
-
- // release memory in IE
- root = script = div = all = a = null;
-})();
-
-
-
-var windowData = {},
- rbrace = /^(?:\{.*\}|\[.*\])$/;
-
-jQuery.extend({
- cache: {},
-
- // Please use with caution
- uuid: 0,
-
- // Unique for each copy of jQuery on the page
- expando: "jQuery" + jQuery.now(),
-
- // The following elements throw uncatchable exceptions if you
- // attempt to add expando properties to them.
- noData: {
- "embed": true,
- // Ban all objects except for Flash (which handle expandos)
- "object": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",
- "applet": true
- },
-
- data: function( elem, name, data ) {
- if ( !jQuery.acceptData( elem ) ) {
- return;
- }
-
- elem = elem == window ?
- windowData :
- elem;
-
- var isNode = elem.nodeType,
- id = isNode ? elem[ jQuery.expando ] : null,
- cache = jQuery.cache, thisCache;
-
- if ( isNode && !id && typeof name === "string" && data === undefined ) {
- return;
- }
-
- // Get the data from the object directly
- if ( !isNode ) {
- cache = elem;
-
- // Compute a unique ID for the element
- } else if ( !id ) {
- elem[ jQuery.expando ] = id = ++jQuery.uuid;
- }
-
- // Avoid generating a new cache unless none exists and we
- // want to manipulate it.
- if ( typeof name === "object" ) {
- if ( isNode ) {
- cache[ id ] = jQuery.extend(cache[ id ], name);
-
- } else {
- jQuery.extend( cache, name );
- }
-
- } else if ( isNode && !cache[ id ] ) {
- cache[ id ] = {};
- }
-
- thisCache = isNode ? cache[ id ] : cache;
-
- // Prevent overriding the named cache with undefined values
- if ( data !== undefined ) {
- thisCache[ name ] = data;
- }
-
- return typeof name === "string" ? thisCache[ name ] : thisCache;
- },
-
- removeData: function( elem, name ) {
- if ( !jQuery.acceptData( elem ) ) {
- return;
- }
-
- elem = elem == window ?
- windowData :
- elem;
-
- var isNode = elem.nodeType,
- id = isNode ? elem[ jQuery.expando ] : elem,
- cache = jQuery.cache,
- thisCache = isNode ? cache[ id ] : id;
-
- // If we want to remove a specific section of the element's data
- if ( name ) {
- if ( thisCache ) {
- // Remove the section of cache data
- delete thisCache[ name ];
-
- // If we've removed all the data, remove the element's cache
- if ( isNode && jQuery.isEmptyObject(thisCache) ) {
- jQuery.removeData( elem );
- }
- }
-
- // Otherwise, we want to remove all of the element's data
- } else {
- if ( isNode && jQuery.support.deleteExpando ) {
- delete elem[ jQuery.expando ];
-
- } else if ( elem.removeAttribute ) {
- elem.removeAttribute( jQuery.expando );
-
- // Completely remove the data cache
- } else if ( isNode ) {
- delete cache[ id ];
-
- // Remove all fields from the object
- } else {
- for ( var n in elem ) {
- delete elem[ n ];
- }
- }
- }
- },
-
- // A method for determining if a DOM node can handle the data expando
- acceptData: function( elem ) {
- if ( elem.nodeName ) {
- var match = jQuery.noData[ elem.nodeName.toLowerCase() ];
-
- if ( match ) {
- return !(match === true || elem.getAttribute("classid") !== match);
- }
- }
-
- return true;
- }
-});
-
-jQuery.fn.extend({
- data: function( key, value ) {
- var data = null;
-
- if ( typeof key === "undefined" ) {
- if ( this.length ) {
- var attr = this[0].attributes, name;
- data = jQuery.data( this[0] );
-
- for ( var i = 0, l = attr.length; i < l; i++ ) {
- name = attr[i].name;
-
- if ( name.indexOf( "data-" ) === 0 ) {
- name = name.substr( 5 );
- dataAttr( this[0], name, data[ name ] );
- }
- }
- }
-
- return data;
-
- } else if ( typeof key === "object" ) {
- return this.each(function() {
- jQuery.data( this, key );
- });
- }
-
- var parts = key.split(".");
- parts[1] = parts[1] ? "." + parts[1] : "";
-
- if ( value === undefined ) {
- data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]);
-
- // Try to fetch any internally stored data first
- if ( data === undefined && this.length ) {
- data = jQuery.data( this[0], key );
- data = dataAttr( this[0], key, data );
- }
-
- return data === undefined && parts[1] ?
- this.data( parts[0] ) :
- data;
-
- } else {
- return this.each(function() {
- var $this = jQuery( this ),
- args = [ parts[0], value ];
-
- $this.triggerHandler( "setData" + parts[1] + "!", args );
- jQuery.data( this, key, value );
- $this.triggerHandler( "changeData" + parts[1] + "!", args );
- });
- }
- },
-
- removeData: function( key ) {
- return this.each(function() {
- jQuery.removeData( this, key );
- });
- }
-});
-
-function dataAttr( elem, key, data ) {
- // If nothing was found internally, try to fetch any
- // data from the HTML5 data-* attribute
- if ( data === undefined && elem.nodeType === 1 ) {
- data = elem.getAttribute( "data-" + key );
-
- if ( typeof data === "string" ) {
- try {
- data = data === "true" ? true :
- data === "false" ? false :
- data === "null" ? null :
- !jQuery.isNaN( data ) ? parseFloat( data ) :
- rbrace.test( data ) ? jQuery.parseJSON( data ) :
- data;
- } catch( e ) {}
-
- // Make sure we set the data so it isn't changed later
- jQuery.data( elem, key, data );
-
- } else {
- data = undefined;
- }
- }
-
- return data;
-}
-
-
-
-
-jQuery.extend({
- queue: function( elem, type, data ) {
- if ( !elem ) {
- return;
- }
-
- type = (type || "fx") + "queue";
- var q = jQuery.data( elem, type );
-
- // Speed up dequeue by getting out quickly if this is just a lookup
- if ( !data ) {
- return q || [];
- }
-
- if ( !q || jQuery.isArray(data) ) {
- q = jQuery.data( elem, type, jQuery.makeArray(data) );
-
- } else {
- q.push( data );
- }
-
- return q;
- },
-
- dequeue: function( elem, type ) {
- type = type || "fx";
-
- var queue = jQuery.queue( elem, type ),
- fn = queue.shift();
-
- // If the fx queue is dequeued, always remove the progress sentinel
- if ( fn === "inprogress" ) {
- fn = queue.shift();
- }
-
- if ( fn ) {
- // Add a progress sentinel to prevent the fx queue from being
- // automatically dequeued
- if ( type === "fx" ) {
- queue.unshift("inprogress");
- }
-
- fn.call(elem, function() {
- jQuery.dequeue(elem, type);
- });
- }
- }
-});
-
-jQuery.fn.extend({
- queue: function( type, data ) {
- if ( typeof type !== "string" ) {
- data = type;
- type = "fx";
- }
-
- if ( data === undefined ) {
- return jQuery.queue( this[0], type );
- }
- return this.each(function( i ) {
- var queue = jQuery.queue( this, type, data );
-
- if ( type === "fx" && queue[0] !== "inprogress" ) {
- jQuery.dequeue( this, type );
- }
- });
- },
- dequeue: function( type ) {
- return this.each(function() {
- jQuery.dequeue( this, type );
- });
- },
-
- // Based off of the plugin by Clint Helfers, with permission.
- // http://blindsignals.com/index.php/2009/07/jquery-delay/
- delay: function( time, type ) {
- time = jQuery.fx ? jQuery.fx.speeds[time] || time : time;
- type = type || "fx";
-
- return this.queue( type, function() {
- var elem = this;
- setTimeout(function() {
- jQuery.dequeue( elem, type );
- }, time );
- });
- },
-
- clearQueue: function( type ) {
- return this.queue( type || "fx", [] );
- }
-});
-
-
-
-
-var rclass = /[\n\t]/g,
- rspaces = /\s+/,
- rreturn = /\r/g,
- rspecialurl = /^(?:href|src|style)$/,
- rtype = /^(?:button|input)$/i,
- rfocusable = /^(?:button|input|object|select|textarea)$/i,
- rclickable = /^a(?:rea)?$/i,
- rradiocheck = /^(?:radio|checkbox)$/i;
-
-jQuery.props = {
- "for": "htmlFor",
- "class": "className",
- readonly: "readOnly",
- maxlength: "maxLength",
- cellspacing: "cellSpacing",
- rowspan: "rowSpan",
- colspan: "colSpan",
- tabindex: "tabIndex",
- usemap: "useMap",
- frameborder: "frameBorder"
-};
-
-jQuery.fn.extend({
- attr: function( name, value ) {
- return jQuery.access( this, name, value, true, jQuery.attr );
- },
-
- removeAttr: function( name, fn ) {
- return this.each(function(){
- jQuery.attr( this, name, "" );
- if ( this.nodeType === 1 ) {
- this.removeAttribute( name );
- }
- });
- },
-
- addClass: function( value ) {
- if ( jQuery.isFunction(value) ) {
- return this.each(function(i) {
- var self = jQuery(this);
- self.addClass( value.call(this, i, self.attr("class")) );
- });
- }
-
- if ( value && typeof value === "string" ) {
- var classNames = (value || "").split( rspaces );
-
- for ( var i = 0, l = this.length; i < l; i++ ) {
- var elem = this[i];
-
- if ( elem.nodeType === 1 ) {
- if ( !elem.className ) {
- elem.className = value;
-
- } else {
- var className = " " + elem.className + " ",
- setClass = elem.className;
-
- for ( var c = 0, cl = classNames.length; c < cl; c++ ) {
- if ( className.indexOf( " " + classNames[c] + " " ) < 0 ) {
- setClass += " " + classNames[c];
- }
- }
- elem.className = jQuery.trim( setClass );
- }
- }
- }
- }
-
- return this;
- },
-
- removeClass: function( value ) {
- if ( jQuery.isFunction(value) ) {
- return this.each(function(i) {
- var self = jQuery(this);
- self.removeClass( value.call(this, i, self.attr("class")) );
- });
- }
-
- if ( (value && typeof value === "string") || value === undefined ) {
- var classNames = (value || "").split( rspaces );
-
- for ( var i = 0, l = this.length; i < l; i++ ) {
- var elem = this[i];
-
- if ( elem.nodeType === 1 && elem.className ) {
- if ( value ) {
- var className = (" " + elem.className + " ").replace(rclass, " ");
- for ( var c = 0, cl = classNames.length; c < cl; c++ ) {
- className = className.replace(" " + classNames[c] + " ", " ");
- }
- elem.className = jQuery.trim( className );
-
- } else {
- elem.className = "";
- }
- }
- }
- }
-
- return this;
- },
-
- toggleClass: function( value, stateVal ) {
- var type = typeof value,
- isBool = typeof stateVal === "boolean";
-
- if ( jQuery.isFunction( value ) ) {
- return this.each(function(i) {
- var self = jQuery(this);
- self.toggleClass( value.call(this, i, self.attr("class"), stateVal), stateVal );
- });
- }
-
- return this.each(function() {
- if ( type === "string" ) {
- // toggle individual class names
- var className,
- i = 0,
- self = jQuery( this ),
- state = stateVal,
- classNames = value.split( rspaces );
-
- while ( (className = classNames[ i++ ]) ) {
- // check each className given, space seperated list
- state = isBool ? state : !self.hasClass( className );
- self[ state ? "addClass" : "removeClass" ]( className );
- }
-
- } else if ( type === "undefined" || type === "boolean" ) {
- if ( this.className ) {
- // store className if set
- jQuery.data( this, "__className__", this.className );
- }
-
- // toggle whole className
- this.className = this.className || value === false ? "" : jQuery.data( this, "__className__" ) || "";
- }
- });
- },
-
- hasClass: function( selector ) {
- var className = " " + selector + " ";
- for ( var i = 0, l = this.length; i < l; i++ ) {
- if ( (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) > -1 ) {
- return true;
- }
- }
-
- return false;
- },
-
- val: function( value ) {
- if ( !arguments.length ) {
- var elem = this[0];
-
- if ( elem ) {
- if ( jQuery.nodeName( elem, "option" ) ) {
- // attributes.value is undefined in Blackberry 4.7 but
- // uses .value. See #6932
- var val = elem.attributes.value;
- return !val || val.specified ? elem.value : elem.text;
- }
-
- // We need to handle select boxes special
- if ( jQuery.nodeName( elem, "select" ) ) {
- var index = elem.selectedIndex,
- values = [],
- options = elem.options,
- one = elem.type === "select-one";
-
- // Nothing was selected
- if ( index < 0 ) {
- return null;
- }
-
- // Loop through all the selected options
- for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) {
- var option = options[ i ];
-
- // Don't return options that are disabled or in a disabled optgroup
- if ( option.selected && (jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null) &&
- (!option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" )) ) {
-
- // Get the specific value for the option
- value = jQuery(option).val();
-
- // We don't need an array for one selects
- if ( one ) {
- return value;
- }
-
- // Multi-Selects return an array
- values.push( value );
- }
- }
-
- return values;
- }
-
- // Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified
- if ( rradiocheck.test( elem.type ) && !jQuery.support.checkOn ) {
- return elem.getAttribute("value") === null ? "on" : elem.value;
- }
-
-
- // Everything else, we just grab the value
- return (elem.value || "").replace(rreturn, "");
-
- }
-
- return undefined;
- }
-
- var isFunction = jQuery.isFunction(value);
-
- return this.each(function(i) {
- var self = jQuery(this), val = value;
-
- if ( this.nodeType !== 1 ) {
- return;
- }
-
- if ( isFunction ) {
- val = value.call(this, i, self.val());
- }
-
- // Treat null/undefined as ""; convert numbers to string
- if ( val == null ) {
- val = "";
- } else if ( typeof val === "number" ) {
- val += "";
- } else if ( jQuery.isArray(val) ) {
- val = jQuery.map(val, function (value) {
- return value == null ? "" : value + "";
- });
- }
-
- if ( jQuery.isArray(val) && rradiocheck.test( this.type ) ) {
- this.checked = jQuery.inArray( self.val(), val ) >= 0;
-
- } else if ( jQuery.nodeName( this, "select" ) ) {
- var values = jQuery.makeArray(val);
-
- jQuery( "option", this ).each(function() {
- this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0;
- });
-
- if ( !values.length ) {
- this.selectedIndex = -1;
- }
-
- } else {
- this.value = val;
- }
- });
- }
-});
-
-jQuery.extend({
- attrFn: {
- val: true,
- css: true,
- html: true,
- text: true,
- data: true,
- width: true,
- height: true,
- offset: true
- },
-
- attr: function( elem, name, value, pass ) {
- // don't set attributes on text and comment nodes
- if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 ) {
- return undefined;
- }
-
- if ( pass && name in jQuery.attrFn ) {
- return jQuery(elem)[name](value);
- }
-
- var notxml = elem.nodeType !== 1 || !jQuery.isXMLDoc( elem ),
- // Whether we are setting (or getting)
- set = value !== undefined;
-
- // Try to normalize/fix the name
- name = notxml && jQuery.props[ name ] || name;
-
- // These attributes require special treatment
- var special = rspecialurl.test( name );
-
- // Safari mis-reports the default selected property of an option
- // Accessing the parent's selectedIndex property fixes it
- if ( name === "selected" && !jQuery.support.optSelected ) {
- var parent = elem.parentNode;
- if ( parent ) {
- parent.selectedIndex;
-
- // Make sure that it also works with optgroups, see #5701
- if ( parent.parentNode ) {
- parent.parentNode.selectedIndex;
- }
- }
- }
-
- // If applicable, access the attribute via the DOM 0 way
- // 'in' checks fail in Blackberry 4.7 #6931
- if ( (name in elem || elem[ name ] !== undefined) && notxml && !special ) {
- if ( set ) {
- // We can't allow the type property to be changed (since it causes problems in IE)
- if ( name === "type" && rtype.test( elem.nodeName ) && elem.parentNode ) {
- jQuery.error( "type property can't be changed" );
- }
-
- if ( value === null ) {
- if ( elem.nodeType === 1 ) {
- elem.removeAttribute( name );
- }
-
- } else {
- elem[ name ] = value;
- }
- }
-
- // browsers index elements by id/name on forms, give priority to attributes.
- if ( jQuery.nodeName( elem, "form" ) && elem.getAttributeNode(name) ) {
- return elem.getAttributeNode( name ).nodeValue;
- }
-
- // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set
- // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabi...
- if ( name === "tabIndex" ) {
- var attributeNode = elem.getAttributeNode( "tabIndex" );
-
- return attributeNode && attributeNode.specified ?
- attributeNode.value :
- rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ?
- 0 :
- undefined;
- }
-
- return elem[ name ];
- }
-
- if ( !jQuery.support.style && notxml && name === "style" ) {
- if ( set ) {
- elem.style.cssText = "" + value;
- }
-
- return elem.style.cssText;
- }
-
- if ( set ) {
- // convert the value to a string (all browsers do this but IE) see #1070
- elem.setAttribute( name, "" + value );
- }
-
- // Ensure that missing attributes return undefined
- // Blackberry 4.7 returns "" from getAttribute #6938
- if ( !elem.attributes[ name ] && (elem.hasAttribute && !elem.hasAttribute( name )) ) {
- return undefined;
- }
-
- var attr = !jQuery.support.hrefNormalized && notxml && special ?
- // Some attributes require a special call on IE
- elem.getAttribute( name, 2 ) :
- elem.getAttribute( name );
-
- // Non-existent attributes return null, we normalize to undefined
- return attr === null ? undefined : attr;
- }
-});
-
-
-
-
-var rnamespaces = /\.(.*)$/,
- rformElems = /^(?:textarea|input|select)$/i,
- rperiod = /\./g,
- rspace = / /g,
- rescape = /[^\w\s.|`]/g,
- fcleanup = function( nm ) {
- return nm.replace(rescape, "\\$&");
- },
- focusCounts = { focusin: 0, focusout: 0 };
-
-/*
- * A number of helper functions used for managing events.
- * Many of the ideas behind this code originated from
- * Dean Edwards' addEvent library.
- */
-jQuery.event = {
-
- // Bind an event to an element
- // Original by Dean Edwards
- add: function( elem, types, handler, data ) {
- if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
- return;
- }
-
- // For whatever reason, IE has trouble passing the window object
- // around, causing it to be cloned in the process
- if ( jQuery.isWindow( elem ) && ( elem !== window && !elem.frameElement ) ) {
- elem = window;
- }
-
- if ( handler === false ) {
- handler = returnFalse;
- } else if ( !handler ) {
- // Fixes bug #7229. Fix recommended by jdalton
- return;
- }
-
- var handleObjIn, handleObj;
-
- if ( handler.handler ) {
- handleObjIn = handler;
- handler = handleObjIn.handler;
- }
-
- // Make sure that the function being executed has a unique ID
- if ( !handler.guid ) {
- handler.guid = jQuery.guid++;
- }
-
- // Init the element's event structure
- var elemData = jQuery.data( elem );
-
- // If no elemData is found then we must be trying to bind to one of the
- // banned noData elements
- if ( !elemData ) {
- return;
- }
-
- // Use a key less likely to result in collisions for plain JS objects.
- // Fixes bug #7150.
- var eventKey = elem.nodeType ? "events" : "__events__",
- events = elemData[ eventKey ],
- eventHandle = elemData.handle;
-
- if ( typeof events === "function" ) {
- // On plain objects events is a fn that holds the the data
- // which prevents this data from being JSON serialized
- // the function does not need to be called, it just contains the data
- eventHandle = events.handle;
- events = events.events;
-
- } else if ( !events ) {
- if ( !elem.nodeType ) {
- // On plain objects, create a fn that acts as the holder
- // of the values to avoid JSON serialization of event data
- elemData[ eventKey ] = elemData = function(){};
- }
-
- elemData.events = events = {};
- }
-
- if ( !eventHandle ) {
- elemData.handle = eventHandle = function() {
- // Handle the second event of a trigger and when
- // an event is called after a page has unloaded
- return typeof jQuery !== "undefined" && !jQuery.event.triggered ?
- jQuery.event.handle.apply( eventHandle.elem, arguments ) :
- undefined;
- };
- }
-
- // Add elem as a property of the handle function
- // This is to prevent a memory leak with non-native events in IE.
- eventHandle.elem = elem;
-
- // Handle multiple events separated by a space
- // jQuery(...).bind("mouseover mouseout", fn);
- types = types.split(" ");
-
- var type, i = 0, namespaces;
-
- while ( (type = types[ i++ ]) ) {
- handleObj = handleObjIn ?
- jQuery.extend({}, handleObjIn) :
- { handler: handler, data: data };
-
- // Namespaced event handlers
- if ( type.indexOf(".") > -1 ) {
- namespaces = type.split(".");
- type = namespaces.shift();
- handleObj.namespace = namespaces.slice(0).sort().join(".");
-
- } else {
- namespaces = [];
- handleObj.namespace = "";
- }
-
- handleObj.type = type;
- if ( !handleObj.guid ) {
- handleObj.guid = handler.guid;
- }
-
- // Get the current list of functions bound to this event
- var handlers = events[ type ],
- special = jQuery.event.special[ type ] || {};
-
- // Init the event handler queue
- if ( !handlers ) {
- handlers = events[ type ] = [];
-
- // Check for a special event handler
- // Only use addEventListener/attachEvent if the special
- // events handler returns false
- if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
- // Bind the global event handler to the element
- if ( elem.addEventListener ) {
- elem.addEventListener( type, eventHandle, false );
-
- } else if ( elem.attachEvent ) {
- elem.attachEvent( "on" + type, eventHandle );
- }
- }
- }
-
- if ( special.add ) {
- special.add.call( elem, handleObj );
-
- if ( !handleObj.handler.guid ) {
- handleObj.handler.guid = handler.guid;
- }
- }
-
- // Add the function to the element's handler list
- handlers.push( handleObj );
-
- // Keep track of which events have been used, for global triggering
- jQuery.event.global[ type ] = true;
- }
-
- // Nullify elem to prevent memory leaks in IE
- elem = null;
- },
-
- global: {},
-
- // Detach an event or set of events from an element
- remove: function( elem, types, handler, pos ) {
- // don't do events on text and comment nodes
- if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
- return;
- }
-
- if ( handler === false ) {
- handler = returnFalse;
- }
-
- var ret, type, fn, j, i = 0, all, namespaces, namespace, special, eventType, handleObj, origType,
- eventKey = elem.nodeType ? "events" : "__events__",
- elemData = jQuery.data( elem ),
- events = elemData && elemData[ eventKey ];
-
- if ( !elemData || !events ) {
- return;
- }
-
- if ( typeof events === "function" ) {
- elemData = events;
- events = events.events;
- }
-
- // types is actually an event object here
- if ( types && types.type ) {
- handler = types.handler;
- types = types.type;
- }
-
- // Unbind all events for the element
- if ( !types || typeof types === "string" && types.charAt(0) === "." ) {
- types = types || "";
-
- for ( type in events ) {
- jQuery.event.remove( elem, type + types );
- }
-
- return;
- }
-
- // Handle multiple events separated by a space
- // jQuery(...).unbind("mouseover mouseout", fn);
- types = types.split(" ");
-
- while ( (type = types[ i++ ]) ) {
- origType = type;
- handleObj = null;
- all = type.indexOf(".") < 0;
- namespaces = [];
-
- if ( !all ) {
- // Namespaced event handlers
- namespaces = type.split(".");
- type = namespaces.shift();
-
- namespace = new RegExp("(^|\\.)" +
- jQuery.map( namespaces.slice(0).sort(), fcleanup ).join("\\.(?:.*\\.)?") + "(\\.|$)");
- }
-
- eventType = events[ type ];
-
- if ( !eventType ) {
- continue;
- }
-
- if ( !handler ) {
- for ( j = 0; j < eventType.length; j++ ) {
- handleObj = eventType[ j ];
-
- if ( all || namespace.test( handleObj.namespace ) ) {
- jQuery.event.remove( elem, origType, handleObj.handler, j );
- eventType.splice( j--, 1 );
- }
- }
-
- continue;
- }
-
- special = jQuery.event.special[ type ] || {};
-
- for ( j = pos || 0; j < eventType.length; j++ ) {
- handleObj = eventType[ j ];
-
- if ( handler.guid === handleObj.guid ) {
- // remove the given handler for the given type
- if ( all || namespace.test( handleObj.namespace ) ) {
- if ( pos == null ) {
- eventType.splice( j--, 1 );
- }
-
- if ( special.remove ) {
- special.remove.call( elem, handleObj );
- }
- }
-
- if ( pos != null ) {
- break;
- }
- }
- }
-
- // remove generic event handler if no more handlers exist
- if ( eventType.length === 0 || pos != null && eventType.length === 1 ) {
- if ( !special.teardown || special.teardown.call( elem, namespaces ) === false ) {
- jQuery.removeEvent( elem, type, elemData.handle );
- }
-
- ret = null;
- delete events[ type ];
- }
- }
-
- // Remove the expando if it's no longer used
- if ( jQuery.isEmptyObject( events ) ) {
- var handle = elemData.handle;
- if ( handle ) {
- handle.elem = null;
- }
-
- delete elemData.events;
- delete elemData.handle;
-
- if ( typeof elemData === "function" ) {
- jQuery.removeData( elem, eventKey );
-
- } else if ( jQuery.isEmptyObject( elemData ) ) {
- jQuery.removeData( elem );
- }
- }
- },
-
- // bubbling is internal
- trigger: function( event, data, elem /*, bubbling */ ) {
- // Event object or event type
- var type = event.type || event,
- bubbling = arguments[3];
-
- if ( !bubbling ) {
- event = typeof event === "object" ?
- // jQuery.Event object
- event[ jQuery.expando ] ? event :
- // Object literal
- jQuery.extend( jQuery.Event(type), event ) :
- // Just the event type (string)
- jQuery.Event(type);
-
- if ( type.indexOf("!") >= 0 ) {
- event.type = type = type.slice(0, -1);
- event.exclusive = true;
- }
-
- // Handle a global trigger
- if ( !elem ) {
- // Don't bubble custom events when global (to avoid too much overhead)
- event.stopPropagation();
-
- // Only trigger if we've ever bound an event for it
- if ( jQuery.event.global[ type ] ) {
- jQuery.each( jQuery.cache, function() {
- if ( this.events && this.events[type] ) {
- jQuery.event.trigger( event, data, this.handle.elem );
- }
- });
- }
- }
-
- // Handle triggering a single element
-
- // don't do events on text and comment nodes
- if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 ) {
- return undefined;
- }
-
- // Clean up in case it is reused
- event.result = undefined;
- event.target = elem;
-
- // Clone the incoming data, if any
- data = jQuery.makeArray( data );
- data.unshift( event );
- }
-
- event.currentTarget = elem;
-
- // Trigger the event, it is assumed that "handle" is a function
- var handle = elem.nodeType ?
- jQuery.data( elem, "handle" ) :
- (jQuery.data( elem, "__events__" ) || {}).handle;
-
- if ( handle ) {
- handle.apply( elem, data );
- }
-
- var parent = elem.parentNode || elem.ownerDocument;
-
- // Trigger an inline bound script
- try {
- if ( !(elem && elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()]) ) {
- if ( elem[ "on" + type ] && elem[ "on" + type ].apply( elem, data ) === false ) {
- event.result = false;
- event.preventDefault();
- }
- }
-
- // prevent IE from throwing an error for some elements with some event types, see #3533
- } catch (inlineError) {}
-
- if ( !event.isPropagationStopped() && parent ) {
- jQuery.event.trigger( event, data, parent, true );
-
- } else if ( !event.isDefaultPrevented() ) {
- var old,
- target = event.target,
- targetType = type.replace( rnamespaces, "" ),
- isClick = jQuery.nodeName( target, "a" ) && targetType === "click",
- special = jQuery.event.special[ targetType ] || {};
-
- if ( (!special._default || special._default.call( elem, event ) === false) &&
- !isClick && !(target && target.nodeName && jQuery.noData[target.nodeName.toLowerCase()]) ) {
-
- try {
- if ( target[ targetType ] ) {
- // Make sure that we don't accidentally re-trigger the onFOO events
- old = target[ "on" + targetType ];
-
- if ( old ) {
- target[ "on" + targetType ] = null;
- }
-
- jQuery.event.triggered = true;
- target[ targetType ]();
- }
-
- // prevent IE from throwing an error for some elements with some event types, see #3533
- } catch (triggerError) {}
-
- if ( old ) {
- target[ "on" + targetType ] = old;
- }
-
- jQuery.event.triggered = false;
- }
- }
- },
-
- handle: function( event ) {
- var all, handlers, namespaces, namespace_re, events,
- namespace_sort = [],
- args = jQuery.makeArray( arguments );
-
- event = args[0] = jQuery.event.fix( event || window.event );
- event.currentTarget = this;
-
- // Namespaced event handlers
- all = event.type.indexOf(".") < 0 && !event.exclusive;
-
- if ( !all ) {
- namespaces = event.type.split(".");
- event.type = namespaces.shift();
- namespace_sort = namespaces.slice(0).sort();
- namespace_re = new RegExp("(^|\\.)" + namespace_sort.join("\\.(?:.*\\.)?") + "(\\.|$)");
- }
-
- event.namespace = event.namespace || namespace_sort.join(".");
-
- events = jQuery.data(this, this.nodeType ? "events" : "__events__");
-
- if ( typeof events === "function" ) {
- events = events.events;
- }
-
- handlers = (events || {})[ event.type ];
-
- if ( events && handlers ) {
- // Clone the handlers to prevent manipulation
- handlers = handlers.slice(0);
-
- for ( var j = 0, l = handlers.length; j < l; j++ ) {
- var handleObj = handlers[ j ];
-
- // Filter the functions by class
- if ( all || namespace_re.test( handleObj.namespace ) ) {
- // Pass in a reference to the handler function itself
- // So that we can later remove it
- event.handler = handleObj.handler;
- event.data = handleObj.data;
- event.handleObj = handleObj;
-
- var ret = handleObj.handler.apply( this, args );
-
- if ( ret !== undefined ) {
- event.result = ret;
- if ( ret === false ) {
- event.preventDefault();
- event.stopPropagation();
- }
- }
-
- if ( event.isImmediatePropagationStopped() ) {
- break;
- }
- }
- }
- }
-
- return event.result;
- },
-
- props: "altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode layerX layerY metaKey newValue offsetX offsetY pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),
-
- fix: function( event ) {
- if ( event[ jQuery.expando ] ) {
- return event;
- }
-
- // store a copy of the original event object
- // and "clone" to set read-only properties
- var originalEvent = event;
- event = jQuery.Event( originalEvent );
-
- for ( var i = this.props.length, prop; i; ) {
- prop = this.props[ --i ];
- event[ prop ] = originalEvent[ prop ];
- }
-
- // Fix target property, if necessary
- if ( !event.target ) {
- // Fixes #1925 where srcElement might not be defined either
- event.target = event.srcElement || document;
- }
-
- // check if target is a textnode (safari)
- if ( event.target.nodeType === 3 ) {
- event.target = event.target.parentNode;
- }
-
- // Add relatedTarget, if necessary
- if ( !event.relatedTarget && event.fromElement ) {
- event.relatedTarget = event.fromElement === event.target ? event.toElement : event.fromElement;
- }
-
- // Calculate pageX/Y if missing and clientX/Y available
- if ( event.pageX == null && event.clientX != null ) {
- var doc = document.documentElement,
- body = document.body;
-
- event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0);
- event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc && doc.clientTop || body && body.clientTop || 0);
- }
-
- // Add which for key events
- if ( event.which == null && (event.charCode != null || event.keyCode != null) ) {
- event.which = event.charCode != null ? event.charCode : event.keyCode;
- }
-
- // Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs)
- if ( !event.metaKey && event.ctrlKey ) {
- event.metaKey = event.ctrlKey;
- }
-
- // Add which for click: 1 === left; 2 === middle; 3 === right
- // Note: button is not normalized, so don't use it
- if ( !event.which && event.button !== undefined ) {
- event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) ));
- }
-
- return event;
- },
-
- // Deprecated, use jQuery.guid instead
- guid: 1E8,
-
- // Deprecated, use jQuery.proxy instead
- proxy: jQuery.proxy,
-
- special: {
- ready: {
- // Make sure the ready event is setup
- setup: jQuery.bindReady,
- teardown: jQuery.noop
- },
-
- live: {
- add: function( handleObj ) {
- jQuery.event.add( this,
- liveConvert( handleObj.origType, handleObj.selector ),
- jQuery.extend({}, handleObj, {handler: liveHandler, guid: handleObj.handler.guid}) );
- },
-
- remove: function( handleObj ) {
- jQuery.event.remove( this, liveConvert( handleObj.origType, handleObj.selector ), handleObj );
- }
- },
-
- beforeunload: {
- setup: function( data, namespaces, eventHandle ) {
- // We only want to do this special case on windows
- if ( jQuery.isWindow( this ) ) {
- this.onbeforeunload = eventHandle;
- }
- },
-
- teardown: function( namespaces, eventHandle ) {
- if ( this.onbeforeunload === eventHandle ) {
- this.onbeforeunload = null;
- }
- }
- }
- }
-};
-
-jQuery.removeEvent = document.removeEventListener ?
- function( elem, type, handle ) {
- if ( elem.removeEventListener ) {
- elem.removeEventListener( type, handle, false );
- }
- } :
- function( elem, type, handle ) {
- if ( elem.detachEvent ) {
- elem.detachEvent( "on" + type, handle );
- }
- };
-
-jQuery.Event = function( src ) {
- // Allow instantiation without the 'new' keyword
- if ( !this.preventDefault ) {
- return new jQuery.Event( src );
- }
-
- // Event object
- if ( src && src.type ) {
- this.originalEvent = src;
- this.type = src.type;
- // Event type
- } else {
- this.type = src;
- }
-
- // timeStamp is buggy for some events on Firefox(#3843)
- // So we won't rely on the native value
- this.timeStamp = jQuery.now();
-
- // Mark it as fixed
- this[ jQuery.expando ] = true;
-};
-
-function returnFalse() {
- return false;
-}
-function returnTrue() {
- return true;
-}
-
-// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
-// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-bind...
-jQuery.Event.prototype = {
- preventDefault: function() {
- this.isDefaultPrevented = returnTrue;
-
- var e = this.originalEvent;
- if ( !e ) {
- return;
- }
-
- // if preventDefault exists run it on the original event
- if ( e.preventDefault ) {
- e.preventDefault();
-
- // otherwise set the returnValue property of the original event to false (IE)
- } else {
- e.returnValue = false;
- }
- },
- stopPropagation: function() {
- this.isPropagationStopped = returnTrue;
-
- var e = this.originalEvent;
- if ( !e ) {
- return;
- }
- // if stopPropagation exists run it on the original event
- if ( e.stopPropagation ) {
- e.stopPropagation();
- }
- // otherwise set the cancelBubble property of the original event to true (IE)
- e.cancelBubble = true;
- },
- stopImmediatePropagation: function() {
- this.isImmediatePropagationStopped = returnTrue;
- this.stopPropagation();
- },
- isDefaultPrevented: returnFalse,
- isPropagationStopped: returnFalse,
- isImmediatePropagationStopped: returnFalse
-};
-
-// Checks if an event happened on an element within another element
-// Used in jQuery.event.special.mouseenter and mouseleave handlers
-var withinElement = function( event ) {
- // Check if mouse(over|out) are still within the same parent element
- var parent = event.relatedTarget;
-
- // Firefox sometimes assigns relatedTarget a XUL element
- // which we cannot access the parentNode property of
- try {
- // Traverse up the tree
- while ( parent && parent !== this ) {
- parent = parent.parentNode;
- }
-
- if ( parent !== this ) {
- // set the correct event type
- event.type = event.data;
-
- // handle event if we actually just moused on to a non sub-element
- jQuery.event.handle.apply( this, arguments );
- }
-
- // assuming we've left the element since we most likely mousedover a xul element
- } catch(e) { }
-},
-
-// In case of event delegation, we only need to rename the event.type,
-// liveHandler will take care of the rest.
-delegate = function( event ) {
- event.type = event.data;
- jQuery.event.handle.apply( this, arguments );
-};
-
-// Create mouseenter and mouseleave events
-jQuery.each({
- mouseenter: "mouseover",
- mouseleave: "mouseout"
-}, function( orig, fix ) {
- jQuery.event.special[ orig ] = {
- setup: function( data ) {
- jQuery.event.add( this, fix, data && data.selector ? delegate : withinElement, orig );
- },
- teardown: function( data ) {
- jQuery.event.remove( this, fix, data && data.selector ? delegate : withinElement );
- }
- };
-});
-
-// submit delegation
-if ( !jQuery.support.submitBubbles ) {
-
- jQuery.event.special.submit = {
- setup: function( data, namespaces ) {
- if ( this.nodeName.toLowerCase() !== "form" ) {
- jQuery.event.add(this, "click.specialSubmit", function( e ) {
- var elem = e.target,
- type = elem.type;
-
- if ( (type === "submit" || type === "image") && jQuery( elem ).closest("form").length ) {
- e.liveFired = undefined;
- return trigger( "submit", this, arguments );
- }
- });
-
- jQuery.event.add(this, "keypress.specialSubmit", function( e ) {
- var elem = e.target,
- type = elem.type;
-
- if ( (type === "text" || type === "password") && jQuery( elem ).closest("form").length && e.keyCode === 13 ) {
- e.liveFired = undefined;
- return trigger( "submit", this, arguments );
- }
- });
-
- } else {
- return false;
- }
- },
-
- teardown: function( namespaces ) {
- jQuery.event.remove( this, ".specialSubmit" );
- }
- };
-
-}
-
-// change delegation, happens here so we have bind.
-if ( !jQuery.support.changeBubbles ) {
-
- var changeFilters,
-
- getVal = function( elem ) {
- var type = elem.type, val = elem.value;
-
- if ( type === "radio" || type === "checkbox" ) {
- val = elem.checked;
-
- } else if ( type === "select-multiple" ) {
- val = elem.selectedIndex > -1 ?
- jQuery.map( elem.options, function( elem ) {
- return elem.selected;
- }).join("-") :
- "";
-
- } else if ( elem.nodeName.toLowerCase() === "select" ) {
- val = elem.selectedIndex;
- }
-
- return val;
- },
-
- testChange = function testChange( e ) {
- var elem = e.target, data, val;
-
- if ( !rformElems.test( elem.nodeName ) || elem.readOnly ) {
- return;
- }
-
- data = jQuery.data( elem, "_change_data" );
- val = getVal(elem);
-
- // the current data will be also retrieved by beforeactivate
- if ( e.type !== "focusout" || elem.type !== "radio" ) {
- jQuery.data( elem, "_change_data", val );
- }
-
- if ( data === undefined || val === data ) {
- return;
- }
-
- if ( data != null || val ) {
- e.type = "change";
- e.liveFired = undefined;
- return jQuery.event.trigger( e, arguments[1], elem );
- }
- };
-
- jQuery.event.special.change = {
- filters: {
- focusout: testChange,
-
- beforedeactivate: testChange,
-
- click: function( e ) {
- var elem = e.target, type = elem.type;
-
- if ( type === "radio" || type === "checkbox" || elem.nodeName.toLowerCase() === "select" ) {
- return testChange.call( this, e );
- }
- },
-
- // Change has to be called before submit
- // Keydown will be called before keypress, which is used in submit-event delegation
- keydown: function( e ) {
- var elem = e.target, type = elem.type;
-
- if ( (e.keyCode === 13 && elem.nodeName.toLowerCase() !== "textarea") ||
- (e.keyCode === 32 && (type === "checkbox" || type === "radio")) ||
- type === "select-multiple" ) {
- return testChange.call( this, e );
- }
- },
-
- // Beforeactivate happens also before the previous element is blurred
- // with this event you can't trigger a change event, but you can store
- // information
- beforeactivate: function( e ) {
- var elem = e.target;
- jQuery.data( elem, "_change_data", getVal(elem) );
- }
- },
-
- setup: function( data, namespaces ) {
- if ( this.type === "file" ) {
- return false;
- }
-
- for ( var type in changeFilters ) {
- jQuery.event.add( this, type + ".specialChange", changeFilters[type] );
- }
-
- return rformElems.test( this.nodeName );
- },
-
- teardown: function( namespaces ) {
- jQuery.event.remove( this, ".specialChange" );
-
- return rformElems.test( this.nodeName );
- }
- };
-
- changeFilters = jQuery.event.special.change.filters;
-
- // Handle when the input is .focus()'d
- changeFilters.focus = changeFilters.beforeactivate;
-}
-
-function trigger( type, elem, args ) {
- args[0].type = type;
- return jQuery.event.handle.apply( elem, args );
-}
-
-// Create "bubbling" focus and blur events
-if ( document.addEventListener ) {
- jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) {
- jQuery.event.special[ fix ] = {
- setup: function() {
- if ( focusCounts[fix]++ === 0 ) {
- document.addEventListener( orig, handler, true );
- }
- },
- teardown: function() {
- if ( --focusCounts[fix] === 0 ) {
- document.removeEventListener( orig, handler, true );
- }
- }
- };
-
- function handler( e ) {
- e = jQuery.event.fix( e );
- e.type = fix;
- return jQuery.event.trigger( e, null, e.target );
- }
- });
-}
-
-jQuery.each(["bind", "one"], function( i, name ) {
- jQuery.fn[ name ] = function( type, data, fn ) {
- // Handle object literals
- if ( typeof type === "object" ) {
- for ( var key in type ) {
- this[ name ](key, data, type[key], fn);
- }
- return this;
- }
-
- if ( jQuery.isFunction( data ) || data === false ) {
- fn = data;
- data = undefined;
- }
-
- var handler = name === "one" ? jQuery.proxy( fn, function( event ) {
- jQuery( this ).unbind( event, handler );
- return fn.apply( this, arguments );
- }) : fn;
-
- if ( type === "unload" && name !== "one" ) {
- this.one( type, data, fn );
-
- } else {
- for ( var i = 0, l = this.length; i < l; i++ ) {
- jQuery.event.add( this[i], type, handler, data );
- }
- }
-
- return this;
- };
-});
-
-jQuery.fn.extend({
- unbind: function( type, fn ) {
- // Handle object literals
- if ( typeof type === "object" && !type.preventDefault ) {
- for ( var key in type ) {
- this.unbind(key, type[key]);
- }
-
- } else {
- for ( var i = 0, l = this.length; i < l; i++ ) {
- jQuery.event.remove( this[i], type, fn );
- }
- }
-
- return this;
- },
-
- delegate: function( selector, types, data, fn ) {
- return this.live( types, data, fn, selector );
- },
-
- undelegate: function( selector, types, fn ) {
- if ( arguments.length === 0 ) {
- return this.unbind( "live" );
-
- } else {
- return this.die( types, null, fn, selector );
- }
- },
-
- trigger: function( type, data ) {
- return this.each(function() {
- jQuery.event.trigger( type, data, this );
- });
- },
-
- triggerHandler: function( type, data ) {
- if ( this[0] ) {
- var event = jQuery.Event( type );
- event.preventDefault();
- event.stopPropagation();
- jQuery.event.trigger( event, data, this[0] );
- return event.result;
- }
- },
-
- toggle: function( fn ) {
- // Save reference to arguments for access in closure
- var args = arguments,
- i = 1;
-
- // link all the functions, so any of them can unbind this click handler
- while ( i < args.length ) {
- jQuery.proxy( fn, args[ i++ ] );
- }
-
- return this.click( jQuery.proxy( fn, function( event ) {
- // Figure out which function to execute
- var lastToggle = ( jQuery.data( this, "lastToggle" + fn.guid ) || 0 ) % i;
- jQuery.data( this, "lastToggle" + fn.guid, lastToggle + 1 );
-
- // Make sure that clicks stop
- event.preventDefault();
-
- // and execute the function
- return args[ lastToggle ].apply( this, arguments ) || false;
- }));
- },
-
- hover: function( fnOver, fnOut ) {
- return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
- }
-});
-
-var liveMap = {
- focus: "focusin",
- blur: "focusout",
- mouseenter: "mouseover",
- mouseleave: "mouseout"
-};
-
-jQuery.each(["live", "die"], function( i, name ) {
- jQuery.fn[ name ] = function( types, data, fn, origSelector /* Internal Use Only */ ) {
- var type, i = 0, match, namespaces, preType,
- selector = origSelector || this.selector,
- context = origSelector ? this : jQuery( this.context );
-
- if ( typeof types === "object" && !types.preventDefault ) {
- for ( var key in types ) {
- context[ name ]( key, data, types[key], selector );
- }
-
- return this;
- }
-
- if ( jQuery.isFunction( data ) ) {
- fn = data;
- data = undefined;
- }
-
- types = (types || "").split(" ");
-
- while ( (type = types[ i++ ]) != null ) {
- match = rnamespaces.exec( type );
- namespaces = "";
-
- if ( match ) {
- namespaces = match[0];
- type = type.replace( rnamespaces, "" );
- }
-
- if ( type === "hover" ) {
- types.push( "mouseenter" + namespaces, "mouseleave" + namespaces );
- continue;
- }
-
- preType = type;
-
- if ( type === "focus" || type === "blur" ) {
- types.push( liveMap[ type ] + namespaces );
- type = type + namespaces;
-
- } else {
- type = (liveMap[ type ] || type) + namespaces;
- }
-
- if ( name === "live" ) {
- // bind live handler
- for ( var j = 0, l = context.length; j < l; j++ ) {
- jQuery.event.add( context[j], "live." + liveConvert( type, selector ),
- { data: data, selector: selector, handler: fn, origType: type, origHandler: fn, preType: preType } );
- }
-
- } else {
- // unbind live handler
- context.unbind( "live." + liveConvert( type, selector ), fn );
- }
- }
-
- return this;
- };
-});
-
-function liveHandler( event ) {
- var stop, maxLevel, related, match, handleObj, elem, j, i, l, data, close, namespace, ret,
- elems = [],
- selectors = [],
- events = jQuery.data( this, this.nodeType ? "events" : "__events__" );
-
- if ( typeof events === "function" ) {
- events = events.events;
- }
-
- // Make sure we avoid non-left-click bubbling in Firefox (#3861)
- if ( event.liveFired === this || !events || !events.live || event.button && event.type === "click" ) {
- return;
- }
-
- if ( event.namespace ) {
- namespace = new RegExp("(^|\\.)" + event.namespace.split(".").join("\\.(?:.*\\.)?") + "(\\.|$)");
- }
-
- event.liveFired = this;
-
- var live = events.live.slice(0);
-
- for ( j = 0; j < live.length; j++ ) {
- handleObj = live[j];
-
- if ( handleObj.origType.replace( rnamespaces, "" ) === event.type ) {
- selectors.push( handleObj.selector );
-
- } else {
- live.splice( j--, 1 );
- }
- }
-
- match = jQuery( event.target ).closest( selectors, event.currentTarget );
-
- for ( i = 0, l = match.length; i < l; i++ ) {
- close = match[i];
-
- for ( j = 0; j < live.length; j++ ) {
- handleObj = live[j];
-
- if ( close.selector === handleObj.selector && (!namespace || namespace.test( handleObj.namespace )) ) {
- elem = close.elem;
- related = null;
-
- // Those two events require additional checking
- if ( handleObj.preType === "mouseenter" || handleObj.preType === "mouseleave" ) {
- event.type = handleObj.preType;
- related = jQuery( event.relatedTarget ).closest( handleObj.selector )[0];
- }
-
- if ( !related || related !== elem ) {
- elems.push({ elem: elem, handleObj: handleObj, level: close.level });
- }
- }
- }
- }
-
- for ( i = 0, l = elems.length; i < l; i++ ) {
- match = elems[i];
-
- if ( maxLevel && match.level > maxLevel ) {
- break;
- }
-
- event.currentTarget = match.elem;
- event.data = match.handleObj.data;
- event.handleObj = match.handleObj;
-
- ret = match.handleObj.origHandler.apply( match.elem, arguments );
-
- if ( ret === false || event.isPropagationStopped() ) {
- maxLevel = match.level;
-
- if ( ret === false ) {
- stop = false;
- }
- if ( event.isImmediatePropagationStopped() ) {
- break;
- }
- }
- }
-
- return stop;
-}
-
-function liveConvert( type, selector ) {
- return (type && type !== "*" ? type + "." : "") + selector.replace(rperiod, "`").replace(rspace, "&");
-}
-
-jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " +
- "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
- "change select submit keydown keypress keyup error").split(" "), function( i, name ) {
-
- // Handle event binding
- jQuery.fn[ name ] = function( data, fn ) {
- if ( fn == null ) {
- fn = data;
- data = null;
- }
-
- return arguments.length > 0 ?
- this.bind( name, data, fn ) :
- this.trigger( name );
- };
-
- if ( jQuery.attrFn ) {
- jQuery.attrFn[ name ] = true;
- }
-});
-
-// Prevent memory leaks in IE
-// Window isn't included so as not to unbind existing unload events
-// More info:
-// - http://isaacschlueter.com/2006/10/msie-memory-leaks/
-if ( window.attachEvent && !window.addEventListener ) {
- jQuery(window).bind("unload", function() {
- for ( var id in jQuery.cache ) {
- if ( jQuery.cache[ id ].handle ) {
- // Try/Catch is to handle iframes being unloaded, see #4280
- try {
- jQuery.event.remove( jQuery.cache[ id ].handle.elem );
- } catch(e) {}
- }
- }
- });
-}
-
-
-/*!
- * Sizzle CSS Selector Engine - v1.0
- * Copyright 2009, The Dojo Foundation
- * Released under the MIT, BSD, and GPL Licenses.
- * More information: http://sizzlejs.com/
- */
-(function(){
-
-var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,
- done = 0,
- toString = Object.prototype.toString,
- hasDuplicate = false,
- baseHasDuplicate = true;
-
-// Here we check if the JavaScript engine is using some sort of
-// optimization where it does not always call our comparision
-// function. If that is the case, discard the hasDuplicate value.
-// Thus far that includes Google Chrome.
-[0, 0].sort(function() {
- baseHasDuplicate = false;
- return 0;
-});
-
-var Sizzle = function( selector, context, results, seed ) {
- results = results || [];
- context = context || document;
-
- var origContext = context;
-
- if ( context.nodeType !== 1 && context.nodeType !== 9 ) {
- return [];
- }
-
- if ( !selector || typeof selector !== "string" ) {
- return results;
- }
-
- var m, set, checkSet, extra, ret, cur, pop, i,
- prune = true,
- contextXML = Sizzle.isXML( context ),
- parts = [],
- soFar = selector;
-
- // Reset the position of the chunker regexp (start from head)
- do {
- chunker.exec( "" );
- m = chunker.exec( soFar );
-
- if ( m ) {
- soFar = m[3];
-
- parts.push( m[1] );
-
- if ( m[2] ) {
- extra = m[3];
- break;
- }
- }
- } while ( m );
-
- if ( parts.length > 1 && origPOS.exec( selector ) ) {
-
- if ( parts.length === 2 && Expr.relative[ parts[0] ] ) {
- set = posProcess( parts[0] + parts[1], context );
-
- } else {
- set = Expr.relative[ parts[0] ] ?
- [ context ] :
- Sizzle( parts.shift(), context );
-
- while ( parts.length ) {
- selector = parts.shift();
-
- if ( Expr.relative[ selector ] ) {
- selector += parts.shift();
- }
-
- set = posProcess( selector, set );
- }
- }
-
- } else {
- // Take a shortcut and set the context if the root selector is an ID
- // (but not if it'll be faster if the inner selector is an ID)
- if ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML &&
- Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) {
-
- ret = Sizzle.find( parts.shift(), context, contextXML );
- context = ret.expr ?
- Sizzle.filter( ret.expr, ret.set )[0] :
- ret.set[0];
- }
-
- if ( context ) {
- ret = seed ?
- { expr: parts.pop(), set: makeArray(seed) } :
- Sizzle.find( parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML );
-
- set = ret.expr ?
- Sizzle.filter( ret.expr, ret.set ) :
- ret.set;
-
- if ( parts.length > 0 ) {
- checkSet = makeArray( set );
-
- } else {
- prune = false;
- }
-
- while ( parts.length ) {
- cur = parts.pop();
- pop = cur;
-
- if ( !Expr.relative[ cur ] ) {
- cur = "";
- } else {
- pop = parts.pop();
- }
-
- if ( pop == null ) {
- pop = context;
- }
-
- Expr.relative[ cur ]( checkSet, pop, contextXML );
- }
-
- } else {
- checkSet = parts = [];
- }
- }
-
- if ( !checkSet ) {
- checkSet = set;
- }
-
- if ( !checkSet ) {
- Sizzle.error( cur || selector );
- }
-
- if ( toString.call(checkSet) === "[object Array]" ) {
- if ( !prune ) {
- results.push.apply( results, checkSet );
-
- } else if ( context && context.nodeType === 1 ) {
- for ( i = 0; checkSet[i] != null; i++ ) {
- if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && Sizzle.contains(context, checkSet[i])) ) {
- results.push( set[i] );
- }
- }
-
- } else {
- for ( i = 0; checkSet[i] != null; i++ ) {
- if ( checkSet[i] && checkSet[i].nodeType === 1 ) {
- results.push( set[i] );
- }
- }
- }
-
- } else {
- makeArray( checkSet, results );
- }
-
- if ( extra ) {
- Sizzle( extra, origContext, results, seed );
- Sizzle.uniqueSort( results );
- }
-
- return results;
-};
-
-Sizzle.uniqueSort = function( results ) {
- if ( sortOrder ) {
- hasDuplicate = baseHasDuplicate;
- results.sort( sortOrder );
-
- if ( hasDuplicate ) {
- for ( var i = 1; i < results.length; i++ ) {
- if ( results[i] === results[ i - 1 ] ) {
- results.splice( i--, 1 );
- }
- }
- }
- }
-
- return results;
-};
-
-Sizzle.matches = function( expr, set ) {
- return Sizzle( expr, null, null, set );
-};
-
-Sizzle.matchesSelector = function( node, expr ) {
- return Sizzle( expr, null, null, [node] ).length > 0;
-};
-
-Sizzle.find = function( expr, context, isXML ) {
- var set;
-
- if ( !expr ) {
- return [];
- }
-
- for ( var i = 0, l = Expr.order.length; i < l; i++ ) {
- var match,
- type = Expr.order[i];
-
- if ( (match = Expr.leftMatch[ type ].exec( expr )) ) {
- var left = match[1];
- match.splice( 1, 1 );
-
- if ( left.substr( left.length - 1 ) !== "\\" ) {
- match[1] = (match[1] || "").replace(/\\/g, "");
- set = Expr.find[ type ]( match, context, isXML );
-
- if ( set != null ) {
- expr = expr.replace( Expr.match[ type ], "" );
- break;
- }
- }
- }
- }
-
- if ( !set ) {
- set = context.getElementsByTagName( "*" );
- }
-
- return { set: set, expr: expr };
-};
-
-Sizzle.filter = function( expr, set, inplace, not ) {
- var match, anyFound,
- old = expr,
- result = [],
- curLoop = set,
- isXMLFilter = set && set[0] && Sizzle.isXML( set[0] );
-
- while ( expr && set.length ) {
- for ( var type in Expr.filter ) {
- if ( (match = Expr.leftMatch[ type ].exec( expr )) != null && match[2] ) {
- var found, item,
- filter = Expr.filter[ type ],
- left = match[1];
-
- anyFound = false;
-
- match.splice(1,1);
-
- if ( left.substr( left.length - 1 ) === "\\" ) {
- continue;
- }
-
- if ( curLoop === result ) {
- result = [];
- }
-
- if ( Expr.preFilter[ type ] ) {
- match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter );
-
- if ( !match ) {
- anyFound = found = true;
-
- } else if ( match === true ) {
- continue;
- }
- }
-
- if ( match ) {
- for ( var i = 0; (item = curLoop[i]) != null; i++ ) {
- if ( item ) {
- found = filter( item, match, i, curLoop );
- var pass = not ^ !!found;
-
- if ( inplace && found != null ) {
- if ( pass ) {
- anyFound = true;
-
- } else {
- curLoop[i] = false;
- }
-
- } else if ( pass ) {
- result.push( item );
- anyFound = true;
- }
- }
- }
- }
-
- if ( found !== undefined ) {
- if ( !inplace ) {
- curLoop = result;
- }
-
- expr = expr.replace( Expr.match[ type ], "" );
-
- if ( !anyFound ) {
- return [];
- }
-
- break;
- }
- }
- }
-
- // Improper expression
- if ( expr === old ) {
- if ( anyFound == null ) {
- Sizzle.error( expr );
-
- } else {
- break;
- }
- }
-
- old = expr;
- }
-
- return curLoop;
-};
-
-Sizzle.error = function( msg ) {
- throw "Syntax error, unrecognized expression: " + msg;
-};
-
-var Expr = Sizzle.selectors = {
- order: [ "ID", "NAME", "TAG" ],
-
- match: {
- ID: /#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,
- CLASS: /\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,
- NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/,
- ATTR: /\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,
- TAG: /^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/,
- CHILD: /:(only|nth|last|first)-child(?:\((even|odd|[\dn+\-]*)\))?/,
- POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/,
- PSEUDO: /:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/
- },
-
- leftMatch: {},
-
- attrMap: {
- "class": "className",
- "for": "htmlFor"
- },
-
- attrHandle: {
- href: function( elem ) {
- return elem.getAttribute( "href" );
- }
- },
-
- relative: {
- "+": function(checkSet, part){
- var isPartStr = typeof part === "string",
- isTag = isPartStr && !/\W/.test( part ),
- isPartStrNotTag = isPartStr && !isTag;
-
- if ( isTag ) {
- part = part.toLowerCase();
- }
-
- for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) {
- if ( (elem = checkSet[i]) ) {
- while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {}
-
- checkSet[i] = isPartStrNotTag || elem && elem.nodeName.toLowerCase() === part ?
- elem || false :
- elem === part;
- }
- }
-
- if ( isPartStrNotTag ) {
- Sizzle.filter( part, checkSet, true );
- }
- },
-
- ">": function( checkSet, part ) {
- var elem,
- isPartStr = typeof part === "string",
- i = 0,
- l = checkSet.length;
-
- if ( isPartStr && !/\W/.test( part ) ) {
- part = part.toLowerCase();
-
- for ( ; i < l; i++ ) {
- elem = checkSet[i];
-
- if ( elem ) {
- var parent = elem.parentNode;
- checkSet[i] = parent.nodeName.toLowerCase() === part ? parent : false;
- }
- }
-
- } else {
- for ( ; i < l; i++ ) {
- elem = checkSet[i];
-
- if ( elem ) {
- checkSet[i] = isPartStr ?
- elem.parentNode :
- elem.parentNode === part;
- }
- }
-
- if ( isPartStr ) {
- Sizzle.filter( part, checkSet, true );
- }
- }
- },
-
- "": function(checkSet, part, isXML){
- var nodeCheck,
- doneName = done++,
- checkFn = dirCheck;
-
- if ( typeof part === "string" && !/\W/.test(part) ) {
- part = part.toLowerCase();
- nodeCheck = part;
- checkFn = dirNodeCheck;
- }
-
- checkFn( "parentNode", part, doneName, checkSet, nodeCheck, isXML );
- },
-
- "~": function( checkSet, part, isXML ) {
- var nodeCheck,
- doneName = done++,
- checkFn = dirCheck;
-
- if ( typeof part === "string" && !/\W/.test( part ) ) {
- part = part.toLowerCase();
- nodeCheck = part;
- checkFn = dirNodeCheck;
- }
-
- checkFn( "previousSibling", part, doneName, checkSet, nodeCheck, isXML );
- }
- },
-
- find: {
- ID: function( match, context, isXML ) {
- if ( typeof context.getElementById !== "undefined" && !isXML ) {
- var m = context.getElementById(match[1]);
- // Check parentNode to catch when Blackberry 4.6 returns
- // nodes that are no longer in the document #6963
- return m && m.parentNode ? [m] : [];
- }
- },
-
- NAME: function( match, context ) {
- if ( typeof context.getElementsByName !== "undefined" ) {
- var ret = [],
- results = context.getElementsByName( match[1] );
-
- for ( var i = 0, l = results.length; i < l; i++ ) {
- if ( results[i].getAttribute("name") === match[1] ) {
- ret.push( results[i] );
- }
- }
-
- return ret.length === 0 ? null : ret;
- }
- },
-
- TAG: function( match, context ) {
- return context.getElementsByTagName( match[1] );
- }
- },
- preFilter: {
- CLASS: function( match, curLoop, inplace, result, not, isXML ) {
- match = " " + match[1].replace(/\\/g, "") + " ";
-
- if ( isXML ) {
- return match;
- }
-
- for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) {
- if ( elem ) {
- if ( not ^ (elem.className && (" " + elem.className + " ").replace(/[\t\n]/g, " ").indexOf(match) >= 0) ) {
- if ( !inplace ) {
- result.push( elem );
- }
-
- } else if ( inplace ) {
- curLoop[i] = false;
- }
- }
- }
-
- return false;
- },
-
- ID: function( match ) {
- return match[1].replace(/\\/g, "");
- },
-
- TAG: function( match, curLoop ) {
- return match[1].toLowerCase();
- },
-
- CHILD: function( match ) {
- if ( match[1] === "nth" ) {
- // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6'
- var test = /(-?)(\d*)n((?:\+|-)?\d*)/.exec(
- match[2] === "even" && "2n" || match[2] === "odd" && "2n+1" ||
- !/\D/.test( match[2] ) && "0n+" + match[2] || match[2]);
-
- // calculate the numbers (first)n+(last) including if they are negative
- match[2] = (test[1] + (test[2] || 1)) - 0;
- match[3] = test[3] - 0;
- }
-
- // TODO: Move to normal caching system
- match[0] = done++;
-
- return match;
- },
-
- ATTR: function( match, curLoop, inplace, result, not, isXML ) {
- var name = match[1].replace(/\\/g, "");
-
- if ( !isXML && Expr.attrMap[name] ) {
- match[1] = Expr.attrMap[name];
- }
-
- if ( match[2] === "~=" ) {
- match[4] = " " + match[4] + " ";
- }
-
- return match;
- },
-
- PSEUDO: function( match, curLoop, inplace, result, not ) {
- if ( match[1] === "not" ) {
- // If we're dealing with a complex expression, or a simple one
- if ( ( chunker.exec(match[3]) || "" ).length > 1 || /^\w/.test(match[3]) ) {
- match[3] = Sizzle(match[3], null, null, curLoop);
-
- } else {
- var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not);
-
- if ( !inplace ) {
- result.push.apply( result, ret );
- }
-
- return false;
- }
-
- } else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) {
- return true;
- }
-
- return match;
- },
-
- POS: function( match ) {
- match.unshift( true );
-
- return match;
- }
- },
-
- filters: {
- enabled: function( elem ) {
- return elem.disabled === false && elem.type !== "hidden";
- },
-
- disabled: function( elem ) {
- return elem.disabled === true;
- },
-
- checked: function( elem ) {
- return elem.checked === true;
- },
-
- selected: function( elem ) {
- // Accessing this property makes selected-by-default
- // options in Safari work properly
- elem.parentNode.selectedIndex;
-
- return elem.selected === true;
- },
-
- parent: function( elem ) {
- return !!elem.firstChild;
- },
-
- empty: function( elem ) {
- return !elem.firstChild;
- },
-
- has: function( elem, i, match ) {
- return !!Sizzle( match[3], elem ).length;
- },
-
- header: function( elem ) {
- return (/h\d/i).test( elem.nodeName );
- },
-
- text: function( elem ) {
- return "text" === elem.type;
- },
- radio: function( elem ) {
- return "radio" === elem.type;
- },
-
- checkbox: function( elem ) {
- return "checkbox" === elem.type;
- },
-
- file: function( elem ) {
- return "file" === elem.type;
- },
- password: function( elem ) {
- return "password" === elem.type;
- },
-
- submit: function( elem ) {
- return "submit" === elem.type;
- },
-
- image: function( elem ) {
- return "image" === elem.type;
- },
-
- reset: function( elem ) {
- return "reset" === elem.type;
- },
-
- button: function( elem ) {
- return "button" === elem.type || elem.nodeName.toLowerCase() === "button";
- },
-
- input: function( elem ) {
- return (/input|select|textarea|button/i).test( elem.nodeName );
- }
- },
- setFilters: {
- first: function( elem, i ) {
- return i === 0;
- },
-
- last: function( elem, i, match, array ) {
- return i === array.length - 1;
- },
-
- even: function( elem, i ) {
- return i % 2 === 0;
- },
-
- odd: function( elem, i ) {
- return i % 2 === 1;
- },
-
- lt: function( elem, i, match ) {
- return i < match[3] - 0;
- },
-
- gt: function( elem, i, match ) {
- return i > match[3] - 0;
- },
-
- nth: function( elem, i, match ) {
- return match[3] - 0 === i;
- },
-
- eq: function( elem, i, match ) {
- return match[3] - 0 === i;
- }
- },
- filter: {
- PSEUDO: function( elem, match, i, array ) {
- var name = match[1],
- filter = Expr.filters[ name ];
-
- if ( filter ) {
- return filter( elem, i, match, array );
-
- } else if ( name === "contains" ) {
- return (elem.textContent || elem.innerText || Sizzle.getText([ elem ]) || "").indexOf(match[3]) >= 0;
-
- } else if ( name === "not" ) {
- var not = match[3];
-
- for ( var j = 0, l = not.length; j < l; j++ ) {
- if ( not[j] === elem ) {
- return false;
- }
- }
-
- return true;
-
- } else {
- Sizzle.error( "Syntax error, unrecognized expression: " + name );
- }
- },
-
- CHILD: function( elem, match ) {
- var type = match[1],
- node = elem;
-
- switch ( type ) {
- case "only":
- case "first":
- while ( (node = node.previousSibling) ) {
- if ( node.nodeType === 1 ) {
- return false;
- }
- }
-
- if ( type === "first" ) {
- return true;
- }
-
- node = elem;
-
- case "last":
- while ( (node = node.nextSibling) ) {
- if ( node.nodeType === 1 ) {
- return false;
- }
- }
-
- return true;
-
- case "nth":
- var first = match[2],
- last = match[3];
-
- if ( first === 1 && last === 0 ) {
- return true;
- }
-
- var doneName = match[0],
- parent = elem.parentNode;
-
- if ( parent && (parent.sizcache !== doneName || !elem.nodeIndex) ) {
- var count = 0;
-
- for ( node = parent.firstChild; node; node = node.nextSibling ) {
- if ( node.nodeType === 1 ) {
- node.nodeIndex = ++count;
- }
- }
-
- parent.sizcache = doneName;
- }
-
- var diff = elem.nodeIndex - last;
-
- if ( first === 0 ) {
- return diff === 0;
-
- } else {
- return ( diff % first === 0 && diff / first >= 0 );
- }
- }
- },
-
- ID: function( elem, match ) {
- return elem.nodeType === 1 && elem.getAttribute("id") === match;
- },
-
- TAG: function( elem, match ) {
- return (match === "*" && elem.nodeType === 1) || elem.nodeName.toLowerCase() === match;
- },
-
- CLASS: function( elem, match ) {
- return (" " + (elem.className || elem.getAttribute("class")) + " ")
- .indexOf( match ) > -1;
- },
-
- ATTR: function( elem, match ) {
- var name = match[1],
- result = Expr.attrHandle[ name ] ?
- Expr.attrHandle[ name ]( elem ) :
- elem[ name ] != null ?
- elem[ name ] :
- elem.getAttribute( name ),
- value = result + "",
- type = match[2],
- check = match[4];
-
- return result == null ?
- type === "!=" :
- type === "=" ?
- value === check :
- type === "*=" ?
- value.indexOf(check) >= 0 :
- type === "~=" ?
- (" " + value + " ").indexOf(check) >= 0 :
- !check ?
- value && result !== false :
- type === "!=" ?
- value !== check :
- type === "^=" ?
- value.indexOf(check) === 0 :
- type === "$=" ?
- value.substr(value.length - check.length) === check :
- type === "|=" ?
- value === check || value.substr(0, check.length + 1) === check + "-" :
- false;
- },
-
- POS: function( elem, match, i, array ) {
- var name = match[2],
- filter = Expr.setFilters[ name ];
-
- if ( filter ) {
- return filter( elem, i, match, array );
- }
- }
- }
-};
-
-var origPOS = Expr.match.POS,
- fescape = function(all, num){
- return "\\" + (num - 0 + 1);
- };
-
-for ( var type in Expr.match ) {
- Expr.match[ type ] = new RegExp( Expr.match[ type ].source + (/(?![^\[]*\])(?![^\(]*\))/.source) );
- Expr.leftMatch[ type ] = new RegExp( /(^(?:.|\r|\n)*?)/.source + Expr.match[ type ].source.replace(/\\(\d+)/g, fescape) );
-}
-
-var makeArray = function( array, results ) {
- array = Array.prototype.slice.call( array, 0 );
-
- if ( results ) {
- results.push.apply( results, array );
- return results;
- }
-
- return array;
-};
-
-// Perform a simple check to determine if the browser is capable of
-// converting a NodeList to an array using builtin methods.
-// Also verifies that the returned array holds DOM nodes
-// (which is not the case in the Blackberry browser)
-try {
- Array.prototype.slice.call( document.documentElement.childNodes, 0 )[0].nodeType;
-
-// Provide a fallback method if it does not work
-} catch( e ) {
- makeArray = function( array, results ) {
- var i = 0,
- ret = results || [];
-
- if ( toString.call(array) === "[object Array]" ) {
- Array.prototype.push.apply( ret, array );
-
- } else {
- if ( typeof array.length === "number" ) {
- for ( var l = array.length; i < l; i++ ) {
- ret.push( array[i] );
- }
-
- } else {
- for ( ; array[i]; i++ ) {
- ret.push( array[i] );
- }
- }
- }
-
- return ret;
- };
-}
-
-var sortOrder, siblingCheck;
-
-if ( document.documentElement.compareDocumentPosition ) {
- sortOrder = function( a, b ) {
- if ( a === b ) {
- hasDuplicate = true;
- return 0;
- }
-
- if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) {
- return a.compareDocumentPosition ? -1 : 1;
- }
-
- return a.compareDocumentPosition(b) & 4 ? -1 : 1;
- };
-
-} else {
- sortOrder = function( a, b ) {
- var al, bl,
- ap = [],
- bp = [],
- aup = a.parentNode,
- bup = b.parentNode,
- cur = aup;
-
- // The nodes are identical, we can exit early
- if ( a === b ) {
- hasDuplicate = true;
- return 0;
-
- // If the nodes are siblings (or identical) we can do a quick check
- } else if ( aup === bup ) {
- return siblingCheck( a, b );
-
- // If no parents were found then the nodes are disconnected
- } else if ( !aup ) {
- return -1;
-
- } else if ( !bup ) {
- return 1;
- }
-
- // Otherwise they're somewhere else in the tree so we need
- // to build up a full list of the parentNodes for comparison
- while ( cur ) {
- ap.unshift( cur );
- cur = cur.parentNode;
- }
-
- cur = bup;
-
- while ( cur ) {
- bp.unshift( cur );
- cur = cur.parentNode;
- }
-
- al = ap.length;
- bl = bp.length;
-
- // Start walking down the tree looking for a discrepancy
- for ( var i = 0; i < al && i < bl; i++ ) {
- if ( ap[i] !== bp[i] ) {
- return siblingCheck( ap[i], bp[i] );
- }
- }
-
- // We ended someplace up the tree so do a sibling check
- return i === al ?
- siblingCheck( a, bp[i], -1 ) :
- siblingCheck( ap[i], b, 1 );
- };
-
- siblingCheck = function( a, b, ret ) {
- if ( a === b ) {
- return ret;
- }
-
- var cur = a.nextSibling;
-
- while ( cur ) {
- if ( cur === b ) {
- return -1;
- }
-
- cur = cur.nextSibling;
- }
-
- return 1;
- };
-}
-
-// Utility function for retreiving the text value of an array of DOM nodes
-Sizzle.getText = function( elems ) {
- var ret = "", elem;
-
- for ( var i = 0; elems[i]; i++ ) {
- elem = elems[i];
-
- // Get the text from text nodes and CDATA nodes
- if ( elem.nodeType === 3 || elem.nodeType === 4 ) {
- ret += elem.nodeValue;
-
- // Traverse everything else, except comment nodes
- } else if ( elem.nodeType !== 8 ) {
- ret += Sizzle.getText( elem.childNodes );
- }
- }
-
- return ret;
-};
-
-// Check to see if the browser returns elements by name when
-// querying by getElementById (and provide a workaround)
-(function(){
- // We're going to inject a fake input element with a specified name
- var form = document.createElement("div"),
- id = "script" + (new Date()).getTime(),
- root = document.documentElement;
-
- form.innerHTML = "<a name='" + id + "'/>";
-
- // Inject it into the root element, check its status, and remove it quickly
- root.insertBefore( form, root.firstChild );
-
- // The workaround has to do additional checks after a getElementById
- // Which slows things down for other browsers (hence the branching)
- if ( document.getElementById( id ) ) {
- Expr.find.ID = function( match, context, isXML ) {
- if ( typeof context.getElementById !== "undefined" && !isXML ) {
- var m = context.getElementById(match[1]);
-
- return m ?
- m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ?
- [m] :
- undefined :
- [];
- }
- };
-
- Expr.filter.ID = function( elem, match ) {
- var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id");
-
- return elem.nodeType === 1 && node && node.nodeValue === match;
- };
- }
-
- root.removeChild( form );
-
- // release memory in IE
- root = form = null;
-})();
-
-(function(){
- // Check to see if the browser returns only elements
- // when doing getElementsByTagName("*")
-
- // Create a fake element
- var div = document.createElement("div");
- div.appendChild( document.createComment("") );
-
- // Make sure no comments are found
- if ( div.getElementsByTagName("*").length > 0 ) {
- Expr.find.TAG = function( match, context ) {
- var results = context.getElementsByTagName( match[1] );
-
- // Filter out possible comments
- if ( match[1] === "*" ) {
- var tmp = [];
-
- for ( var i = 0; results[i]; i++ ) {
- if ( results[i].nodeType === 1 ) {
- tmp.push( results[i] );
- }
- }
-
- results = tmp;
- }
-
- return results;
- };
- }
-
- // Check to see if an attribute returns normalized href attributes
- div.innerHTML = "<a href='#'></a>";
-
- if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" &&
- div.firstChild.getAttribute("href") !== "#" ) {
-
- Expr.attrHandle.href = function( elem ) {
- return elem.getAttribute( "href", 2 );
- };
- }
-
- // release memory in IE
- div = null;
-})();
-
-if ( document.querySelectorAll ) {
- (function(){
- var oldSizzle = Sizzle,
- div = document.createElement("div"),
- id = "__sizzle__";
-
- div.innerHTML = "<p class='TEST'></p>";
-
- // Safari can't handle uppercase or unicode characters when
- // in quirks mode.
- if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) {
- return;
- }
-
- Sizzle = function( query, context, extra, seed ) {
- context = context || document;
-
- // Make sure that attribute selectors are quoted
- query = query.replace(/\=\s*([^'"\]]*)\s*\]/g, "='$1']");
-
- // Only use querySelectorAll on non-XML documents
- // (ID selectors don't work in non-HTML documents)
- if ( !seed && !Sizzle.isXML(context) ) {
- if ( context.nodeType === 9 ) {
- try {
- return makeArray( context.querySelectorAll(query), extra );
- } catch(qsaError) {}
-
- // qSA works strangely on Element-rooted queries
- // We can work around this by specifying an extra ID on the root
- // and working up from there (Thanks to Andrew Dupont for the technique)
- // IE 8 doesn't work on object elements
- } else if ( context.nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) {
- var old = context.getAttribute( "id" ),
- nid = old || id;
-
- if ( !old ) {
- context.setAttribute( "id", nid );
- }
-
- try {
- return makeArray( context.querySelectorAll( "#" + nid + " " + query ), extra );
-
- } catch(pseudoError) {
- } finally {
- if ( !old ) {
- context.removeAttribute( "id" );
- }
- }
- }
- }
-
- return oldSizzle(query, context, extra, seed);
- };
-
- for ( var prop in oldSizzle ) {
- Sizzle[ prop ] = oldSizzle[ prop ];
- }
-
- // release memory in IE
- div = null;
- })();
-}
-
-(function(){
- var html = document.documentElement,
- matches = html.matchesSelector || html.mozMatchesSelector || html.webkitMatchesSelector || html.msMatchesSelector,
- pseudoWorks = false;
-
- try {
- // This should fail with an exception
- // Gecko does not error, returns false instead
- matches.call( document.documentElement, "[test!='']:sizzle" );
-
- } catch( pseudoError ) {
- pseudoWorks = true;
- }
-
- if ( matches ) {
- Sizzle.matchesSelector = function( node, expr ) {
- // Make sure that attribute selectors are quoted
- expr = expr.replace(/\=\s*([^'"\]]*)\s*\]/g, "='$1']");
-
- if ( !Sizzle.isXML( node ) ) {
- try {
- if ( pseudoWorks || !Expr.match.PSEUDO.test( expr ) && !/!=/.test( expr ) ) {
- return matches.call( node, expr );
- }
- } catch(e) {}
- }
-
- return Sizzle(expr, null, null, [node]).length > 0;
- };
- }
-})();
-
-(function(){
- var div = document.createElement("div");
-
- div.innerHTML = "<div class='test e'></div><div class='test'></div>";
-
- // Opera can't find a second classname (in 9.6)
- // Also, make sure that getElementsByClassName actually exists
- if ( !div.getElementsByClassName || div.getElementsByClassName("e").length === 0 ) {
- return;
- }
-
- // Safari caches class attributes, doesn't catch changes (in 3.2)
- div.lastChild.className = "e";
-
- if ( div.getElementsByClassName("e").length === 1 ) {
- return;
- }
-
- Expr.order.splice(1, 0, "CLASS");
- Expr.find.CLASS = function( match, context, isXML ) {
- if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) {
- return context.getElementsByClassName(match[1]);
- }
- };
-
- // release memory in IE
- div = null;
-})();
-
-function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
- for ( var i = 0, l = checkSet.length; i < l; i++ ) {
- var elem = checkSet[i];
-
- if ( elem ) {
- var match = false;
-
- elem = elem[dir];
-
- while ( elem ) {
- if ( elem.sizcache === doneName ) {
- match = checkSet[elem.sizset];
- break;
- }
-
- if ( elem.nodeType === 1 && !isXML ){
- elem.sizcache = doneName;
- elem.sizset = i;
- }
-
- if ( elem.nodeName.toLowerCase() === cur ) {
- match = elem;
- break;
- }
-
- elem = elem[dir];
- }
-
- checkSet[i] = match;
- }
- }
-}
-
-function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
- for ( var i = 0, l = checkSet.length; i < l; i++ ) {
- var elem = checkSet[i];
-
- if ( elem ) {
- var match = false;
-
- elem = elem[dir];
-
- while ( elem ) {
- if ( elem.sizcache === doneName ) {
- match = checkSet[elem.sizset];
- break;
- }
-
- if ( elem.nodeType === 1 ) {
- if ( !isXML ) {
- elem.sizcache = doneName;
- elem.sizset = i;
- }
-
- if ( typeof cur !== "string" ) {
- if ( elem === cur ) {
- match = true;
- break;
- }
-
- } else if ( Sizzle.filter( cur, [elem] ).length > 0 ) {
- match = elem;
- break;
- }
- }
-
- elem = elem[dir];
- }
-
- checkSet[i] = match;
- }
- }
-}
-
-if ( document.documentElement.contains ) {
- Sizzle.contains = function( a, b ) {
- return a !== b && (a.contains ? a.contains(b) : true);
- };
-
-} else if ( document.documentElement.compareDocumentPosition ) {
- Sizzle.contains = function( a, b ) {
- return !!(a.compareDocumentPosition(b) & 16);
- };
-
-} else {
- Sizzle.contains = function() {
- return false;
- };
-}
-
-Sizzle.isXML = function( elem ) {
- // documentElement is verified for cases where it doesn't yet exist
- // (such as loading iframes in IE - #4833)
- var documentElement = (elem ? elem.ownerDocument || elem : 0).documentElement;
-
- return documentElement ? documentElement.nodeName !== "HTML" : false;
-};
-
-var posProcess = function( selector, context ) {
- var match,
- tmpSet = [],
- later = "",
- root = context.nodeType ? [context] : context;
-
- // Position selectors must be done after the filter
- // And so must :not(positional) so we move all PSEUDOs to the end
- while ( (match = Expr.match.PSEUDO.exec( selector )) ) {
- later += match[0];
- selector = selector.replace( Expr.match.PSEUDO, "" );
- }
-
- selector = Expr.relative[selector] ? selector + "*" : selector;
-
- for ( var i = 0, l = root.length; i < l; i++ ) {
- Sizzle( selector, root[i], tmpSet );
- }
-
- return Sizzle.filter( later, tmpSet );
-};
-
-// EXPOSE
-jQuery.find = Sizzle;
-jQuery.expr = Sizzle.selectors;
-jQuery.expr[":"] = jQuery.expr.filters;
-jQuery.unique = Sizzle.uniqueSort;
-jQuery.text = Sizzle.getText;
-jQuery.isXMLDoc = Sizzle.isXML;
-jQuery.contains = Sizzle.contains;
-
-
-})();
-
-
-var runtil = /Until$/,
- rparentsprev = /^(?:parents|prevUntil|prevAll)/,
- // Note: This RegExp should be improved, or likely pulled from Sizzle
- rmultiselector = /,/,
- isSimple = /^.[^:#\[\.,]*$/,
- slice = Array.prototype.slice,
- POS = jQuery.expr.match.POS;
-
-jQuery.fn.extend({
- find: function( selector ) {
- var ret = this.pushStack( "", "find", selector ),
- length = 0;
-
- for ( var i = 0, l = this.length; i < l; i++ ) {
- length = ret.length;
- jQuery.find( selector, this[i], ret );
-
- if ( i > 0 ) {
- // Make sure that the results are unique
- for ( var n = length; n < ret.length; n++ ) {
- for ( var r = 0; r < length; r++ ) {
- if ( ret[r] === ret[n] ) {
- ret.splice(n--, 1);
- break;
- }
- }
- }
- }
- }
-
- return ret;
- },
-
- has: function( target ) {
- var targets = jQuery( target );
- return this.filter(function() {
- for ( var i = 0, l = targets.length; i < l; i++ ) {
- if ( jQuery.contains( this, targets[i] ) ) {
- return true;
- }
- }
- });
- },
-
- not: function( selector ) {
- return this.pushStack( winnow(this, selector, false), "not", selector);
- },
-
- filter: function( selector ) {
- return this.pushStack( winnow(this, selector, true), "filter", selector );
- },
-
- is: function( selector ) {
- return !!selector && jQuery.filter( selector, this ).length > 0;
- },
-
- closest: function( selectors, context ) {
- var ret = [], i, l, cur = this[0];
-
- if ( jQuery.isArray( selectors ) ) {
- var match, selector,
- matches = {},
- level = 1;
-
- if ( cur && selectors.length ) {
- for ( i = 0, l = selectors.length; i < l; i++ ) {
- selector = selectors[i];
-
- if ( !matches[selector] ) {
- matches[selector] = jQuery.expr.match.POS.test( selector ) ?
- jQuery( selector, context || this.context ) :
- selector;
- }
- }
-
- while ( cur && cur.ownerDocument && cur !== context ) {
- for ( selector in matches ) {
- match = matches[selector];
-
- if ( match.jquery ? match.index(cur) > -1 : jQuery(cur).is(match) ) {
- ret.push({ selector: selector, elem: cur, level: level });
- }
- }
-
- cur = cur.parentNode;
- level++;
- }
- }
-
- return ret;
- }
-
- var pos = POS.test( selectors ) ?
- jQuery( selectors, context || this.context ) : null;
-
- for ( i = 0, l = this.length; i < l; i++ ) {
- cur = this[i];
-
- while ( cur ) {
- if ( pos ? pos.index(cur) > -1 : jQuery.find.matchesSelector(cur, selectors) ) {
- ret.push( cur );
- break;
-
- } else {
- cur = cur.parentNode;
- if ( !cur || !cur.ownerDocument || cur === context ) {
- break;
- }
- }
- }
- }
-
- ret = ret.length > 1 ? jQuery.unique(ret) : ret;
-
- return this.pushStack( ret, "closest", selectors );
- },
-
- // Determine the position of an element within
- // the matched set of elements
- index: function( elem ) {
- if ( !elem || typeof elem === "string" ) {
- return jQuery.inArray( this[0],
- // If it receives a string, the selector is used
- // If it receives nothing, the siblings are used
- elem ? jQuery( elem ) : this.parent().children() );
- }
- // Locate the position of the desired element
- return jQuery.inArray(
- // If it receives a jQuery object, the first element is used
- elem.jquery ? elem[0] : elem, this );
- },
-
- add: function( selector, context ) {
- var set = typeof selector === "string" ?
- jQuery( selector, context || this.context ) :
- jQuery.makeArray( selector ),
- all = jQuery.merge( this.get(), set );
-
- return this.pushStack( isDisconnected( set[0] ) || isDisconnected( all[0] ) ?
- all :
- jQuery.unique( all ) );
- },
-
- andSelf: function() {
- return this.add( this.prevObject );
- }
-});
-
-// A painfully simple check to see if an element is disconnected
-// from a document (should be improved, where feasible).
-function isDisconnected( node ) {
- return !node || !node.parentNode || node.parentNode.nodeType === 11;
-}
-
-jQuery.each({
- parent: function( elem ) {
- var parent = elem.parentNode;
- return parent && parent.nodeType !== 11 ? parent : null;
- },
- parents: function( elem ) {
- return jQuery.dir( elem, "parentNode" );
- },
- parentsUntil: function( elem, i, until ) {
- return jQuery.dir( elem, "parentNode", until );
- },
- next: function( elem ) {
- return jQuery.nth( elem, 2, "nextSibling" );
- },
- prev: function( elem ) {
- return jQuery.nth( elem, 2, "previousSibling" );
- },
- nextAll: function( elem ) {
- return jQuery.dir( elem, "nextSibling" );
- },
- prevAll: function( elem ) {
- return jQuery.dir( elem, "previousSibling" );
- },
- nextUntil: function( elem, i, until ) {
- return jQuery.dir( elem, "nextSibling", until );
- },
- prevUntil: function( elem, i, until ) {
- return jQuery.dir( elem, "previousSibling", until );
- },
- siblings: function( elem ) {
- return jQuery.sibling( elem.parentNode.firstChild, elem );
- },
- children: function( elem ) {
- return jQuery.sibling( elem.firstChild );
- },
- contents: function( elem ) {
- return jQuery.nodeName( elem, "iframe" ) ?
- elem.contentDocument || elem.contentWindow.document :
- jQuery.makeArray( elem.childNodes );
- }
-}, function( name, fn ) {
- jQuery.fn[ name ] = function( until, selector ) {
- var ret = jQuery.map( this, fn, until );
-
- if ( !runtil.test( name ) ) {
- selector = until;
- }
-
- if ( selector && typeof selector === "string" ) {
- ret = jQuery.filter( selector, ret );
- }
-
- ret = this.length > 1 ? jQuery.unique( ret ) : ret;
-
- if ( (this.length > 1 || rmultiselector.test( selector )) && rparentsprev.test( name ) ) {
- ret = ret.reverse();
- }
-
- return this.pushStack( ret, name, slice.call(arguments).join(",") );
- };
-});
-
-jQuery.extend({
- filter: function( expr, elems, not ) {
- if ( not ) {
- expr = ":not(" + expr + ")";
- }
-
- return elems.length === 1 ?
- jQuery.find.matchesSelector(elems[0], expr) ? [ elems[0] ] : [] :
- jQuery.find.matches(expr, elems);
- },
-
- dir: function( elem, dir, until ) {
- var matched = [],
- cur = elem[ dir ];
-
- while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) {
- if ( cur.nodeType === 1 ) {
- matched.push( cur );
- }
- cur = cur[dir];
- }
- return matched;
- },
-
- nth: function( cur, result, dir, elem ) {
- result = result || 1;
- var num = 0;
-
- for ( ; cur; cur = cur[dir] ) {
- if ( cur.nodeType === 1 && ++num === result ) {
- break;
- }
- }
-
- return cur;
- },
-
- sibling: function( n, elem ) {
- var r = [];
-
- for ( ; n; n = n.nextSibling ) {
- if ( n.nodeType === 1 && n !== elem ) {
- r.push( n );
- }
- }
-
- return r;
- }
-});
-
-// Implement the identical functionality for filter and not
-function winnow( elements, qualifier, keep ) {
- if ( jQuery.isFunction( qualifier ) ) {
- return jQuery.grep(elements, function( elem, i ) {
- var retVal = !!qualifier.call( elem, i, elem );
- return retVal === keep;
- });
-
- } else if ( qualifier.nodeType ) {
- return jQuery.grep(elements, function( elem, i ) {
- return (elem === qualifier) === keep;
- });
-
- } else if ( typeof qualifier === "string" ) {
- var filtered = jQuery.grep(elements, function( elem ) {
- return elem.nodeType === 1;
- });
-
- if ( isSimple.test( qualifier ) ) {
- return jQuery.filter(qualifier, filtered, !keep);
- } else {
- qualifier = jQuery.filter( qualifier, filtered );
- }
- }
-
- return jQuery.grep(elements, function( elem, i ) {
- return (jQuery.inArray( elem, qualifier ) >= 0) === keep;
- });
-}
-
-
-
-
-var rinlinejQuery = / jQuery\d+="(?:\d+|null)"/g,
- rleadingWhitespace = /^\s+/,
- rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,
- rtagName = /<([\w:]+)/,
- rtbody = /<tbody/i,
- rhtml = /<|&#?\w+;/,
- rnocache = /<(?:script|object|embed|option|style)/i,
- // checked="checked" or checked (html5)
- rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
- raction = /\=([^="'>\s]+\/)>/g,
- wrapMap = {
- option: [ 1, "<select multiple='multiple'>", "</select>" ],
- legend: [ 1, "<fieldset>", "</fieldset>" ],
- thead: [ 1, "<table>", "</table>" ],
- tr: [ 2, "<table><tbody>", "</tbody></table>" ],
- td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
- col: [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ],
- area: [ 1, "<map>", "</map>" ],
- _default: [ 0, "", "" ]
- };
-
-wrapMap.optgroup = wrapMap.option;
-wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
-wrapMap.th = wrapMap.td;
-
-// IE can't serialize <link> and <script> tags normally
-if ( !jQuery.support.htmlSerialize ) {
- wrapMap._default = [ 1, "div<div>", "</div>" ];
-}
-
-jQuery.fn.extend({
- text: function( text ) {
- if ( jQuery.isFunction(text) ) {
- return this.each(function(i) {
- var self = jQuery( this );
-
- self.text( text.call(this, i, self.text()) );
- });
- }
-
- if ( typeof text !== "object" && text !== undefined ) {
- return this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) );
- }
-
- return jQuery.text( this );
- },
-
- wrapAll: function( html ) {
- if ( jQuery.isFunction( html ) ) {
- return this.each(function(i) {
- jQuery(this).wrapAll( html.call(this, i) );
- });
- }
-
- if ( this[0] ) {
- // The elements to wrap the target around
- var wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true);
-
- if ( this[0].parentNode ) {
- wrap.insertBefore( this[0] );
- }
-
- wrap.map(function() {
- var elem = this;
-
- while ( elem.firstChild && elem.firstChild.nodeType === 1 ) {
- elem = elem.firstChild;
- }
-
- return elem;
- }).append(this);
- }
-
- return this;
- },
-
- wrapInner: function( html ) {
- if ( jQuery.isFunction( html ) ) {
- return this.each(function(i) {
- jQuery(this).wrapInner( html.call(this, i) );
- });
- }
-
- return this.each(function() {
- var self = jQuery( this ),
- contents = self.contents();
-
- if ( contents.length ) {
- contents.wrapAll( html );
-
- } else {
- self.append( html );
- }
- });
- },
-
- wrap: function( html ) {
- return this.each(function() {
- jQuery( this ).wrapAll( html );
- });
- },
-
- unwrap: function() {
- return this.parent().each(function() {
- if ( !jQuery.nodeName( this, "body" ) ) {
- jQuery( this ).replaceWith( this.childNodes );
- }
- }).end();
- },
-
- append: function() {
- return this.domManip(arguments, true, function( elem ) {
- if ( this.nodeType === 1 ) {
- this.appendChild( elem );
- }
- });
- },
-
- prepend: function() {
- return this.domManip(arguments, true, function( elem ) {
- if ( this.nodeType === 1 ) {
- this.insertBefore( elem, this.firstChild );
- }
- });
- },
-
- before: function() {
- if ( this[0] && this[0].parentNode ) {
- return this.domManip(arguments, false, function( elem ) {
- this.parentNode.insertBefore( elem, this );
- });
- } else if ( arguments.length ) {
- var set = jQuery(arguments[0]);
- set.push.apply( set, this.toArray() );
- return this.pushStack( set, "before", arguments );
- }
- },
-
- after: function() {
- if ( this[0] && this[0].parentNode ) {
- return this.domManip(arguments, false, function( elem ) {
- this.parentNode.insertBefore( elem, this.nextSibling );
- });
- } else if ( arguments.length ) {
- var set = this.pushStack( this, "after", arguments );
- set.push.apply( set, jQuery(arguments[0]).toArray() );
- return set;
- }
- },
-
- // keepData is for internal use only--do not document
- remove: function( selector, keepData ) {
- for ( var i = 0, elem; (elem = this[i]) != null; i++ ) {
- if ( !selector || jQuery.filter( selector, [ elem ] ).length ) {
- if ( !keepData && elem.nodeType === 1 ) {
- jQuery.cleanData( elem.getElementsByTagName("*") );
- jQuery.cleanData( [ elem ] );
- }
-
- if ( elem.parentNode ) {
- elem.parentNode.removeChild( elem );
- }
- }
- }
-
- return this;
- },
-
- empty: function() {
- for ( var i = 0, elem; (elem = this[i]) != null; i++ ) {
- // Remove element nodes and prevent memory leaks
- if ( elem.nodeType === 1 ) {
- jQuery.cleanData( elem.getElementsByTagName("*") );
- }
-
- // Remove any remaining nodes
- while ( elem.firstChild ) {
- elem.removeChild( elem.firstChild );
- }
- }
-
- return this;
- },
-
- clone: function( events ) {
- // Do the clone
- var ret = this.map(function() {
- if ( !jQuery.support.noCloneEvent && !jQuery.isXMLDoc(this) ) {
- // IE copies events bound via attachEvent when
- // using cloneNode. Calling detachEvent on the
- // clone will also remove the events from the orignal
- // In order to get around this, we use innerHTML.
- // Unfortunately, this means some modifications to
- // attributes in IE that are actually only stored
- // as properties will not be copied (such as the
- // the name attribute on an input).
- var html = this.outerHTML,
- ownerDocument = this.ownerDocument;
-
- if ( !html ) {
- var div = ownerDocument.createElement("div");
- div.appendChild( this.cloneNode(true) );
- html = div.innerHTML;
- }
-
- return jQuery.clean([html.replace(rinlinejQuery, "")
- // Handle the case in IE 8 where action=/test/> self-closes a tag
- .replace(raction, '="$1">')
- .replace(rleadingWhitespace, "")], ownerDocument)[0];
- } else {
- return this.cloneNode(true);
- }
- });
-
- // Copy the events from the original to the clone
- if ( events === true ) {
- cloneCopyEvent( this, ret );
- cloneCopyEvent( this.find("*"), ret.find("*") );
- }
-
- // Return the cloned set
- return ret;
- },
-
- html: function( value ) {
- if ( value === undefined ) {
- return this[0] && this[0].nodeType === 1 ?
- this[0].innerHTML.replace(rinlinejQuery, "") :
- null;
-
- // See if we can take a shortcut and just use innerHTML
- } else if ( typeof value === "string" && !rnocache.test( value ) &&
- (jQuery.support.leadingWhitespace || !rleadingWhitespace.test( value )) &&
- !wrapMap[ (rtagName.exec( value ) || ["", ""])[1].toLowerCase() ] ) {
-
- value = value.replace(rxhtmlTag, "<$1></$2>");
-
- try {
- for ( var i = 0, l = this.length; i < l; i++ ) {
- // Remove element nodes and prevent memory leaks
- if ( this[i].nodeType === 1 ) {
- jQuery.cleanData( this[i].getElementsByTagName("*") );
- this[i].innerHTML = value;
- }
- }
-
- // If using innerHTML throws an exception, use the fallback method
- } catch(e) {
- this.empty().append( value );
- }
-
- } else if ( jQuery.isFunction( value ) ) {
- this.each(function(i){
- var self = jQuery( this );
-
- self.html( value.call(this, i, self.html()) );
- });
-
- } else {
- this.empty().append( value );
- }
-
- return this;
- },
-
- replaceWith: function( value ) {
- if ( this[0] && this[0].parentNode ) {
- // Make sure that the elements are removed from the DOM before they are inserted
- // this can help fix replacing a parent with child elements
- if ( jQuery.isFunction( value ) ) {
- return this.each(function(i) {
- var self = jQuery(this), old = self.html();
- self.replaceWith( value.call( this, i, old ) );
- });
- }
-
- if ( typeof value !== "string" ) {
- value = jQuery( value ).detach();
- }
-
- return this.each(function() {
- var next = this.nextSibling,
- parent = this.parentNode;
-
- jQuery( this ).remove();
-
- if ( next ) {
- jQuery(next).before( value );
- } else {
- jQuery(parent).append( value );
- }
- });
- } else {
- return this.pushStack( jQuery(jQuery.isFunction(value) ? value() : value), "replaceWith", value );
- }
- },
-
- detach: function( selector ) {
- return this.remove( selector, true );
- },
-
- domManip: function( args, table, callback ) {
- var results, first, fragment, parent,
- value = args[0],
- scripts = [];
-
- // We can't cloneNode fragments that contain checked, in WebKit
- if ( !jQuery.support.checkClone && arguments.length === 3 && typeof value === "string" && rchecked.test( value ) ) {
- return this.each(function() {
- jQuery(this).domManip( args, table, callback, true );
- });
- }
-
- if ( jQuery.isFunction(value) ) {
- return this.each(function(i) {
- var self = jQuery(this);
- args[0] = value.call(this, i, table ? self.html() : undefined);
- self.domManip( args, table, callback );
- });
- }
-
- if ( this[0] ) {
- parent = value && value.parentNode;
-
- // If we're in a fragment, just use that instead of building a new one
- if ( jQuery.support.parentNode && parent && parent.nodeType === 11 && parent.childNodes.length === this.length ) {
- results = { fragment: parent };
-
- } else {
- results = jQuery.buildFragment( args, this, scripts );
- }
-
- fragment = results.fragment;
-
- if ( fragment.childNodes.length === 1 ) {
- first = fragment = fragment.firstChild;
- } else {
- first = fragment.firstChild;
- }
-
- if ( first ) {
- table = table && jQuery.nodeName( first, "tr" );
-
- for ( var i = 0, l = this.length; i < l; i++ ) {
- callback.call(
- table ?
- root(this[i], first) :
- this[i],
- i > 0 || results.cacheable || this.length > 1 ?
- fragment.cloneNode(true) :
- fragment
- );
- }
- }
-
- if ( scripts.length ) {
- jQuery.each( scripts, evalScript );
- }
- }
-
- return this;
- }
-});
-
-function root( elem, cur ) {
- return jQuery.nodeName(elem, "table") ?
- (elem.getElementsByTagName("tbody")[0] ||
- elem.appendChild(elem.ownerDocument.createElement("tbody"))) :
- elem;
-}
-
-function cloneCopyEvent(orig, ret) {
- var i = 0;
-
- ret.each(function() {
- if ( this.nodeName !== (orig[i] && orig[i].nodeName) ) {
- return;
- }
-
- var oldData = jQuery.data( orig[i++] ),
- curData = jQuery.data( this, oldData ),
- events = oldData && oldData.events;
-
- if ( events ) {
- delete curData.handle;
- curData.events = {};
-
- for ( var type in events ) {
- for ( var handler in events[ type ] ) {
- jQuery.event.add( this, type, events[ type ][ handler ], events[ type ][ handler ].data );
- }
- }
- }
- });
-}
-
-jQuery.buildFragment = function( args, nodes, scripts ) {
- var fragment, cacheable, cacheresults,
- doc = (nodes && nodes[0] ? nodes[0].ownerDocument || nodes[0] : document);
-
- // Only cache "small" (1/2 KB) strings that are associated with the main document
- // Cloning options loses the selected state, so don't cache them
- // IE 6 doesn't like it when you put <object> or <embed> elements in a fragment
- // Also, WebKit does not clone 'checked' attributes on cloneNode, so don't cache
- if ( args.length === 1 && typeof args[0] === "string" && args[0].length < 512 && doc === document &&
- !rnocache.test( args[0] ) && (jQuery.support.checkClone || !rchecked.test( args[0] )) ) {
-
- cacheable = true;
- cacheresults = jQuery.fragments[ args[0] ];
- if ( cacheresults ) {
- if ( cacheresults !== 1 ) {
- fragment = cacheresults;
- }
- }
- }
-
- if ( !fragment ) {
- fragment = doc.createDocumentFragment();
- jQuery.clean( args, doc, fragment, scripts );
- }
-
- if ( cacheable ) {
- jQuery.fragments[ args[0] ] = cacheresults ? fragment : 1;
- }
-
- return { fragment: fragment, cacheable: cacheable };
-};
-
-jQuery.fragments = {};
-
-jQuery.each({
- appendTo: "append",
- prependTo: "prepend",
- insertBefore: "before",
- insertAfter: "after",
- replaceAll: "replaceWith"
-}, function( name, original ) {
- jQuery.fn[ name ] = function( selector ) {
- var ret = [],
- insert = jQuery( selector ),
- parent = this.length === 1 && this[0].parentNode;
-
- if ( parent && parent.nodeType === 11 && parent.childNodes.length === 1 && insert.length === 1 ) {
- insert[ original ]( this[0] );
- return this;
-
- } else {
- for ( var i = 0, l = insert.length; i < l; i++ ) {
- var elems = (i > 0 ? this.clone(true) : this).get();
- jQuery( insert[i] )[ original ]( elems );
- ret = ret.concat( elems );
- }
-
- return this.pushStack( ret, name, insert.selector );
- }
- };
-});
-
-jQuery.extend({
- clean: function( elems, context, fragment, scripts ) {
- context = context || document;
-
- // !context.createElement fails in IE with an error but returns typeof 'object'
- if ( typeof context.createElement === "undefined" ) {
- context = context.ownerDocument || context[0] && context[0].ownerDocument || document;
- }
-
- var ret = [];
-
- for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
- if ( typeof elem === "number" ) {
- elem += "";
- }
-
- if ( !elem ) {
- continue;
- }
-
- // Convert html string into DOM nodes
- if ( typeof elem === "string" && !rhtml.test( elem ) ) {
- elem = context.createTextNode( elem );
-
- } else if ( typeof elem === "string" ) {
- // Fix "XHTML"-style tags in all browsers
- elem = elem.replace(rxhtmlTag, "<$1></$2>");
-
- // Trim whitespace, otherwise indexOf won't work as expected
- var tag = (rtagName.exec( elem ) || ["", ""])[1].toLowerCase(),
- wrap = wrapMap[ tag ] || wrapMap._default,
- depth = wrap[0],
- div = context.createElement("div");
-
- // Go to html and back, then peel off extra wrappers
- div.innerHTML = wrap[1] + elem + wrap[2];
-
- // Move to the right depth
- while ( depth-- ) {
- div = div.lastChild;
- }
-
- // Remove IE's autoinserted <tbody> from table fragments
- if ( !jQuery.support.tbody ) {
-
- // String was a <table>, *may* have spurious <tbody>
- var hasBody = rtbody.test(elem),
- tbody = tag === "table" && !hasBody ?
- div.firstChild && div.firstChild.childNodes :
-
- // String was a bare <thead> or <tfoot>
- wrap[1] === "<table>" && !hasBody ?
- div.childNodes :
- [];
-
- for ( var j = tbody.length - 1; j >= 0 ; --j ) {
- if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length ) {
- tbody[ j ].parentNode.removeChild( tbody[ j ] );
- }
- }
-
- }
-
- // IE completely kills leading whitespace when innerHTML is used
- if ( !jQuery.support.leadingWhitespace && rleadingWhitespace.test( elem ) ) {
- div.insertBefore( context.createTextNode( rleadingWhitespace.exec(elem)[0] ), div.firstChild );
- }
-
- elem = div.childNodes;
- }
-
- if ( elem.nodeType ) {
- ret.push( elem );
- } else {
- ret = jQuery.merge( ret, elem );
- }
- }
-
- if ( fragment ) {
- for ( i = 0; ret[i]; i++ ) {
- if ( scripts && jQuery.nodeName( ret[i], "script" ) && (!ret[i].type || ret[i].type.toLowerCase() === "text/javascript") ) {
- scripts.push( ret[i].parentNode ? ret[i].parentNode.removeChild( ret[i] ) : ret[i] );
-
- } else {
- if ( ret[i].nodeType === 1 ) {
- ret.splice.apply( ret, [i + 1, 0].concat(jQuery.makeArray(ret[i].getElementsByTagName("script"))) );
- }
- fragment.appendChild( ret[i] );
- }
- }
- }
-
- return ret;
- },
-
- cleanData: function( elems ) {
- var data, id, cache = jQuery.cache,
- special = jQuery.event.special,
- deleteExpando = jQuery.support.deleteExpando;
-
- for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
- if ( elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()] ) {
- continue;
- }
-
- id = elem[ jQuery.expando ];
-
- if ( id ) {
- data = cache[ id ];
-
- if ( data && data.events ) {
- for ( var type in data.events ) {
- if ( special[ type ] ) {
- jQuery.event.remove( elem, type );
-
- } else {
- jQuery.removeEvent( elem, type, data.handle );
- }
- }
- }
-
- if ( deleteExpando ) {
- delete elem[ jQuery.expando ];
-
- } else if ( elem.removeAttribute ) {
- elem.removeAttribute( jQuery.expando );
- }
-
- delete cache[ id ];
- }
- }
- }
-});
-
-function evalScript( i, elem ) {
- if ( elem.src ) {
- jQuery.ajax({
- url: elem.src,
- async: false,
- dataType: "script"
- });
- } else {
- jQuery.globalEval( elem.text || elem.textContent || elem.innerHTML || "" );
- }
-
- if ( elem.parentNode ) {
- elem.parentNode.removeChild( elem );
- }
-}
-
-
-
-
-var ralpha = /alpha\([^)]*\)/i,
- ropacity = /opacity=([^)]*)/,
- rdashAlpha = /-([a-z])/ig,
- rupper = /([A-Z])/g,
- rnumpx = /^-?\d+(?:px)?$/i,
- rnum = /^-?\d/,
-
- cssShow = { position: "absolute", visibility: "hidden", display: "block" },
- cssWidth = [ "Left", "Right" ],
- cssHeight = [ "Top", "Bottom" ],
- curCSS,
-
- getComputedStyle,
- currentStyle,
-
- fcamelCase = function( all, letter ) {
- return letter.toUpperCase();
- };
-
-jQuery.fn.css = function( name, value ) {
- // Setting 'undefined' is a no-op
- if ( arguments.length === 2 && value === undefined ) {
- return this;
- }
-
- return jQuery.access( this, name, value, true, function( elem, name, value ) {
- return value !== undefined ?
- jQuery.style( elem, name, value ) :
- jQuery.css( elem, name );
- });
-};
-
-jQuery.extend({
- // Add in style property hooks for overriding the default
- // behavior of getting and setting a style property
- cssHooks: {
- opacity: {
- get: function( elem, computed ) {
- if ( computed ) {
- // We should always get a number back from opacity
- var ret = curCSS( elem, "opacity", "opacity" );
- return ret === "" ? "1" : ret;
-
- } else {
- return elem.style.opacity;
- }
- }
- }
- },
-
- // Exclude the following css properties to add px
- cssNumber: {
- "zIndex": true,
- "fontWeight": true,
- "opacity": true,
- "zoom": true,
- "lineHeight": true
- },
-
- // Add in properties whose names you wish to fix before
- // setting or getting the value
- cssProps: {
- // normalize float css property
- "float": jQuery.support.cssFloat ? "cssFloat" : "styleFloat"
- },
-
- // Get and set the style property on a DOM Node
- style: function( elem, name, value, extra ) {
- // Don't set styles on text and comment nodes
- if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
- return;
- }
-
- // Make sure that we're working with the right name
- var ret, origName = jQuery.camelCase( name ),
- style = elem.style, hooks = jQuery.cssHooks[ origName ];
-
- name = jQuery.cssProps[ origName ] || origName;
-
- // Check if we're setting a value
- if ( value !== undefined ) {
- // Make sure that NaN and null values aren't set. See: #7116
- if ( typeof value === "number" && isNaN( value ) || value == null ) {
- return;
- }
-
- // If a number was passed in, add 'px' to the (except for certain CSS properties)
- if ( typeof value === "number" && !jQuery.cssNumber[ origName ] ) {
- value += "px";
- }
-
- // If a hook was provided, use that value, otherwise just set the specified value
- if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value )) !== undefined ) {
- // Wrapped to prevent IE from throwing errors when 'invalid' values are provided
- // Fixes bug #5509
- try {
- style[ name ] = value;
- } catch(e) {}
- }
-
- } else {
- // If a hook was provided get the non-computed value from there
- if ( hooks && "get" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) {
- return ret;
- }
-
- // Otherwise just get the value from the style object
- return style[ name ];
- }
- },
-
- css: function( elem, name, extra ) {
- // Make sure that we're working with the right name
- var ret, origName = jQuery.camelCase( name ),
- hooks = jQuery.cssHooks[ origName ];
-
- name = jQuery.cssProps[ origName ] || origName;
-
- // If a hook was provided get the computed value from there
- if ( hooks && "get" in hooks && (ret = hooks.get( elem, true, extra )) !== undefined ) {
- return ret;
-
- // Otherwise, if a way to get the computed value exists, use that
- } else if ( curCSS ) {
- return curCSS( elem, name, origName );
- }
- },
-
- // A method for quickly swapping in/out CSS properties to get correct calculations
- swap: function( elem, options, callback ) {
- var old = {};
-
- // Remember the old values, and insert the new ones
- for ( var name in options ) {
- old[ name ] = elem.style[ name ];
- elem.style[ name ] = options[ name ];
- }
-
- callback.call( elem );
-
- // Revert the old values
- for ( name in options ) {
- elem.style[ name ] = old[ name ];
- }
- },
-
- camelCase: function( string ) {
- return string.replace( rdashAlpha, fcamelCase );
- }
-});
-
-// DEPRECATED, Use jQuery.css() instead
-jQuery.curCSS = jQuery.css;
-
-jQuery.each(["height", "width"], function( i, name ) {
- jQuery.cssHooks[ name ] = {
- get: function( elem, computed, extra ) {
- var val;
-
- if ( computed ) {
- if ( elem.offsetWidth !== 0 ) {
- val = getWH( elem, name, extra );
-
- } else {
- jQuery.swap( elem, cssShow, function() {
- val = getWH( elem, name, extra );
- });
- }
-
- if ( val <= 0 ) {
- val = curCSS( elem, name, name );
-
- if ( val === "0px" && currentStyle ) {
- val = currentStyle( elem, name, name );
- }
-
- if ( val != null ) {
- // Should return "auto" instead of 0, use 0 for
- // temporary backwards-compat
- return val === "" || val === "auto" ? "0px" : val;
- }
- }
-
- if ( val < 0 || val == null ) {
- val = elem.style[ name ];
-
- // Should return "auto" instead of 0, use 0 for
- // temporary backwards-compat
- return val === "" || val === "auto" ? "0px" : val;
- }
-
- return typeof val === "string" ? val : val + "px";
- }
- },
-
- set: function( elem, value ) {
- if ( rnumpx.test( value ) ) {
- // ignore negative width and height values #1599
- value = parseFloat(value);
-
- if ( value >= 0 ) {
- return value + "px";
- }
-
- } else {
- return value;
- }
- }
- };
-});
-
-if ( !jQuery.support.opacity ) {
- jQuery.cssHooks.opacity = {
- get: function( elem, computed ) {
- // IE uses filters for opacity
- return ropacity.test((computed && elem.currentStyle ? elem.currentStyle.filter : elem.style.filter) || "") ?
- (parseFloat(RegExp.$1) / 100) + "" :
- computed ? "1" : "";
- },
-
- set: function( elem, value ) {
- var style = elem.style;
-
- // IE has trouble with opacity if it does not have layout
- // Force it by setting the zoom level
- style.zoom = 1;
-
- // Set the alpha filter to set the opacity
- var opacity = jQuery.isNaN(value) ?
- "" :
- "alpha(opacity=" + value * 100 + ")",
- filter = style.filter || "";
-
- style.filter = ralpha.test(filter) ?
- filter.replace(ralpha, opacity) :
- style.filter + ' ' + opacity;
- }
- };
-}
-
-if ( document.defaultView && document.defaultView.getComputedStyle ) {
- getComputedStyle = function( elem, newName, name ) {
- var ret, defaultView, computedStyle;
-
- name = name.replace( rupper, "-$1" ).toLowerCase();
-
- if ( !(defaultView = elem.ownerDocument.defaultView) ) {
- return undefined;
- }
-
- if ( (computedStyle = defaultView.getComputedStyle( elem, null )) ) {
- ret = computedStyle.getPropertyValue( name );
- if ( ret === "" && !jQuery.contains( elem.ownerDocument.documentElement, elem ) ) {
- ret = jQuery.style( elem, name );
- }
- }
-
- return ret;
- };
-}
-
-if ( document.documentElement.currentStyle ) {
- currentStyle = function( elem, name ) {
- var left, rsLeft,
- ret = elem.currentStyle && elem.currentStyle[ name ],
- style = elem.style;
-
- // From the awesome hack by Dean Edwards
- // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
-
- // If we're not dealing with a regular pixel number
- // but a number that has a weird ending, we need to convert it to pixels
- if ( !rnumpx.test( ret ) && rnum.test( ret ) ) {
- // Remember the original values
- left = style.left;
- rsLeft = elem.runtimeStyle.left;
-
- // Put in the new values to get a computed value out
- elem.runtimeStyle.left = elem.currentStyle.left;
- style.left = name === "fontSize" ? "1em" : (ret || 0);
- ret = style.pixelLeft + "px";
-
- // Revert the changed values
- style.left = left;
- elem.runtimeStyle.left = rsLeft;
- }
-
- return ret === "" ? "auto" : ret;
- };
-}
-
-curCSS = getComputedStyle || currentStyle;
-
-function getWH( elem, name, extra ) {
- var which = name === "width" ? cssWidth : cssHeight,
- val = name === "width" ? elem.offsetWidth : elem.offsetHeight;
-
- if ( extra === "border" ) {
- return val;
- }
-
- jQuery.each( which, function() {
- if ( !extra ) {
- val -= parseFloat(jQuery.css( elem, "padding" + this )) || 0;
- }
-
- if ( extra === "margin" ) {
- val += parseFloat(jQuery.css( elem, "margin" + this )) || 0;
-
- } else {
- val -= parseFloat(jQuery.css( elem, "border" + this + "Width" )) || 0;
- }
- });
-
- return val;
-}
-
-if ( jQuery.expr && jQuery.expr.filters ) {
- jQuery.expr.filters.hidden = function( elem ) {
- var width = elem.offsetWidth,
- height = elem.offsetHeight;
-
- return (width === 0 && height === 0) || (!jQuery.support.reliableHiddenOffsets && (elem.style.display || jQuery.css( elem, "display" )) === "none");
- };
-
- jQuery.expr.filters.visible = function( elem ) {
- return !jQuery.expr.filters.hidden( elem );
- };
-}
-
-
-
-
-var jsc = jQuery.now(),
- rscript = /<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,
- rselectTextarea = /^(?:select|textarea)/i,
- rinput = /^(?:color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,
- rnoContent = /^(?:GET|HEAD)$/,
- rbracket = /\[\]$/,
- jsre = /\=\?(&|$)/,
- rquery = /\?/,
- rts = /([?&])_=[^&]*/,
- rurl = /^(\w+:)?\/\/([^\/?#]+)/,
- r20 = /%20/g,
- rhash = /#.*$/,
-
- // Keep a copy of the old load method
- _load = jQuery.fn.load;
-
-jQuery.fn.extend({
- load: function( url, params, callback ) {
- if ( typeof url !== "string" && _load ) {
- return _load.apply( this, arguments );
-
- // Don't do a request if no elements are being requested
- } else if ( !this.length ) {
- return this;
- }
-
- var off = url.indexOf(" ");
- if ( off >= 0 ) {
- var selector = url.slice(off, url.length);
- url = url.slice(0, off);
- }
-
- // Default to a GET request
- var type = "GET";
-
- // If the second parameter was provided
- if ( params ) {
- // If it's a function
- if ( jQuery.isFunction( params ) ) {
- // We assume that it's the callback
- callback = params;
- params = null;
-
- // Otherwise, build a param string
- } else if ( typeof params === "object" ) {
- params = jQuery.param( params, jQuery.ajaxSettings.traditional );
- type = "POST";
- }
- }
-
- var self = this;
-
- // Request the remote document
- jQuery.ajax({
- url: url,
- type: type,
- dataType: "html",
- data: params,
- complete: function( res, status ) {
- // If successful, inject the HTML into all the matched elements
- if ( status === "success" || status === "notmodified" ) {
- // See if a selector was specified
- self.html( selector ?
- // Create a dummy div to hold the results
- jQuery("<div>")
- // inject the contents of the document in, removing the scripts
- // to avoid any 'Permission Denied' errors in IE
- .append(res.responseText.replace(rscript, ""))
-
- // Locate the specified elements
- .find(selector) :
-
- // If not, just inject the full result
- res.responseText );
- }
-
- if ( callback ) {
- self.each( callback, [res.responseText, status, res] );
- }
- }
- });
-
- return this;
- },
-
- serialize: function() {
- return jQuery.param(this.serializeArray());
- },
-
- serializeArray: function() {
- return this.map(function() {
- return this.elements ? jQuery.makeArray(this.elements) : this;
- })
- .filter(function() {
- return this.name && !this.disabled &&
- (this.checked || rselectTextarea.test(this.nodeName) ||
- rinput.test(this.type));
- })
- .map(function( i, elem ) {
- var val = jQuery(this).val();
-
- return val == null ?
- null :
- jQuery.isArray(val) ?
- jQuery.map( val, function( val, i ) {
- return { name: elem.name, value: val };
- }) :
- { name: elem.name, value: val };
- }).get();
- }
-});
-
-// Attach a bunch of functions for handling common AJAX events
-jQuery.each( "ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "), function( i, o ) {
- jQuery.fn[o] = function( f ) {
- return this.bind(o, f);
- };
-});
-
-jQuery.extend({
- get: function( url, data, callback, type ) {
- // shift arguments if data argument was omited
- if ( jQuery.isFunction( data ) ) {
- type = type || callback;
- callback = data;
- data = null;
- }
-
- return jQuery.ajax({
- type: "GET",
- url: url,
- data: data,
- success: callback,
- dataType: type
- });
- },
-
- getScript: function( url, callback ) {
- return jQuery.get(url, null, callback, "script");
- },
-
- getJSON: function( url, data, callback ) {
- return jQuery.get(url, data, callback, "json");
- },
-
- post: function( url, data, callback, type ) {
- // shift arguments if data argument was omited
- if ( jQuery.isFunction( data ) ) {
- type = type || callback;
- callback = data;
- data = {};
- }
-
- return jQuery.ajax({
- type: "POST",
- url: url,
- data: data,
- success: callback,
- dataType: type
- });
- },
-
- ajaxSetup: function( settings ) {
- jQuery.extend( jQuery.ajaxSettings, settings );
- },
-
- ajaxSettings: {
- url: location.href,
- global: true,
- type: "GET",
- contentType: "application/x-www-form-urlencoded",
- processData: true,
- async: true,
- /*
- timeout: 0,
- data: null,
- username: null,
- password: null,
- traditional: false,
- */
- // This function can be overriden by calling jQuery.ajaxSetup
- xhr: function() {
- return new window.XMLHttpRequest();
- },
- accepts: {
- xml: "application/xml, text/xml",
- html: "text/html",
- script: "text/javascript, application/javascript",
- json: "application/json, text/javascript",
- text: "text/plain",
- _default: "*/*"
- }
- },
-
- ajax: function( origSettings ) {
- var s = jQuery.extend(true, {}, jQuery.ajaxSettings, origSettings),
- jsonp, status, data, type = s.type.toUpperCase(), noContent = rnoContent.test(type);
-
- s.url = s.url.replace( rhash, "" );
-
- // Use original (not extended) context object if it was provided
- s.context = origSettings && origSettings.context != null ? origSettings.context : s;
-
- // convert data if not already a string
- if ( s.data && s.processData && typeof s.data !== "string" ) {
- s.data = jQuery.param( s.data, s.traditional );
- }
-
- // Handle JSONP Parameter Callbacks
- if ( s.dataType === "jsonp" ) {
- if ( type === "GET" ) {
- if ( !jsre.test( s.url ) ) {
- s.url += (rquery.test( s.url ) ? "&" : "?") + (s.jsonp || "callback") + "=?";
- }
- } else if ( !s.data || !jsre.test(s.data) ) {
- s.data = (s.data ? s.data + "&" : "") + (s.jsonp || "callback") + "=?";
- }
- s.dataType = "json";
- }
-
- // Build temporary JSONP function
- if ( s.dataType === "json" && (s.data && jsre.test(s.data) || jsre.test(s.url)) ) {
- jsonp = s.jsonpCallback || ("jsonp" + jsc++);
-
- // Replace the =? sequence both in the query string and the data
- if ( s.data ) {
- s.data = (s.data + "").replace(jsre, "=" + jsonp + "$1");
- }
-
- s.url = s.url.replace(jsre, "=" + jsonp + "$1");
-
- // We need to make sure
- // that a JSONP style response is executed properly
- s.dataType = "script";
-
- // Handle JSONP-style loading
- var customJsonp = window[ jsonp ];
-
- window[ jsonp ] = function( tmp ) {
- if ( jQuery.isFunction( customJsonp ) ) {
- customJsonp( tmp );
-
- } else {
- // Garbage collect
- window[ jsonp ] = undefined;
-
- try {
- delete window[ jsonp ];
- } catch( jsonpError ) {}
- }
-
- data = tmp;
- jQuery.handleSuccess( s, xhr, status, data );
- jQuery.handleComplete( s, xhr, status, data );
-
- if ( head ) {
- head.removeChild( script );
- }
- };
- }
-
- if ( s.dataType === "script" && s.cache === null ) {
- s.cache = false;
- }
-
- if ( s.cache === false && noContent ) {
- var ts = jQuery.now();
-
- // try replacing _= if it is there
- var ret = s.url.replace(rts, "$1_=" + ts);
-
- // if nothing was replaced, add timestamp to the end
- s.url = ret + ((ret === s.url) ? (rquery.test(s.url) ? "&" : "?") + "_=" + ts : "");
- }
-
- // If data is available, append data to url for GET/HEAD requests
- if ( s.data && noContent ) {
- s.url += (rquery.test(s.url) ? "&" : "?") + s.data;
- }
-
- // Watch for a new set of requests
- if ( s.global && jQuery.active++ === 0 ) {
- jQuery.event.trigger( "ajaxStart" );
- }
-
- // Matches an absolute URL, and saves the domain
- var parts = rurl.exec( s.url ),
- remote = parts && (parts[1] && parts[1].toLowerCase() !== location.protocol || parts[2].toLowerCase() !== location.host);
-
- // If we're requesting a remote document
- // and trying to load JSON or Script with a GET
- if ( s.dataType === "script" && type === "GET" && remote ) {
- var head = document.getElementsByTagName("head")[0] || document.documentElement;
- var script = document.createElement("script");
- if ( s.scriptCharset ) {
- script.charset = s.scriptCharset;
- }
- script.src = s.url;
-
- // Handle Script loading
- if ( !jsonp ) {
- var done = false;
-
- // Attach handlers for all browsers
- script.onload = script.onreadystatechange = function() {
- if ( !done && (!this.readyState ||
- this.readyState === "loaded" || this.readyState === "complete") ) {
- done = true;
- jQuery.handleSuccess( s, xhr, status, data );
- jQuery.handleComplete( s, xhr, status, data );
-
- // Handle memory leak in IE
- script.onload = script.onreadystatechange = null;
- if ( head && script.parentNode ) {
- head.removeChild( script );
- }
- }
- };
- }
-
- // Use insertBefore instead of appendChild to circumvent an IE6 bug.
- // This arises when a base node is used (#2709 and #4378).
- head.insertBefore( script, head.firstChild );
-
- // We handle everything using the script element injection
- return undefined;
- }
-
- var requestDone = false;
-
- // Create the request object
- var xhr = s.xhr();
-
- if ( !xhr ) {
- return;
- }
-
- // Open the socket
- // Passing null username, generates a login popup on Opera (#2865)
- if ( s.username ) {
- xhr.open(type, s.url, s.async, s.username, s.password);
- } else {
- xhr.open(type, s.url, s.async);
- }
-
- // Need an extra try/catch for cross domain requests in Firefox 3
- try {
- // Set content-type if data specified and content-body is valid for this type
- if ( (s.data != null && !noContent) || (origSettings && origSettings.contentType) ) {
- xhr.setRequestHeader("Content-Type", s.contentType);
- }
-
- // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
- if ( s.ifModified ) {
- if ( jQuery.lastModified[s.url] ) {
- xhr.setRequestHeader("If-Modified-Since", jQuery.lastModified[s.url]);
- }
-
- if ( jQuery.etag[s.url] ) {
- xhr.setRequestHeader("If-None-Match", jQuery.etag[s.url]);
- }
- }
-
- // Set header so the called script knows that it's an XMLHttpRequest
- // Only send the header if it's not a remote XHR
- if ( !remote ) {
- xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
- }
-
- // Set the Accepts header for the server, depending on the dataType
- xhr.setRequestHeader("Accept", s.dataType && s.accepts[ s.dataType ] ?
- s.accepts[ s.dataType ] + ", */*; q=0.01" :
- s.accepts._default );
- } catch( headerError ) {}
-
- // Allow custom headers/mimetypes and early abort
- if ( s.beforeSend && s.beforeSend.call(s.context, xhr, s) === false ) {
- // Handle the global AJAX counter
- if ( s.global && jQuery.active-- === 1 ) {
- jQuery.event.trigger( "ajaxStop" );
- }
-
- // close opended socket
- xhr.abort();
- return false;
- }
-
- if ( s.global ) {
- jQuery.triggerGlobal( s, "ajaxSend", [xhr, s] );
- }
-
- // Wait for a response to come back
- var onreadystatechange = xhr.onreadystatechange = function( isTimeout ) {
- // The request was aborted
- if ( !xhr || xhr.readyState === 0 || isTimeout === "abort" ) {
- // Opera doesn't call onreadystatechange before this point
- // so we simulate the call
- if ( !requestDone ) {
- jQuery.handleComplete( s, xhr, status, data );
- }
-
- requestDone = true;
- if ( xhr ) {
- xhr.onreadystatechange = jQuery.noop;
- }
-
- // The transfer is complete and the data is available, or the request timed out
- } else if ( !requestDone && xhr && (xhr.readyState === 4 || isTimeout === "timeout") ) {
- requestDone = true;
- xhr.onreadystatechange = jQuery.noop;
-
- status = isTimeout === "timeout" ?
- "timeout" :
- !jQuery.httpSuccess( xhr ) ?
- "error" :
- s.ifModified && jQuery.httpNotModified( xhr, s.url ) ?
- "notmodified" :
- "success";
-
- var errMsg;
-
- if ( status === "success" ) {
- // Watch for, and catch, XML document parse errors
- try {
- // process the data (runs the xml through httpData regardless of callback)
- data = jQuery.httpData( xhr, s.dataType, s );
- } catch( parserError ) {
- status = "parsererror";
- errMsg = parserError;
- }
- }
-
- // Make sure that the request was successful or notmodified
- if ( status === "success" || status === "notmodified" ) {
- // JSONP handles its own success callback
- if ( !jsonp ) {
- jQuery.handleSuccess( s, xhr, status, data );
- }
- } else {
- jQuery.handleError( s, xhr, status, errMsg );
- }
-
- // Fire the complete handlers
- if ( !jsonp ) {
- jQuery.handleComplete( s, xhr, status, data );
- }
-
- if ( isTimeout === "timeout" ) {
- xhr.abort();
- }
-
- // Stop memory leaks
- if ( s.async ) {
- xhr = null;
- }
- }
- };
-
- // Override the abort handler, if we can (IE 6 doesn't allow it, but that's OK)
- // Opera doesn't fire onreadystatechange at all on abort
- try {
- var oldAbort = xhr.abort;
- xhr.abort = function() {
- if ( xhr ) {
- // oldAbort has no call property in IE7 so
- // just do it this way, which works in all
- // browsers
- Function.prototype.call.call( oldAbort, xhr );
- }
-
- onreadystatechange( "abort" );
- };
- } catch( abortError ) {}
-
- // Timeout checker
- if ( s.async && s.timeout > 0 ) {
- setTimeout(function() {
- // Check to see if the request is still happening
- if ( xhr && !requestDone ) {
- onreadystatechange( "timeout" );
- }
- }, s.timeout);
- }
-
- // Send the data
- try {
- xhr.send( noContent || s.data == null ? null : s.data );
-
- } catch( sendError ) {
- jQuery.handleError( s, xhr, null, sendError );
-
- // Fire the complete handlers
- jQuery.handleComplete( s, xhr, status, data );
- }
-
- // firefox 1.5 doesn't fire statechange for sync requests
- if ( !s.async ) {
- onreadystatechange();
- }
-
- // return XMLHttpRequest to allow aborting the request etc.
- return xhr;
- },
-
- // Serialize an array of form elements or a set of
- // key/values into a query string
- param: function( a, traditional ) {
- var s = [],
- add = function( key, value ) {
- // If value is a function, invoke it and return its value
- value = jQuery.isFunction(value) ? value() : value;
- s[ s.length ] = encodeURIComponent(key) + "=" + encodeURIComponent(value);
- };
-
- // Set traditional to true for jQuery <= 1.3.2 behavior.
- if ( traditional === undefined ) {
- traditional = jQuery.ajaxSettings.traditional;
- }
-
- // If an array was passed in, assume that it is an array of form elements.
- if ( jQuery.isArray(a) || a.jquery ) {
- // Serialize the form elements
- jQuery.each( a, function() {
- add( this.name, this.value );
- });
-
- } else {
- // If traditional, encode the "old" way (the way 1.3.2 or older
- // did it), otherwise encode params recursively.
- for ( var prefix in a ) {
- buildParams( prefix, a[prefix], traditional, add );
- }
- }
-
- // Return the resulting serialization
- return s.join("&").replace(r20, "+");
- }
-});
-
-function buildParams( prefix, obj, traditional, add ) {
- if ( jQuery.isArray(obj) && obj.length ) {
- // Serialize array item.
- jQuery.each( obj, function( i, v ) {
- if ( traditional || rbracket.test( prefix ) ) {
- // Treat each array item as a scalar.
- add( prefix, v );
-
- } else {
- // If array item is non-scalar (array or object), encode its
- // numeric index to resolve deserialization ambiguity issues.
- // Note that rack (as of 1.0.0) can't currently deserialize
- // nested arrays properly, and attempting to do so may cause
- // a server error. Possible fixes are to modify rack's
- // deserialization algorithm or to provide an option or flag
- // to force array serialization to be shallow.
- buildParams( prefix + "[" + ( typeof v === "object" || jQuery.isArray(v) ? i : "" ) + "]", v, traditional, add );
- }
- });
-
- } else if ( !traditional && obj != null && typeof obj === "object" ) {
- if ( jQuery.isEmptyObject( obj ) ) {
- add( prefix, "" );
-
- // Serialize object item.
- } else {
- jQuery.each( obj, function( k, v ) {
- buildParams( prefix + "[" + k + "]", v, traditional, add );
- });
- }
-
- } else {
- // Serialize scalar item.
- add( prefix, obj );
- }
-}
-
-// This is still on the jQuery object... for now
-// Want to move this to jQuery.ajax some day
-jQuery.extend({
-
- // Counter for holding the number of active queries
- active: 0,
-
- // Last-Modified header cache for next request
- lastModified: {},
- etag: {},
-
- handleError: function( s, xhr, status, e ) {
- // If a local callback was specified, fire it
- if ( s.error ) {
- s.error.call( s.context, xhr, status, e );
- }
-
- // Fire the global callback
- if ( s.global ) {
- jQuery.triggerGlobal( s, "ajaxError", [xhr, s, e] );
- }
- },
-
- handleSuccess: function( s, xhr, status, data ) {
- // If a local callback was specified, fire it and pass it the data
- if ( s.success ) {
- s.success.call( s.context, data, status, xhr );
- }
-
- // Fire the global callback
- if ( s.global ) {
- jQuery.triggerGlobal( s, "ajaxSuccess", [xhr, s] );
- }
- },
-
- handleComplete: function( s, xhr, status ) {
- // Process result
- if ( s.complete ) {
- s.complete.call( s.context, xhr, status );
- }
-
- // The request was completed
- if ( s.global ) {
- jQuery.triggerGlobal( s, "ajaxComplete", [xhr, s] );
- }
-
- // Handle the global AJAX counter
- if ( s.global && jQuery.active-- === 1 ) {
- jQuery.event.trigger( "ajaxStop" );
- }
- },
-
- triggerGlobal: function( s, type, args ) {
- (s.context && s.context.url == null ? jQuery(s.context) : jQuery.event).trigger(type, args);
- },
-
- // Determines if an XMLHttpRequest was successful or not
- httpSuccess: function( xhr ) {
- try {
- // IE error sometimes returns 1223 when it should be 204 so treat it as success, see #1450
- return !xhr.status && location.protocol === "file:" ||
- xhr.status >= 200 && xhr.status < 300 ||
- xhr.status === 304 || xhr.status === 1223;
- } catch(e) {}
-
- return false;
- },
-
- // Determines if an XMLHttpRequest returns NotModified
- httpNotModified: function( xhr, url ) {
- var lastModified = xhr.getResponseHeader("Last-Modified"),
- etag = xhr.getResponseHeader("Etag");
-
- if ( lastModified ) {
- jQuery.lastModified[url] = lastModified;
- }
-
- if ( etag ) {
- jQuery.etag[url] = etag;
- }
-
- return xhr.status === 304;
- },
-
- httpData: function( xhr, type, s ) {
- var ct = xhr.getResponseHeader("content-type") || "",
- xml = type === "xml" || !type && ct.indexOf("xml") >= 0,
- data = xml ? xhr.responseXML : xhr.responseText;
-
- if ( xml && data.documentElement.nodeName === "parsererror" ) {
- jQuery.error( "parsererror" );
- }
-
- // Allow a pre-filtering function to sanitize the response
- // s is checked to keep backwards compatibility
- if ( s && s.dataFilter ) {
- data = s.dataFilter( data, type );
- }
-
- // The filter can actually parse the response
- if ( typeof data === "string" ) {
- // Get the JavaScript object, if JSON is used.
- if ( type === "json" || !type && ct.indexOf("json") >= 0 ) {
- data = jQuery.parseJSON( data );
-
- // If the type is "script", eval it in global context
- } else if ( type === "script" || !type && ct.indexOf("javascript") >= 0 ) {
- jQuery.globalEval( data );
- }
- }
-
- return data;
- }
-
-});
-
-/*
- * Create the request object; Microsoft failed to properly
- * implement the XMLHttpRequest in IE7 (can't request local files),
- * so we use the ActiveXObject when it is available
- * Additionally XMLHttpRequest can be disabled in IE7/IE8 so
- * we need a fallback.
- */
-if ( window.ActiveXObject ) {
- jQuery.ajaxSettings.xhr = function() {
- if ( window.location.protocol !== "file:" ) {
- try {
- return new window.XMLHttpRequest();
- } catch(xhrError) {}
- }
-
- try {
- return new window.ActiveXObject("Microsoft.XMLHTTP");
- } catch(activeError) {}
- };
-}
-
-// Does this browser support XHR requests?
-jQuery.support.ajax = !!jQuery.ajaxSettings.xhr();
-
-
-
-
-var elemdisplay = {},
- rfxtypes = /^(?:toggle|show|hide)$/,
- rfxnum = /^([+\-]=)?([\d+.\-]+)(.*)$/,
- timerId,
- fxAttrs = [
- // height animations
- [ "height", "marginTop", "marginBottom", "paddingTop", "paddingBottom" ],
- // width animations
- [ "width", "marginLeft", "marginRight", "paddingLeft", "paddingRight" ],
- // opacity animations
- [ "opacity" ]
- ];
-
-jQuery.fn.extend({
- show: function( speed, easing, callback ) {
- var elem, display;
-
- if ( speed || speed === 0 ) {
- return this.animate( genFx("show", 3), speed, easing, callback);
-
- } else {
- for ( var i = 0, j = this.length; i < j; i++ ) {
- elem = this[i];
- display = elem.style.display;
-
- // Reset the inline display of this element to learn if it is
- // being hidden by cascaded rules or not
- if ( !jQuery.data(elem, "olddisplay") && display === "none" ) {
- display = elem.style.display = "";
- }
-
- // Set elements which have been overridden with display: none
- // in a stylesheet to whatever the default browser style is
- // for such an element
- if ( display === "" && jQuery.css( elem, "display" ) === "none" ) {
- jQuery.data(elem, "olddisplay", defaultDisplay(elem.nodeName));
- }
- }
-
- // Set the display of most of the elements in a second loop
- // to avoid the constant reflow
- for ( i = 0; i < j; i++ ) {
- elem = this[i];
- display = elem.style.display;
-
- if ( display === "" || display === "none" ) {
- elem.style.display = jQuery.data(elem, "olddisplay") || "";
- }
- }
-
- return this;
- }
- },
-
- hide: function( speed, easing, callback ) {
- if ( speed || speed === 0 ) {
- return this.animate( genFx("hide", 3), speed, easing, callback);
-
- } else {
- for ( var i = 0, j = this.length; i < j; i++ ) {
- var display = jQuery.css( this[i], "display" );
-
- if ( display !== "none" ) {
- jQuery.data( this[i], "olddisplay", display );
- }
- }
-
- // Set the display of the elements in a second loop
- // to avoid the constant reflow
- for ( i = 0; i < j; i++ ) {
- this[i].style.display = "none";
- }
-
- return this;
- }
- },
-
- // Save the old toggle function
- _toggle: jQuery.fn.toggle,
-
- toggle: function( fn, fn2, callback ) {
- var bool = typeof fn === "boolean";
-
- if ( jQuery.isFunction(fn) && jQuery.isFunction(fn2) ) {
- this._toggle.apply( this, arguments );
-
- } else if ( fn == null || bool ) {
- this.each(function() {
- var state = bool ? fn : jQuery(this).is(":hidden");
- jQuery(this)[ state ? "show" : "hide" ]();
- });
-
- } else {
- this.animate(genFx("toggle", 3), fn, fn2, callback);
- }
-
- return this;
- },
-
- fadeTo: function( speed, to, easing, callback ) {
- return this.filter(":hidden").css("opacity", 0).show().end()
- .animate({opacity: to}, speed, easing, callback);
- },
-
- animate: function( prop, speed, easing, callback ) {
- var optall = jQuery.speed(speed, easing, callback);
-
- if ( jQuery.isEmptyObject( prop ) ) {
- return this.each( optall.complete );
- }
-
- return this[ optall.queue === false ? "each" : "queue" ](function() {
- // XXX 'this' does not always have a nodeName when running the
- // test suite
-
- var opt = jQuery.extend({}, optall), p,
- isElement = this.nodeType === 1,
- hidden = isElement && jQuery(this).is(":hidden"),
- self = this;
-
- for ( p in prop ) {
- var name = jQuery.camelCase( p );
-
- if ( p !== name ) {
- prop[ name ] = prop[ p ];
- delete prop[ p ];
- p = name;
- }
-
- if ( prop[p] === "hide" && hidden || prop[p] === "show" && !hidden ) {
- return opt.complete.call(this);
- }
-
- if ( isElement && ( p === "height" || p === "width" ) ) {
- // Make sure that nothing sneaks out
- // Record all 3 overflow attributes because IE does not
- // change the overflow attribute when overflowX and
- // overflowY are set to the same value
- opt.overflow = [ this.style.overflow, this.style.overflowX, this.style.overflowY ];
-
- // Set display property to inline-block for height/width
- // animations on inline elements that are having width/height
- // animated
- if ( jQuery.css( this, "display" ) === "inline" &&
- jQuery.css( this, "float" ) === "none" ) {
- if ( !jQuery.support.inlineBlockNeedsLayout ) {
- this.style.display = "inline-block";
-
- } else {
- var display = defaultDisplay(this.nodeName);
-
- // inline-level elements accept inline-block;
- // block-level elements need to be inline with layout
- if ( display === "inline" ) {
- this.style.display = "inline-block";
-
- } else {
- this.style.display = "inline";
- this.style.zoom = 1;
- }
- }
- }
- }
-
- if ( jQuery.isArray( prop[p] ) ) {
- // Create (if needed) and add to specialEasing
- (opt.specialEasing = opt.specialEasing || {})[p] = prop[p][1];
- prop[p] = prop[p][0];
- }
- }
-
- if ( opt.overflow != null ) {
- this.style.overflow = "hidden";
- }
-
- opt.curAnim = jQuery.extend({}, prop);
-
- jQuery.each( prop, function( name, val ) {
- var e = new jQuery.fx( self, opt, name );
-
- if ( rfxtypes.test(val) ) {
- e[ val === "toggle" ? hidden ? "show" : "hide" : val ]( prop );
-
- } else {
- var parts = rfxnum.exec(val),
- start = e.cur() || 0;
-
- if ( parts ) {
- var end = parseFloat( parts[2] ),
- unit = parts[3] || "px";
-
- // We need to compute starting value
- if ( unit !== "px" ) {
- jQuery.style( self, name, (end || 1) + unit);
- start = ((end || 1) / e.cur()) * start;
- jQuery.style( self, name, start + unit);
- }
-
- // If a +=/-= token was provided, we're doing a relative animation
- if ( parts[1] ) {
- end = ((parts[1] === "-=" ? -1 : 1) * end) + start;
- }
-
- e.custom( start, end, unit );
-
- } else {
- e.custom( start, val, "" );
- }
- }
- });
-
- // For JS strict compliance
- return true;
- });
- },
-
- stop: function( clearQueue, gotoEnd ) {
- var timers = jQuery.timers;
-
- if ( clearQueue ) {
- this.queue([]);
- }
-
- this.each(function() {
- // go in reverse order so anything added to the queue during the loop is ignored
- for ( var i = timers.length - 1; i >= 0; i-- ) {
- if ( timers[i].elem === this ) {
- if (gotoEnd) {
- // force the next step to be the last
- timers[i](true);
- }
-
- timers.splice(i, 1);
- }
- }
- });
-
- // start the next in the queue if the last step wasn't forced
- if ( !gotoEnd ) {
- this.dequeue();
- }
-
- return this;
- }
-
-});
-
-function genFx( type, num ) {
- var obj = {};
-
- jQuery.each( fxAttrs.concat.apply([], fxAttrs.slice(0,num)), function() {
- obj[ this ] = type;
- });
-
- return obj;
-}
-
-// Generate shortcuts for custom animations
-jQuery.each({
- slideDown: genFx("show", 1),
- slideUp: genFx("hide", 1),
- slideToggle: genFx("toggle", 1),
- fadeIn: { opacity: "show" },
- fadeOut: { opacity: "hide" },
- fadeToggle: { opacity: "toggle" }
-}, function( name, props ) {
- jQuery.fn[ name ] = function( speed, easing, callback ) {
- return this.animate( props, speed, easing, callback );
- };
-});
-
-jQuery.extend({
- speed: function( speed, easing, fn ) {
- var opt = speed && typeof speed === "object" ? jQuery.extend({}, speed) : {
- complete: fn || !fn && easing ||
- jQuery.isFunction( speed ) && speed,
- duration: speed,
- easing: fn && easing || easing && !jQuery.isFunction(easing) && easing
- };
-
- opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration :
- opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[opt.duration] : jQuery.fx.speeds._default;
-
- // Queueing
- opt.old = opt.complete;
- opt.complete = function() {
- if ( opt.queue !== false ) {
- jQuery(this).dequeue();
- }
- if ( jQuery.isFunction( opt.old ) ) {
- opt.old.call( this );
- }
- };
-
- return opt;
- },
-
- easing: {
- linear: function( p, n, firstNum, diff ) {
- return firstNum + diff * p;
- },
- swing: function( p, n, firstNum, diff ) {
- return ((-Math.cos(p*Math.PI)/2) + 0.5) * diff + firstNum;
- }
- },
-
- timers: [],
-
- fx: function( elem, options, prop ) {
- this.options = options;
- this.elem = elem;
- this.prop = prop;
-
- if ( !options.orig ) {
- options.orig = {};
- }
- }
-
-});
-
-jQuery.fx.prototype = {
- // Simple function for setting a style value
- update: function() {
- if ( this.options.step ) {
- this.options.step.call( this.elem, this.now, this );
- }
-
- (jQuery.fx.step[this.prop] || jQuery.fx.step._default)( this );
- },
-
- // Get the current size
- cur: function() {
- if ( this.elem[this.prop] != null && (!this.elem.style || this.elem.style[this.prop] == null) ) {
- return this.elem[ this.prop ];
- }
-
- var r = parseFloat( jQuery.css( this.elem, this.prop ) );
- return r && r > -10000 ? r : 0;
- },
-
- // Start an animation from one number to another
- custom: function( from, to, unit ) {
- var self = this,
- fx = jQuery.fx;
-
- this.startTime = jQuery.now();
- this.start = from;
- this.end = to;
- this.unit = unit || this.unit || "px";
- this.now = this.start;
- this.pos = this.state = 0;
-
- function t( gotoEnd ) {
- return self.step(gotoEnd);
- }
-
- t.elem = this.elem;
-
- if ( t() && jQuery.timers.push(t) && !timerId ) {
- timerId = setInterval(fx.tick, fx.interval);
- }
- },
-
- // Simple 'show' function
- show: function() {
- // Remember where we started, so that we can go back to it later
- this.options.orig[this.prop] = jQuery.style( this.elem, this.prop );
- this.options.show = true;
-
- // Begin the animation
- // Make sure that we start at a small width/height to avoid any
- // flash of content
- this.custom(this.prop === "width" || this.prop === "height" ? 1 : 0, this.cur());
-
- // Start by showing the element
- jQuery( this.elem ).show();
- },
-
- // Simple 'hide' function
- hide: function() {
- // Remember where we started, so that we can go back to it later
- this.options.orig[this.prop] = jQuery.style( this.elem, this.prop );
- this.options.hide = true;
-
- // Begin the animation
- this.custom(this.cur(), 0);
- },
-
- // Each step of an animation
- step: function( gotoEnd ) {
- var t = jQuery.now(), done = true;
-
- if ( gotoEnd || t >= this.options.duration + this.startTime ) {
- this.now = this.end;
- this.pos = this.state = 1;
- this.update();
-
- this.options.curAnim[ this.prop ] = true;
-
- for ( var i in this.options.curAnim ) {
- if ( this.options.curAnim[i] !== true ) {
- done = false;
- }
- }
-
- if ( done ) {
- // Reset the overflow
- if ( this.options.overflow != null && !jQuery.support.shrinkWrapBlocks ) {
- var elem = this.elem,
- options = this.options;
-
- jQuery.each( [ "", "X", "Y" ], function (index, value) {
- elem.style[ "overflow" + value ] = options.overflow[index];
- } );
- }
-
- // Hide the element if the "hide" operation was done
- if ( this.options.hide ) {
- jQuery(this.elem).hide();
- }
-
- // Reset the properties, if the item has been hidden or shown
- if ( this.options.hide || this.options.show ) {
- for ( var p in this.options.curAnim ) {
- jQuery.style( this.elem, p, this.options.orig[p] );
- }
- }
-
- // Execute the complete function
- this.options.complete.call( this.elem );
- }
-
- return false;
-
- } else {
- var n = t - this.startTime;
- this.state = n / this.options.duration;
-
- // Perform the easing function, defaults to swing
- var specialEasing = this.options.specialEasing && this.options.specialEasing[this.prop];
- var defaultEasing = this.options.easing || (jQuery.easing.swing ? "swing" : "linear");
- this.pos = jQuery.easing[specialEasing || defaultEasing](this.state, n, 0, 1, this.options.duration);
- this.now = this.start + ((this.end - this.start) * this.pos);
-
- // Perform the next step of the animation
- this.update();
- }
-
- return true;
- }
-};
-
-jQuery.extend( jQuery.fx, {
- tick: function() {
- var timers = jQuery.timers;
-
- for ( var i = 0; i < timers.length; i++ ) {
- if ( !timers[i]() ) {
- timers.splice(i--, 1);
- }
- }
-
- if ( !timers.length ) {
- jQuery.fx.stop();
- }
- },
-
- interval: 13,
-
- stop: function() {
- clearInterval( timerId );
- timerId = null;
- },
-
- speeds: {
- slow: 600,
- fast: 200,
- // Default speed
- _default: 400
- },
-
- step: {
- opacity: function( fx ) {
- jQuery.style( fx.elem, "opacity", fx.now );
- },
-
- _default: function( fx ) {
- if ( fx.elem.style && fx.elem.style[ fx.prop ] != null ) {
- fx.elem.style[ fx.prop ] = (fx.prop === "width" || fx.prop === "height" ? Math.max(0, fx.now) : fx.now) + fx.unit;
- } else {
- fx.elem[ fx.prop ] = fx.now;
- }
- }
- }
-});
-
-if ( jQuery.expr && jQuery.expr.filters ) {
- jQuery.expr.filters.animated = function( elem ) {
- return jQuery.grep(jQuery.timers, function( fn ) {
- return elem === fn.elem;
- }).length;
- };
-}
-
-function defaultDisplay( nodeName ) {
- if ( !elemdisplay[ nodeName ] ) {
- var elem = jQuery("<" + nodeName + ">").appendTo("body"),
- display = elem.css("display");
-
- elem.remove();
-
- if ( display === "none" || display === "" ) {
- display = "block";
- }
-
- elemdisplay[ nodeName ] = display;
- }
-
- return elemdisplay[ nodeName ];
-}
-
-
-
-
-var rtable = /^t(?:able|d|h)$/i,
- rroot = /^(?:body|html)$/i;
-
-if ( "getBoundingClientRect" in document.documentElement ) {
- jQuery.fn.offset = function( options ) {
- var elem = this[0], box;
-
- if ( options ) {
- return this.each(function( i ) {
- jQuery.offset.setOffset( this, options, i );
- });
- }
-
- if ( !elem || !elem.ownerDocument ) {
- return null;
- }
-
- if ( elem === elem.ownerDocument.body ) {
- return jQuery.offset.bodyOffset( elem );
- }
-
- try {
- box = elem.getBoundingClientRect();
- } catch(e) {}
-
- var doc = elem.ownerDocument,
- docElem = doc.documentElement;
-
- // Make sure we're not dealing with a disconnected DOM node
- if ( !box || !jQuery.contains( docElem, elem ) ) {
- return box || { top: 0, left: 0 };
- }
-
- var body = doc.body,
- win = getWindow(doc),
- clientTop = docElem.clientTop || body.clientTop || 0,
- clientLeft = docElem.clientLeft || body.clientLeft || 0,
- scrollTop = (win.pageYOffset || jQuery.support.boxModel && docElem.scrollTop || body.scrollTop ),
- scrollLeft = (win.pageXOffset || jQuery.support.boxModel && docElem.scrollLeft || body.scrollLeft),
- top = box.top + scrollTop - clientTop,
- left = box.left + scrollLeft - clientLeft;
-
- return { top: top, left: left };
- };
-
-} else {
- jQuery.fn.offset = function( options ) {
- var elem = this[0];
-
- if ( options ) {
- return this.each(function( i ) {
- jQuery.offset.setOffset( this, options, i );
- });
- }
-
- if ( !elem || !elem.ownerDocument ) {
- return null;
- }
-
- if ( elem === elem.ownerDocument.body ) {
- return jQuery.offset.bodyOffset( elem );
- }
-
- jQuery.offset.initialize();
-
- var computedStyle,
- offsetParent = elem.offsetParent,
- prevOffsetParent = elem,
- doc = elem.ownerDocument,
- docElem = doc.documentElement,
- body = doc.body,
- defaultView = doc.defaultView,
- prevComputedStyle = defaultView ? defaultView.getComputedStyle( elem, null ) : elem.currentStyle,
- top = elem.offsetTop,
- left = elem.offsetLeft;
-
- while ( (elem = elem.parentNode) && elem !== body && elem !== docElem ) {
- if ( jQuery.offset.supportsFixedPosition && prevComputedStyle.position === "fixed" ) {
- break;
- }
-
- computedStyle = defaultView ? defaultView.getComputedStyle(elem, null) : elem.currentStyle;
- top -= elem.scrollTop;
- left -= elem.scrollLeft;
-
- if ( elem === offsetParent ) {
- top += elem.offsetTop;
- left += elem.offsetLeft;
-
- if ( jQuery.offset.doesNotAddBorder && !(jQuery.offset.doesAddBorderForTableAndCells && rtable.test(elem.nodeName)) ) {
- top += parseFloat( computedStyle.borderTopWidth ) || 0;
- left += parseFloat( computedStyle.borderLeftWidth ) || 0;
- }
-
- prevOffsetParent = offsetParent;
- offsetParent = elem.offsetParent;
- }
-
- if ( jQuery.offset.subtractsBorderForOverflowNotVisible && computedStyle.overflow !== "visible" ) {
- top += parseFloat( computedStyle.borderTopWidth ) || 0;
- left += parseFloat( computedStyle.borderLeftWidth ) || 0;
- }
-
- prevComputedStyle = computedStyle;
- }
-
- if ( prevComputedStyle.position === "relative" || prevComputedStyle.position === "static" ) {
- top += body.offsetTop;
- left += body.offsetLeft;
- }
-
- if ( jQuery.offset.supportsFixedPosition && prevComputedStyle.position === "fixed" ) {
- top += Math.max( docElem.scrollTop, body.scrollTop );
- left += Math.max( docElem.scrollLeft, body.scrollLeft );
- }
-
- return { top: top, left: left };
- };
-}
-
-jQuery.offset = {
- initialize: function() {
- var body = document.body, container = document.createElement("div"), innerDiv, checkDiv, table, td, bodyMarginTop = parseFloat( jQuery.css(body, "marginTop") ) || 0,
- html = "<div style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;'><div></div></div><table style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;' cellpadding='0' cellspacing='0'><tr><td></td></tr></table>";
-
- jQuery.extend( container.style, { position: "absolute", top: 0, left: 0, margin: 0, border: 0, width: "1px", height: "1px", visibility: "hidden" } );
-
- container.innerHTML = html;
- body.insertBefore( container, body.firstChild );
- innerDiv = container.firstChild;
- checkDiv = innerDiv.firstChild;
- td = innerDiv.nextSibling.firstChild.firstChild;
-
- this.doesNotAddBorder = (checkDiv.offsetTop !== 5);
- this.doesAddBorderForTableAndCells = (td.offsetTop === 5);
-
- checkDiv.style.position = "fixed";
- checkDiv.style.top = "20px";
-
- // safari subtracts parent border width here which is 5px
- this.supportsFixedPosition = (checkDiv.offsetTop === 20 || checkDiv.offsetTop === 15);
- checkDiv.style.position = checkDiv.style.top = "";
-
- innerDiv.style.overflow = "hidden";
- innerDiv.style.position = "relative";
-
- this.subtractsBorderForOverflowNotVisible = (checkDiv.offsetTop === -5);
-
- this.doesNotIncludeMarginInBodyOffset = (body.offsetTop !== bodyMarginTop);
-
- body.removeChild( container );
- body = container = innerDiv = checkDiv = table = td = null;
- jQuery.offset.initialize = jQuery.noop;
- },
-
- bodyOffset: function( body ) {
- var top = body.offsetTop,
- left = body.offsetLeft;
-
- jQuery.offset.initialize();
-
- if ( jQuery.offset.doesNotIncludeMarginInBodyOffset ) {
- top += parseFloat( jQuery.css(body, "marginTop") ) || 0;
- left += parseFloat( jQuery.css(body, "marginLeft") ) || 0;
- }
-
- return { top: top, left: left };
- },
-
- setOffset: function( elem, options, i ) {
- var position = jQuery.css( elem, "position" );
-
- // set position first, in-case top/left are set even on static elem
- if ( position === "static" ) {
- elem.style.position = "relative";
- }
-
- var curElem = jQuery( elem ),
- curOffset = curElem.offset(),
- curCSSTop = jQuery.css( elem, "top" ),
- curCSSLeft = jQuery.css( elem, "left" ),
- calculatePosition = (position === "absolute" && jQuery.inArray('auto', [curCSSTop, curCSSLeft]) > -1),
- props = {}, curPosition = {}, curTop, curLeft;
-
- // need to be able to calculate position if either top or left is auto and position is absolute
- if ( calculatePosition ) {
- curPosition = curElem.position();
- }
-
- curTop = calculatePosition ? curPosition.top : parseInt( curCSSTop, 10 ) || 0;
- curLeft = calculatePosition ? curPosition.left : parseInt( curCSSLeft, 10 ) || 0;
-
- if ( jQuery.isFunction( options ) ) {
- options = options.call( elem, i, curOffset );
- }
-
- if (options.top != null) {
- props.top = (options.top - curOffset.top) + curTop;
- }
- if (options.left != null) {
- props.left = (options.left - curOffset.left) + curLeft;
- }
-
- if ( "using" in options ) {
- options.using.call( elem, props );
- } else {
- curElem.css( props );
- }
- }
-};
-
-
-jQuery.fn.extend({
- position: function() {
- if ( !this[0] ) {
- return null;
- }
-
- var elem = this[0],
-
- // Get *real* offsetParent
- offsetParent = this.offsetParent(),
-
- // Get correct offsets
- offset = this.offset(),
- parentOffset = rroot.test(offsetParent[0].nodeName) ? { top: 0, left: 0 } : offsetParent.offset();
-
- // Subtract element margins
- // note: when an element has margin: auto the offsetLeft and marginLeft
- // are the same in Safari causing offset.left to incorrectly be 0
- offset.top -= parseFloat( jQuery.css(elem, "marginTop") ) || 0;
- offset.left -= parseFloat( jQuery.css(elem, "marginLeft") ) || 0;
-
- // Add offsetParent borders
- parentOffset.top += parseFloat( jQuery.css(offsetParent[0], "borderTopWidth") ) || 0;
- parentOffset.left += parseFloat( jQuery.css(offsetParent[0], "borderLeftWidth") ) || 0;
-
- // Subtract the two offsets
- return {
- top: offset.top - parentOffset.top,
- left: offset.left - parentOffset.left
- };
- },
-
- offsetParent: function() {
- return this.map(function() {
- var offsetParent = this.offsetParent || document.body;
- while ( offsetParent && (!rroot.test(offsetParent.nodeName) && jQuery.css(offsetParent, "position") === "static") ) {
- offsetParent = offsetParent.offsetParent;
- }
- return offsetParent;
- });
- }
-});
-
-
-// Create scrollLeft and scrollTop methods
-jQuery.each( ["Left", "Top"], function( i, name ) {
- var method = "scroll" + name;
-
- jQuery.fn[ method ] = function(val) {
- var elem = this[0], win;
-
- if ( !elem ) {
- return null;
- }
-
- if ( val !== undefined ) {
- // Set the scroll offset
- return this.each(function() {
- win = getWindow( this );
-
- if ( win ) {
- win.scrollTo(
- !i ? val : jQuery(win).scrollLeft(),
- i ? val : jQuery(win).scrollTop()
- );
-
- } else {
- this[ method ] = val;
- }
- });
- } else {
- win = getWindow( elem );
-
- // Return the scroll offset
- return win ? ("pageXOffset" in win) ? win[ i ? "pageYOffset" : "pageXOffset" ] :
- jQuery.support.boxModel && win.document.documentElement[ method ] ||
- win.document.body[ method ] :
- elem[ method ];
- }
- };
-});
-
-function getWindow( elem ) {
- return jQuery.isWindow( elem ) ?
- elem :
- elem.nodeType === 9 ?
- elem.defaultView || elem.parentWindow :
- false;
-}
-
-
-
-
-// Create innerHeight, innerWidth, outerHeight and outerWidth methods
-jQuery.each([ "Height", "Width" ], function( i, name ) {
-
- var type = name.toLowerCase();
-
- // innerHeight and innerWidth
- jQuery.fn["inner" + name] = function() {
- return this[0] ?
- parseFloat( jQuery.css( this[0], type, "padding" ) ) :
- null;
- };
-
- // outerHeight and outerWidth
- jQuery.fn["outer" + name] = function( margin ) {
- return this[0] ?
- parseFloat( jQuery.css( this[0], type, margin ? "margin" : "border" ) ) :
- null;
- };
-
- jQuery.fn[ type ] = function( size ) {
- // Get window width or height
- var elem = this[0];
- if ( !elem ) {
- return size == null ? null : this;
- }
-
- if ( jQuery.isFunction( size ) ) {
- return this.each(function( i ) {
- var self = jQuery( this );
- self[ type ]( size.call( this, i, self[ type ]() ) );
- });
- }
-
- if ( jQuery.isWindow( elem ) ) {
- // Everyone else use document.documentElement or document.body depending on Quirks vs Standards mode
- return elem.document.compatMode === "CSS1Compat" && elem.document.documentElement[ "client" + name ] ||
- elem.document.body[ "client" + name ];
-
- // Get document width or height
- } else if ( elem.nodeType === 9 ) {
- // Either scroll[Width/Height] or offset[Width/Height], whichever is greater
- return Math.max(
- elem.documentElement["client" + name],
- elem.body["scroll" + name], elem.documentElement["scroll" + name],
- elem.body["offset" + name], elem.documentElement["offset" + name]
- );
-
- // Get or set width or height on the element
- } else if ( size === undefined ) {
- var orig = jQuery.css( elem, type ),
- ret = parseFloat( orig );
-
- return jQuery.isNaN( ret ) ? orig : ret;
-
- // Set the width or height on the element (default to pixels if value is unitless)
- } else {
- return this.css( type, typeof size === "string" ? size : size + "px" );
- }
- };
-
-});
-
-
-})(window);
13 years, 3 months
[rhq] modules/enterprise
by mazz
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/selenium/Locatable.java | 26 +++++++++-
1 file changed, 25 insertions(+), 1 deletion(-)
New commits:
commit da30a6ee7d9cfaebafed74721d7eebb061c2e114
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Fri Mar 18 11:08:22 2011 -0400
add javadoc
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/selenium/Locatable.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/selenium/Locatable.java
index 1cfe874..50f3766 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/selenium/Locatable.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/selenium/Locatable.java
@@ -1,10 +1,34 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2011 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2, as
+ * published by the Free Software Foundation, and/or the GNU Lesser
+ * General Public License, version 2.1, also as published by the Free
+ * Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License and the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * and the GNU Lesser General Public License along with this program;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
package org.rhq.enterprise.gui.coregui.client.util.selenium;
import org.rhq.enterprise.gui.coregui.client.CoreGUI;
import org.rhq.enterprise.gui.coregui.client.Messages;
/**
- * TODO
+ * Interface to all locatable components.
+ * Implement this to ensure Selenium testability for the implementing component.
*/
public interface Locatable {
13 years, 3 months