[rhq] 2 commits - modules/enterprise
by lkrejci
modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/core/plugin/DatabaseAndFilePluginDeploymentTest.java | 4
modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/test/StandardServerPluginService.java | 74 ++++++++++
2 files changed, 77 insertions(+), 1 deletion(-)
New commits:
commit ce289f2f7798a1f1244aef73c56a5572206ce63a
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Fri Mar 4 15:24:01 2011 +0100
execute the DatabaseAndFilePluginDeploymentTest only after all the tests from plugin.metadata group have been executed, so that the rhq_plugin table is cleaned up.
diff --git a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/core/plugin/DatabaseAndFilePluginDeploymentTest.java b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/core/plugin/DatabaseAndFilePluginDeploymentTest.java
index 3dc168a..75ed400 100644
--- a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/core/plugin/DatabaseAndFilePluginDeploymentTest.java
+++ b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/core/plugin/DatabaseAndFilePluginDeploymentTest.java
@@ -41,7 +41,9 @@ import java.util.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
-@Test
+//make sure we run this after the plugins.metadata tests are done so that
+//the db contents don't interfere
+@Test(dependsOnGroups = "plugins.metadata")
public class DatabaseAndFilePluginDeploymentTest extends AbstractEJB3Test {
private static final String PLUGIN_NAME = "DeployTest"; // as defined in our test descriptors
commit 71803539f68d9ea97680f325aec38391645fce96
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Fri Mar 4 15:22:58 2011 +0100
ok, now the ResourceFactoryManagerTest *really* works.. ;)
diff --git a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/test/StandardServerPluginService.java b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/test/StandardServerPluginService.java
index a5ac8df..d17981c 100644
--- a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/test/StandardServerPluginService.java
+++ b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/test/StandardServerPluginService.java
@@ -19,7 +19,25 @@
package org.rhq.enterprise.server.test;
+import java.io.File;
+import java.lang.reflect.Constructor;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.rhq.enterprise.server.plugin.pc.AbstractTypeServerPluginContainer;
+import org.rhq.enterprise.server.plugin.pc.MasterServerPluginContainer;
+import org.rhq.enterprise.server.plugin.pc.MasterServerPluginContainerConfiguration;
import org.rhq.enterprise.server.plugin.pc.ServerPluginService;
+import org.rhq.enterprise.server.plugin.pc.alert.AlertServerPluginContainer;
+import org.rhq.enterprise.server.plugin.pc.bundle.BundleServerPluginContainer;
+import org.rhq.enterprise.server.plugin.pc.content.ContentServerPluginContainer;
+import org.rhq.enterprise.server.plugin.pc.content.PackageTypeServerPluginContainer;
+import org.rhq.enterprise.server.plugin.pc.entitlement.EntitlementServerPluginContainer;
+import org.rhq.enterprise.server.plugin.pc.generic.GenericServerPluginContainer;
+import org.rhq.enterprise.server.plugin.pc.perspective.PerspectiveServerPluginContainer;
/**
* An MBean to use as a ServerPluginService for tests that actually don't care
@@ -30,4 +48,60 @@ import org.rhq.enterprise.server.plugin.pc.ServerPluginService;
*/
public class StandardServerPluginService extends ServerPluginService implements StandardServerPluginServiceMBean {
+ private static final Log LOG = LogFactory.getLog(StandardServerPluginService.class);
+
+ public static class TestMasterServerPluginContainer extends MasterServerPluginContainer {
+ private List<AbstractTypeServerPluginContainer> serverPluginContainers = new ArrayList<AbstractTypeServerPluginContainer>();
+
+ public TestMasterServerPluginContainer(
+ List<Class<? extends AbstractTypeServerPluginContainer>> pluginContainerClasses) {
+
+ for (Class<? extends AbstractTypeServerPluginContainer> cls : pluginContainerClasses) {
+ try {
+ Constructor<? extends AbstractTypeServerPluginContainer> ctor = cls
+ .getConstructor(MasterServerPluginContainer.class);
+ AbstractTypeServerPluginContainer container = ctor.newInstance(this);
+ serverPluginContainers.add(container);
+ } catch (Exception e) {
+ LOG.error("Failed to instantiate server plugin container class: " + cls.getName(), e);
+ }
+ }
+ }
+
+ @Override
+ protected List<AbstractTypeServerPluginContainer> createPluginContainers() {
+ return serverPluginContainers;
+ }
+ }
+
+ // public so tests can directly set these
+ public TestMasterServerPluginContainer master;
+ public MasterServerPluginContainerConfiguration masterConfig;
+
+ /**
+ * This list contains all the standard server plugin container classes by default.
+ * Modify it before the master plugin container is started, if you don't want
+ * some of these deployed or if you want to supply a custom one tailored for your test.
+ */
+ public List<Class<? extends AbstractTypeServerPluginContainer>> pluginContainerClasses;
+
+ public StandardServerPluginService() {
+ File dir = new File(System.getProperty("java.io.tmpdir"), "test-server-plugins");
+ this.masterConfig = new MasterServerPluginContainerConfiguration(dir, dir, dir, null);
+ pluginContainerClasses = new ArrayList<Class<? extends AbstractTypeServerPluginContainer>>();
+ pluginContainerClasses.add(AlertServerPluginContainer.class);
+ pluginContainerClasses.add(BundleServerPluginContainer.class);
+ pluginContainerClasses.add(ContentServerPluginContainer.class);
+ pluginContainerClasses.add(EntitlementServerPluginContainer.class);
+ pluginContainerClasses.add(GenericServerPluginContainer.class);
+ pluginContainerClasses.add(PackageTypeServerPluginContainer.class);
+ pluginContainerClasses.add(PerspectiveServerPluginContainer.class);
+ }
+
+ @Override
+ protected MasterServerPluginContainer createMasterPluginContainer() {
+ this.master = new TestMasterServerPluginContainer(pluginContainerClasses);
+ this.master.initialize(this.masterConfig);
+ return this.master;
+ }
}
13 years, 2 months
[rhq] modules/enterprise
by Heiko W. Rupp
modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_de.properties | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
New commits:
commit 175322392406028da81d6b35be429150f0cbd716
Author: Heiko W. Rupp <hwr(a)redhat.com>
Date: Fri Mar 4 14:49:45 2011 +0100
Fix two translation properties, which were missing placeholders
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 8e19922..22e239a 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
@@ -1300,8 +1300,8 @@ view_resourceResourceGroupList_message_updateSuccess = Group membership updated
#-------------------------------
view_configurationDetails_noPermission = You do not have permission to edit this Resource''s configuration.~
view_configurationDetails_error_updateFailure = Konnte die Konfiguration nicht aktualisieren
-view_configurationDetails_messageConcise = Konfiguration aktualisiert
-view_configurationDetails_messageDetailed = Konfiguration der Ressource [{0}] aktualisiert.
+view_configurationDetails_messageConcise = Konfiguration aktualisiert - aktuelle Version is {0}
+view_configurationDetails_messageDetailed = Konfiguration der Ressource [{1}] aktualisiert auf Version [{0}].
view_configurationDetails_allPropertiesValid = All configuration properties have valid values, so the configuration can now be saved.~
view_configurationDetails_somePropertiesInvalid = The following configuration properties have invalid values: {0}. The values must be corrected before the configuration can be saved.~
13 years, 2 months
[rhq] modules/enterprise
by lkrejci
modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/bundle/TestBundleServerPluginService.java | 4 +
modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/resource/test/ResourceFactoryManagerBeanTest.java | 8 ++
modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/test/StandardServerPluginService.java | 33 ++++++++++
modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/test/StandardServerPluginServiceMBean.java | 31 +++++++++
4 files changed, 76 insertions(+)
New commits:
commit bdcff81c5db08b376358fe4467f80683f8b594f1
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Fri Mar 4 14:11:17 2011 +0100
Fixing the ResourceFactoryManagerBeanTest and the bundle tests by correctly initializing the server plugin master container. Whenever we create a package, we need a package type plugin container initialized now.
diff --git a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/bundle/TestBundleServerPluginService.java b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/bundle/TestBundleServerPluginService.java
index cb3f16e..61c53d3 100644
--- a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/bundle/TestBundleServerPluginService.java
+++ b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/bundle/TestBundleServerPluginService.java
@@ -49,6 +49,7 @@ import org.rhq.enterprise.server.plugin.pc.bundle.BundleServerPluginFacet;
import org.rhq.enterprise.server.plugin.pc.bundle.BundleServerPluginManager;
import org.rhq.enterprise.server.plugin.pc.content.ContentServerPluginContainer;
import org.rhq.enterprise.server.plugin.pc.content.ContentServerPluginManager;
+import org.rhq.enterprise.server.plugin.pc.content.PackageTypeServerPluginContainer;
import org.rhq.enterprise.server.xmlschema.ServerPluginDescriptorMetadataParser;
import org.rhq.enterprise.server.xmlschema.generated.serverplugin.ServerPluginDescriptorType;
@@ -88,6 +89,9 @@ public class TestBundleServerPluginService extends ServerPluginService implement
bundlePC = new TestBundleServerPluginContainer(this);
pcs.add(bundlePC);
pcs.add(new TestContentServerPluginContainer(this));
+
+ //needed internally by the server, so let's provide the standard impl.
+ pcs.add(new PackageTypeServerPluginContainer(this));
return pcs;
}
diff --git a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/resource/test/ResourceFactoryManagerBeanTest.java b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/resource/test/ResourceFactoryManagerBeanTest.java
index 2525cdb..aa30bf5 100644
--- a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/resource/test/ResourceFactoryManagerBeanTest.java
+++ b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/resource/test/ResourceFactoryManagerBeanTest.java
@@ -55,9 +55,11 @@ import org.rhq.core.domain.resource.ResourceCategory;
import org.rhq.core.domain.resource.ResourceType;
import org.rhq.core.domain.util.PageControl;
import org.rhq.core.domain.util.PageList;
+import org.rhq.enterprise.server.plugin.pc.ServerPluginService;
import org.rhq.enterprise.server.resource.ResourceFactoryManagerLocal;
import org.rhq.enterprise.server.resource.ResourceManagerLocal;
import org.rhq.enterprise.server.test.AbstractEJB3Test;
+import org.rhq.enterprise.server.test.StandardServerPluginService;
import org.rhq.enterprise.server.test.TestServerCommunicationsService;
import org.rhq.enterprise.server.util.LookupUtil;
@@ -92,12 +94,18 @@ public class ResourceFactoryManagerBeanTest extends AbstractEJB3Test {
prepareScheduler();
TestServerCommunicationsService agentServiceContainer = prepareForTestAgents();
agentServiceContainer.resourceFactoryService = mockAgentService;
+
+ //the server plugins are in play when package types are involved
+ StandardServerPluginService serverPluginService = new StandardServerPluginService();
+ prepareCustomServerPluginService(serverPluginService);
+ serverPluginService.startMasterPluginContainer();
}
@AfterClass
public void teardownAfterClass() throws Exception {
unprepareForTestAgents();
unprepareScheduler();
+ unprepareServerPluginService();
}
@BeforeMethod
diff --git a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/test/StandardServerPluginService.java b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/test/StandardServerPluginService.java
new file mode 100644
index 0000000..a5ac8df
--- /dev/null
+++ b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/test/StandardServerPluginService.java
@@ -0,0 +1,33 @@
+/*
+ * 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 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.server.test;
+
+import org.rhq.enterprise.server.plugin.pc.ServerPluginService;
+
+/**
+ * An MBean to use as a ServerPluginService for tests that actually don't care
+ * about the server plugin services but need the server to have the server plugin
+ * infrastructure started up.
+ *
+ * @author Lukas Krejci
+ */
+public class StandardServerPluginService extends ServerPluginService implements StandardServerPluginServiceMBean {
+
+}
diff --git a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/test/StandardServerPluginServiceMBean.java b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/test/StandardServerPluginServiceMBean.java
new file mode 100644
index 0000000..232ff17
--- /dev/null
+++ b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/test/StandardServerPluginServiceMBean.java
@@ -0,0 +1,31 @@
+/*
+ * 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 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.server.test;
+
+import org.rhq.enterprise.server.plugin.pc.ServerPluginServiceManagement;
+
+/**
+ * A generic MBean interface for tests that need a ServerPluginService setup.
+ *
+ * @author Lukas Krejci
+ */
+public interface StandardServerPluginServiceMBean extends ServerPluginServiceManagement {
+
+}
13 years, 2 months
[rhq] modules/enterprise
by Heiko W. Rupp
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertDefinitionManagerBean.java | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
New commits:
commit 30c2b6fd04e6db39ef219467b77737c2a4c94403
Author: Heiko W. Rupp <hwr(a)redhat.com>
Date: Fri Mar 4 11:53:06 2011 +0100
Prevent an NPE if no Description is set.
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertDefinitionManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertDefinitionManagerBean.java
index 84e6b8a..c633ed5 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertDefinitionManagerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertDefinitionManagerBean.java
@@ -78,7 +78,7 @@ public class AlertDefinitionManagerBean implements AlertDefinitionManagerLocal,
private AuthorizationManagerLocal authorizationManager;
@EJB
private AlertDefinitionManagerLocal alertDefinitionManager;
-
+
@EJB
@IgnoreDependency
private AlertManagerLocal alertManager;
@@ -89,7 +89,7 @@ public class AlertDefinitionManagerBean implements AlertDefinitionManagerLocal,
@EJB
@IgnoreDependency
private AlertNotificationManagerLocal alertNotificationManager;
-
+
private boolean checkViewPermission(Subject subject, AlertDefinition alertDefinition) {
if (alertDefinition.getResourceType() != null) { // an alert template
return authorizationManager.hasGlobalPermission(subject, Permission.MANAGE_SETTINGS);
@@ -600,7 +600,7 @@ public class AlertDefinitionManagerBean implements AlertDefinitionManagerLocal,
private void checkAlertDefinition(Subject subject, AlertDefinition alertDefinition, Integer resourceId)
throws InvalidAlertDefinitionException {
// if someone enters a really long description, we need to truncate it - the column is only 250 chars
- if (alertDefinition.getDescription().length() > 250) {
+ if (alertDefinition.getDescription()!=null && alertDefinition.getDescription().length() > 250) {
alertDefinition.setDescription(alertDefinition.getDescription().substring(0, 250));
}
@@ -623,8 +623,8 @@ public class AlertDefinitionManagerBean implements AlertDefinitionManagerLocal,
+ "' is a trending metric, and thus will never have baselines calculated for it.");
}
}
- }
-
+ }
+
if (!alertNotificationManager.finalizeNotifications(subject, alertDefinition.getAlertNotifications())) {
throw new InvalidAlertDefinitionException("Some of the notifications failed to validate.");
}
13 years, 2 months
[rhq] modules/core
by lkrejci
modules/core/domain/src/main/java/org/rhq/core/domain/util/OSGiVersionComparator.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
New commits:
commit 7155470bef5164e4bf162fbb840abd5005bcf221
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Fri Mar 4 10:18:49 2011 +0100
OSGiVersionComparator works again.
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/util/OSGiVersionComparator.java b/modules/core/domain/src/main/java/org/rhq/core/domain/util/OSGiVersionComparator.java
index 70cdc74..a8fb83f 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/util/OSGiVersionComparator.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/util/OSGiVersionComparator.java
@@ -50,7 +50,7 @@ public class OSGiVersionComparator implements Comparator<String> {
if (ver2.getQualifier() == null) {
result = 1;
} else {
- ver1.getQualifier().compareTo(ver2.getQualifier());
+ result = ver1.getQualifier().compareTo(ver2.getQualifier());
}
} else {
if (ver2.getQualifier() == null) {
13 years, 2 months
[rhq] modules/core modules/enterprise
by ips
modules/core/domain/src/main/java/org/rhq/core/domain/configuration/PropertyList.java | 8
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/ImageManager.java | 9
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/configuration/ConfigurationEditor.java | 111 ++++------
modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages.properties | 2
4 files changed, 63 insertions(+), 67 deletions(-)
New commits:
commit f86ed171f4f2de439792b667caf34c390c45c475
Author: Ian Springer <ian.springer(a)redhat.com>
Date: Thu Mar 3 16:45:22 2011 -0500
fix various bugs related to open-maps in config editor; fix PropertyList entity so order of list elements is maintained when a list prop is loaded from the DB
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/PropertyList.java b/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/PropertyList.java
index a5f7e2a..5b1f40a 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/PropertyList.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/PropertyList.java
@@ -1,6 +1,6 @@
/*
* RHQ Management Platform
- * Copyright (C) 2005-2008 Red Hat, Inc.
+ * Copyright (C) 2005-2011 Red Hat, Inc.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
@@ -29,6 +29,7 @@ import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.OneToMany;
+import javax.persistence.OrderBy;
import javax.persistence.Transient;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
@@ -61,7 +62,10 @@ public class PropertyList extends Property {
// CascadeType.REMOVE has been omitted, the cascade delete has been moved to the data model for performance
@Cascade( { CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH, CascadeType.DELETE_ORPHAN })
@OneToMany(mappedBy = "parentList", targetEntity = Property.class, fetch = FetchType.EAGER)
- //@IndexColumn(name = "list_index") TODO GH: This seems broken
+ // Order by primary key which will also put the list elements in chronological order.
+ // Note, if we decide at some point to add support in the GUI for reordering list elements, we'll
+ // need to add a new ORDER column and order by that.
+ @OrderBy
private List<Property> list = new ArrayList<Property>();
@Transient
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/ImageManager.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/ImageManager.java
index 1aad4e6..0cd64b2 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/ImageManager.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/ImageManager.java
@@ -36,7 +36,7 @@ public class ImageManager {
}
/**
- * Returns a generic edit icon.
+ * Returns a generic view icon.
*/
public static String getViewIcon() {
return "[SKIN]/actions/view.png";
@@ -50,6 +50,13 @@ public class ImageManager {
}
/**
+ * Returns a generic remove icon.
+ */
+ public static String getRemoveIcon() {
+ return "[SKIN]/actions/remove.png";
+ }
+
+ /**
* Returns a generic approve (aka "ok") icon.
*/
public static String getApproveIcon() {
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/configuration/ConfigurationEditor.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/configuration/ConfigurationEditor.java
index 993f303..a63e70f 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/configuration/ConfigurationEditor.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/configuration/ConfigurationEditor.java
@@ -33,8 +33,8 @@ import java.util.Set;
import com.allen_sauer.gwt.log.client.Log;
import com.google.gwt.user.client.rpc.AsyncCallback;
-import com.smartgwt.client.data.Record;
import com.smartgwt.client.types.Alignment;
+import com.smartgwt.client.types.AutoFitWidthApproach;
import com.smartgwt.client.types.ListGridFieldType;
import com.smartgwt.client.types.MultipleAppearance;
import com.smartgwt.client.types.Overflow;
@@ -163,8 +163,6 @@ public class ConfigurationEditor extends LocatableVLayout {
private boolean readOnly = false;
private Set<String> invalidPropertyNames = new HashSet<String>();
private Set<PropertyValueChangeListener> propertyValueChangeListeners = new HashSet<PropertyValueChangeListener>();
- private boolean loaded;
- private boolean reloadable;
public static enum ConfigType {
plugin, resource
@@ -183,18 +181,23 @@ public class ConfigurationEditor extends LocatableVLayout {
private LoadHandler loadHandler = null;
- public ConfigurationEditor(String locatorId, int resourceId, int resourceTypeId, ConfigType configType) {
+ private ConfigurationEditor(String locatorId) {
super(locatorId);
+
+ setOverflow(Overflow.AUTO);
+ }
+
+ public ConfigurationEditor(String locatorId, int resourceId, int resourceTypeId, ConfigType configType) {
+ this(locatorId);
+
this.resourceId = resourceId;
this.resourceTypeId = resourceTypeId;
this.configType = configType;
- setOverflow(Overflow.AUTO);
- this.reloadable = true;
}
public ConfigurationEditor(String locatorId, ConfigurationDefinition configurationDefinition,
Configuration configuration) {
- super(locatorId);
+ this(locatorId);
if (configuration == null) {
throw new IllegalArgumentException("Null configuration.");
@@ -343,16 +346,18 @@ public class ConfigurationEditor extends LocatableVLayout {
}
public void reload() {
- if (this.loaded && !this.reloadable) {
+ /*if (this.loaded && !this.reloadable) {
return;
- }
+ }*/
- if (configurationDefinition == null || configuration == null) {
+ if (this.configurationDefinition == null || this.configuration == null) {
// Wait for both to load.
return;
}
- originalConfiguration = configuration.deepCopy();
+ if (this.originalConfiguration == null) {
+ this.originalConfiguration = configuration.deepCopy();
+ }
for (Canvas childCanvas : getChildren()) {
childCanvas.destroy();
@@ -375,7 +380,6 @@ public class ConfigurationEditor extends LocatableVLayout {
}
this.markForRedraw();
- this.loaded = true;
}
public void reset() {
@@ -384,7 +388,6 @@ public class ConfigurationEditor extends LocatableVLayout {
}
protected LocatableVLayout buildStructuredPane() {
-
LocatableVLayout layout = new LocatableVLayout(extendLocatorId("Structured"));
List<PropertyGroupDefinition> groupDefinitions = configurationDefinition.getGroupDefinitions();
@@ -491,7 +494,7 @@ public class ConfigurationEditor extends LocatableVLayout {
return section;
}
- protected DynamicForm buildPropertiesForm(String locatorId, Collection<PropertyDefinition> propertyDefinitions,
+ protected LocatableDynamicForm buildPropertiesForm(String locatorId, Collection<PropertyDefinition> propertyDefinitions,
AbstractPropertyMap propertyMap) {
LocatableDynamicForm form = new LocatableDynamicForm(locatorId);
@@ -693,59 +696,31 @@ public class ConfigurationEditor extends LocatableVLayout {
PropertyDefinitionMap propertyDefinitionMapClone = new PropertyDefinitionMap(propertyDefinitionMap
.getName(), propertyDefinitionMap.getDescription(), propertyDefinitionMap.isRequired());
propertyDefinitionMapClone.setConfigurationDefinition(propertyDefinitionMap.getConfigurationDefinition());
+ propertyDefinitionMapClone.setReadOnly(propertyDefinitionMap.isReadOnly());
addMemberPropertyDefinitionsToDynamicPropertyMap(propertyDefinitionMapClone, propertyMap);
propertyDefinitionMap = propertyDefinitionMapClone;
}
- VLayout layout = new VLayout();
+ LocatableVLayout layout = new LocatableVLayout(parentLocatorId + "_Layout");
final PropertyDefinitionMap propertyDefinitionMapFinal = propertyDefinitionMap;
- Canvas valuesCanvas = buildPropertiesForm(parentLocatorId, propertyDefinitionMapFinal.getPropertyDefinitions()
- .values(), propertyMap);
+ LocatableDynamicForm valuesCanvas = buildPropertiesForm(layout.getLocatorId(),
+ propertyDefinitionMapFinal.getPropertyDefinitions().values(), propertyMap);
layout.addMember(valuesCanvas);
if (isDynamic && !isReadOnly(propertyDefinitionMap, propertyMap)) {
// Map is not read-only - add footer with New and Delete buttons to allow user to add or remove members.
- ToolStrip buttonBar = new ToolStrip();
+ LocatableToolStrip buttonBar = new LocatableToolStrip(layout.extendLocatorId("ButtonBar"));
buttonBar.setPadding(5);
buttonBar.setWidth100();
buttonBar.setMembersMargin(15);
layout.addMember(buttonBar);
- /*final IButton deleteButton = new LocatableIButton(extendLocatorId(propertyMap.getName()), "Delete");
- deleteButton.setDisabled(true);
- deleteButton.addClickHandler(new com.smartgwt.client.widgets.events.ClickHandler() {
- public void onClick(ClickEvent clickEvent) {
- final ListGridRecord[] selectedRecords = propertyGrid.getSelection();
- String noun = (selectedRecords.length == 1) ? "property" : "properties";
- String message = "Are you sure you want to delete the selected" + noun + "?";
- SC.ask(message, new BooleanCallback() {
- public void execute(Boolean confirmed) {
- if (confirmed) {
- for (ListGridRecord selectedRecord : selectedRecords) {
- propertyGrid.removeData(selectedRecord);
- String propertyName = selectedRecord.getAttribute("Name");
- propertyMap.getMap().remove(propertyName);
- }
- }
- }
- });
- }
- });
- footer.addMember(deleteButton);
-
- propertyGrid.addSelectionChangedHandler(new SelectionChangedHandler() {
- public void onSelectionChanged(SelectionEvent selectionEvent) {
- int count = propertyGrid.getSelection().length;
- deleteButton.setDisabled(count < 1);
- }
- });*/
-
- final IButton newButton = new LocatableIButton(extendLocatorId(propertyMap.getName()), MSG
+ final IButton newButton = new LocatableIButton(buttonBar.extendLocatorId("New"), MSG
.common_button_new());
+ newButton.setIcon(Window.getImgURL("[SKIN]/actions/add.png"));
newButton.addClickHandler(new com.smartgwt.client.widgets.events.ClickHandler() {
public void onClick(ClickEvent clickEvent) {
SC.askforValue(MSG.view_configEdit_enterPropName(), new ValueCallback() {
- @Override
public void execute(String propertyName) {
if (propertyMap.get(propertyName) != null) {
CoreGUI.getMessageCenter().notify(
@@ -768,9 +743,17 @@ public class ConfigurationEditor extends LocatableVLayout {
});
buttonBar.addMember(newButton);
- DynamicForm deleteForm = new DynamicForm();
+ HLayout spacer = new HLayout();
+ spacer.setWidth(12);
+ buttonBar.addMember(spacer);
+
+ LocatableHLayout deleteControlsLayout = new LocatableHLayout(buttonBar.extendLocatorId("DeleteControls"));
+ deleteControlsLayout.setMargin(3);
+ deleteControlsLayout.setMembersMargin(3);
+ LocatableDynamicForm deleteForm = new LocatableDynamicForm(deleteControlsLayout.extendLocatorId("Form"));
deleteForm.setNumCols(3);
- buttonBar.addMember(deleteForm);
+ deleteControlsLayout.addMember(deleteForm);
+ buttonBar.addMember(deleteControlsLayout);
final SelectItem selectItem = new SelectItem();
selectItem.setValueMap(propertyDefinitionMap.getPropertyDefinitions().keySet().toArray(
@@ -779,12 +762,11 @@ public class ConfigurationEditor extends LocatableVLayout {
selectItem.setMultipleAppearance(MultipleAppearance.GRID);
selectItem.setTitle(MSG.common_button_delete());
- final ButtonItem okButtonItem = new ButtonItem();
- okButtonItem.setTitle(MSG.common_button_ok());
- okButtonItem.setDisabled(true);
- okButtonItem.setEndRow(true);
- okButtonItem.addClickHandler(new com.smartgwt.client.widgets.form.fields.events.ClickHandler() {
- public void onClick(com.smartgwt.client.widgets.form.fields.events.ClickEvent clickEvent) {
+ final LocatableIButton okButton = new LocatableIButton(buttonBar.extendLocatorId("OK"));
+ okButton.setTitle(MSG.common_button_ok());
+ okButton.setDisabled(true);
+ okButton.addClickHandler(new com.smartgwt.client.widgets.events.ClickHandler() {
+ public void onClick(ClickEvent clickEvent) {
SC.confirm(MSG.view_configEdit_confirm_1(), new BooleanCallback() {
@Override
public void execute(Boolean confirmed) {
@@ -808,6 +790,7 @@ public class ConfigurationEditor extends LocatableVLayout {
});
}
});
+ deleteControlsLayout.addMember(okButton);
selectItem.addChangedHandler(new ChangedHandler() {
@Override
@@ -816,12 +799,12 @@ public class ConfigurationEditor extends LocatableVLayout {
if (value != null) {
String stringValue = value.toString();
String[] memberPropertyNames = stringValue.split(",");
- okButtonItem.setDisabled(memberPropertyNames.length == 0);
+ okButton.setDisabled(memberPropertyNames.length == 0);
}
}
});
- deleteForm.setFields(selectItem, okButtonItem);
+ deleteForm.setFields(selectItem);
}
CanvasItem canvasItem = buildComplexPropertyField(layout);
@@ -841,7 +824,7 @@ public class ConfigurationEditor extends LocatableVLayout {
parentMap.getMap().remove(propertySimple.getName());
}
- private boolean isDynamic(PropertyDefinitionMap propertyDefinitionMap) {
+ private static boolean isDynamic(PropertyDefinitionMap propertyDefinitionMap) {
Map<String, PropertyDefinition> memberPropertyDefinitions = propertyDefinitionMap.getPropertyDefinitions();
return memberPropertyDefinitions == null || memberPropertyDefinitions.isEmpty();
}
@@ -876,6 +859,9 @@ public class ConfigurationEditor extends LocatableVLayout {
summaryTable.setBodyOverflow(Overflow.VISIBLE);
summaryTable.setOverflow(Overflow.VISIBLE);
summaryTable.setWidth100();
+ summaryTable.setAutoFitFieldWidths(true);
+ summaryTable.setAutoFitWidthApproach(AutoFitWidthApproach.BOTH);
+ summaryTable.setRecordEnabledProperty(null);
List<ListGridField> fieldsList = new ArrayList<ListGridField>();
final List<PropertyDefinition> propertyDefinitions = new ArrayList<PropertyDefinition>(memberPropertyDefinitionMap
@@ -923,8 +909,7 @@ public class ConfigurationEditor extends LocatableVLayout {
if (!(readOnly || propertyDefinitionList.isReadOnly())) {
ListGridField removeField = new ListGridField("remove", 20);
removeField.setType(ListGridFieldType.ICON);
- // removeField.setIcon(Window.getImgURL("[SKIN]/actions/remove.png")); //"/images/tbb_delete.gif");
- removeField.setCellIcon(Window.getImgURL("[SKIN]/actions/remove.png")); //"/images/tbb_delete.gif");
+ removeField.setCellIcon(Window.getImgURL(ImageManager.getRemoveIcon()));
removeField.setCanEdit(false);
removeField.setCanFilter(true);
removeField.setFilterEditorType(new SpacerItem());
@@ -1505,7 +1490,7 @@ public class ConfigurationEditor extends LocatableVLayout {
if (newRow) {
try {
list.add(workingMap);
- int index = list.getList().size();
+ int index = list.getList().size() - 1;
PropertyMapListGridRecord record = new PropertyMapListGridRecord(workingMap, index,
memberDefinitions);
summaryTable.addData(record);
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 d359a5b..9bf2f0f 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
@@ -1838,7 +1838,7 @@ view_resourceResourceGroupList_message_updateSuccess = Group membership updated
#-------------------------------
view_configurationDetails_noPermission = You do not have permission to edit this Resource''s configuration.
view_configurationDetails_error_updateFailure = Failed to update configuration.
-view_configurationDetails_messageConcise = Configuration updated - current version is {0}).
+view_configurationDetails_messageConcise = Configuration updated - current version is {0}.
view_configurationDetails_messageDetailed = Configuration updated to version {0} for Resource [{1}].
view_configurationDetails_allPropertiesValid = All configuration properties have valid values, so the configuration can now be saved.
view_configurationDetails_somePropertiesInvalid = The following configuration properties have invalid values: {0}. The values must be corrected before the configuration can be saved.
13 years, 2 months
[rhq] 3 commits - modules/enterprise pom.xml
by ips
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/users/UsersDataSource.java | 3 ++-
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/configuration/PropertyMapListGridRecord.java | 2 ++
pom.xml | 2 +-
3 files changed, 5 insertions(+), 2 deletions(-)
New commits:
commit 27d7edd1fddecd408e753b670249506694b7ba83
Author: Ian Springer <ian.springer(a)redhat.com>
Date: Thu Mar 3 12:02:22 2011 -0500
add javadoc
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/configuration/PropertyMapListGridRecord.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/configuration/PropertyMapListGridRecord.java
index 9c24a57..843c15d 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/configuration/PropertyMapListGridRecord.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/configuration/PropertyMapListGridRecord.java
@@ -9,7 +9,9 @@ import org.rhq.core.domain.configuration.definition.PropertyDefinitionSimple;
import java.util.List;
/**
+ * A ListGridRecord representation of an RHQ PropertyMap.
*
+ * @author Ian Springer
*/
public class PropertyMapListGridRecord extends ListGridRecord {
commit 9f3eac44f731fc331ecc21f63599d8e7e934d7bb
Author: Ian Springer <ian.springer(a)redhat.com>
Date: Thu Mar 3 12:02:02 2011 -0500
upgrade ojdbc5 (Oracle JDBC driver) dep from 11.2.0.1.0 to 11.2.0.2.0
diff --git a/pom.xml b/pom.xml
index 7c07d11..97e45f7 100644
--- a/pom.xml
+++ b/pom.xml
@@ -84,7 +84,7 @@
<jaxb-impl.version>2.1.9</jaxb-impl.version>
<jsf-api.version>1.2_14</jsf-api.version>
<jsf-impl.version>1.2_14</jsf-impl.version>
- <ojdbc5.version>11.2.0.1.0</ojdbc5.version>
+ <ojdbc5.version>11.2.0.2.0</ojdbc5.version>
<ems.version>1.2.15.1</ems.version>
<postgresql.version>9.0-801.jdbc4</postgresql.version>
<h2.version>1.2.139</h2.version>
commit 4c250b29e7c36a2cd72a14e17998fb7f50e2f284
Author: Ian Springer <ian.springer(a)redhat.com>
Date: Thu Mar 3 12:00:57 2011 -0500
make email-address validation regexp accept addresses with a non-qualified hostname portion (e.g. root@localhost) (https://bugzilla.redhat.com/show_bug.cgi?id=681621)
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/users/UsersDataSource.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/users/UsersDataSource.java
index fbb8a26..5b76b5e 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/users/UsersDataSource.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/users/UsersDataSource.java
@@ -54,7 +54,8 @@ import org.rhq.enterprise.gui.coregui.client.util.message.Message;
public class UsersDataSource extends RPCDataSource<Subject> {
private static UsersDataSource INSTANCE;
- private static final String EMAIL_ADDRESS_REGEXP = "^([a-zA-Z0-9_.\\-+])+(a)(([a-zA-Z0-9\\-])+\\.)+[a-zA-Z0-9]{2,4}$";
+
+ private static final String EMAIL_ADDRESS_REGEXP = "^([a-zA-Z0-9_.\\-+])+(a)([a-zA-Z0-9\\-])+(\\.([a-zA-Z0-9\\-])+)*$";
private static final String MASKED_PASSWORD_VALUE = "XXXXXXXX";
public static abstract class Field {
13 years, 2 months
[rhq] modules/enterprise
by Heiko W. Rupp
modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages.properties | 18 +++++-----
modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_de.properties | 18 ++++++++++
2 files changed, 27 insertions(+), 9 deletions(-)
New commits:
commit 332d99ae9d418c62c81c3cd44464707253d3fdb4
Author: Heiko W. Rupp <hwr(a)redhat.com>
Date: Thu Mar 3 17:39:34 2011 +0100
Some more translations.
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 a0d6421..d359a5b 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
@@ -117,7 +117,7 @@ common_title_generalProp = General Properties
common_title_group = Group
common_title_groups = Groups
common_title_group_def_total = Group Definition Total
-common_title_icon =
+common_title_icon =
common_title_id = ID
common_title_id_parent = Parent ID
common_title_info = Info
@@ -719,7 +719,7 @@ view_admin_systemSettings_serverDetails_buildNumber = Build Number
view_admin_systemSettings_serverDetails_tz = Server Time Zone
view_admin_systemSettings_serverDetails_time = Server Local Time
view_admin_systemSettings_serverDetails_installDir = Server Installation Directory
-view_admin_systemSettings_serverDetails_dbUrl = Database Connection URL
+view_admin_systemSettings_serverDetails_dbUrl = Database Connection URL
view_admin_systemSettings_serverDetails_dbName = Database Product Name
view_admin_systemSettings_serverDetails_dbVersion = Database Product Version
view_admin_systemSettings_serverDetails_dbDriverName = Database Driver Name
@@ -760,7 +760,7 @@ view_admin_systemSettings_LDAPUrl_name = LDAP URL
view_admin_systemSettings_LDAPUrl_desc = URL to the LDAP Server
view_admin_systemSettings_LDAPProtocol_name = SSL
view_admin_systemSettings_LDAPProtocol_desc = Should communication with the LDAP server be done over SSL?
-view_admin_systemSettings_LDAPLoginProperty_name = Login Property
+view_admin_systemSettings_LDAPLoginProperty_name = Login Property
view_admin_systemSettings_LDAPLoginProperty_desc = The LDAP property that contains the user name. Defaults to "cn". If multiple matches are found, the first entry found is used.
view_admin_systemSettings_LDAPFilter_name = Search Filter
view_admin_systemSettings_LDAPFilter_desc = Any additional filters to apply when doing the LDAP search. This is useful if the population to authenticate can be identified via a given LDAP property, e.g. RHQUser=true
@@ -1009,7 +1009,7 @@ view_alert_definition_notification_cliScript_editor_thisUser = Myself
view_alert_definition_notification_cliScript_editor_anotherUser = Another User
view_alert_definition_notification_cliScript_editor_verifyAuthentication = Verify
view_alert_definition_notification_cliScript_editor_loadFailed = Loading the CLI Notification Editor Failed.
-view_alert_definition_notification_cliScript_editor_selectRepoFirst = Select a repo first.
+view_alert_definition_notification_cliScript_editor_selectRepoFirst = Select a repository first.
view_alert_definition_notification_cliScript_editor_existingScript = Existing Script
view_alert_definition_notification_cliScript_editor_uploadNewScript = Upload New Script
view_alert_definition_notification_cliScript_editor_newScriptVersion = Version
@@ -1389,7 +1389,7 @@ view_type_typeTreeLoadFailure = Failed to load resource type tree data
# Tabs
view_tabs_invalidSubTab = Invalid subtab: {0}
-view_tabs_invalidTab = Invalid tab: {0}~
+view_tabs_invalidTab = Invalid tab: {0}~
#=================== Dashboard =====================
view_dashboard_favorites_error1 = Failed to load favorite Resources.
@@ -1426,10 +1426,10 @@ view_portlet_defaultName_tagCloud = Tag Count
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_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.
+view_portlet_help_inventorySummary = This portlet displays a short summary of the current user''s viewable inventory and metric collection rate.
view_portlet_help_mashup = This portlet displays the returned content of a remote HTTP request (via an iframe).
view_portlet_help_message = This portlet displays a static HTML message. The <i>message</i> property must be configured.
-view_portlet_help_operations = This portlet displays executing, completed and scheduled operations for the current user''s inventory.
+view_portlet_help_operations = This portlet displays executing, completed and scheduled operations for the current user''s inventory.
view_portlet_help_platformSummary = This portlet displays information about the current user''s platform resources.
view_portlet_help_problemResources = This portlet displays the current user''s alerted or unavailable resources.
view_portlet_help_recentAlerts = This portlet displays alerts recently fired on the current user''s viewable inventory.
@@ -1706,9 +1706,9 @@ view_dynagroup_exprBuilder_expressionType_tooltip = The type of property this ex
<b>Plugin Configuration</b>: Search by the plugin component configuration setting of the component<br/> \
<b>Resource Configuration</b>: Search by the configuration setting of the managed resource
view_dynagroup_exprBuilder_resource = Resource
-view_dynagroup_exprBuilder_resource_tooltip = Choose the level of the resource you wish to select. For example, select "parent" will find resources whose parent resource matches the rest of the expression.
+view_dynagroup_exprBuilder_resource_tooltip = Choose the level of the resource you wish to select. For example, select "parent" will find resources whose parent resource matches the rest of the expression.
view_dynagroup_exprBuilder_groupBy = Group by
-view_dynagroup_exprBuilder_groupBy_tooltip = GroupBy will cause the system to pivot on the values from the entered expressions creating a separate group for each value. For example, GroupBy on the cluster name to create a group for each cluster with all cluster members in it.
+view_dynagroup_exprBuilder_groupBy_tooltip = GroupBy will cause the system to pivot on the values from the entered expressions creating a separate group for each value. For example, GroupBy on the cluster name to create a group for each cluster with all cluster members in it.
view_dynagroup_exprBuilder_resource_resource = Resource
view_dynagroup_exprBuilder_resource_child = Child
view_dynagroup_exprBuilder_resource_parent = Parent
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 3ed231a..8e19922 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
@@ -1646,6 +1646,24 @@ view_admin_systemSettings_serverDetails_installDir=Installationsverzeichnis des
view_admin_systemSettings_serverDetails_nextRotation=Nächste Rotation der Metrik-Tabellen
view_admin_systemSettings_serverDetails_currentTable=Aktuelle Datenbanktablee für Metrikdaten
view_admin_systemSettings_TraitPurge_name=Lösche Trait-Daten, die älter sind als
+view_operationHistoryList_notYetStarted=noch nicht gestartet
+common_msg_see_more=mehr ...
+common_status_unknown=Unbekannt
+common_unit_days=Tage
+common_unit_hours=Stunden
+common_unit_milliseconds=Millisekunden
+common_unit_minutes=Minuten
+common_unit_months=Monate
+common_unit_seconds=Sekunden
+common_unit_times=mal
+common_unit_weeks=Wochen
+common_unit_years=Jahre
+view_alert_definition_notification_cliScript_editor_existingScript=Vorhandenes Skript
+view_alert_definition_notification_cliScript_editor_anotherUser=Anderer Benutzer
+view_alert_definition_notification_cliScript_editor_script=Skript
+view_alert_definition_notification_cliScript_editor_thisUser=Aktueller Benutzer
+view_autoDiscoveryQ_confirmSelect=Sollen auch die Kinder der Platform ausgewählt werden?
+view_autoDiscoveryQ_showStatus=Zeige
13 years, 2 months
[rhq] Branch 'release-3.0.0' - modules/cli-tests modules/common modules/core modules/enterprise modules/helpers modules/plugins modules/pom.xml modules/test-utils pom.xml
by John Sanda
modules/cli-tests/pom.xml | 2 +-
modules/common/ant-bundle/pom.xml | 2 +-
modules/common/filetemplate-bundle/pom.xml | 2 +-
modules/common/jboss-as/pom.xml | 2 +-
modules/common/pom.xml | 2 +-
modules/core/client-api/pom.xml | 2 +-
modules/core/comm-api/pom.xml | 2 +-
modules/core/dbutils/pom.xml | 2 +-
modules/core/domain/pom.xml | 2 +-
modules/core/gui/pom.xml | 2 +-
modules/core/native-system/pom.xml | 2 +-
modules/core/plugin-api/pom.xml | 2 +-
modules/core/plugin-container/pom.xml | 2 +-
modules/core/plugin-validator/pom.xml | 2 +-
modules/core/plugindoc/pom.xml | 2 +-
modules/core/pom.xml | 2 +-
modules/core/util/pom.xml | 2 +-
modules/enterprise/agent/pom.xml | 2 +-
modules/enterprise/agentupdate/pom.xml | 2 +-
modules/enterprise/comm/pom.xml | 2 +-
modules/enterprise/gui/base-perspective-jar/pom.xml | 2 +-
modules/enterprise/gui/base-perspective-war/pom.xml | 2 +-
modules/enterprise/gui/content_http-war/pom.xml | 2 +-
modules/enterprise/gui/coregui/pom.xml | 2 +-
modules/enterprise/gui/installer-war/pom.xml | 2 +-
modules/enterprise/gui/pom.xml | 2 +-
modules/enterprise/gui/portal-war/pom.xml | 2 +-
modules/enterprise/gui/webdav-war/pom.xml | 2 +-
modules/enterprise/pom.xml | 2 +-
modules/enterprise/remoting/cli/pom.xml | 2 +-
modules/enterprise/remoting/client-api/pom.xml | 2 +-
modules/enterprise/remoting/pom.xml | 2 +-
modules/enterprise/remoting/webservices/pom.xml | 2 +-
modules/enterprise/server/container-lib/pom.xml | 2 +-
modules/enterprise/server/container/pom.xml | 2 +-
modules/enterprise/server/ear/pom.xml | 2 +-
modules/enterprise/server/jar/pom.xml | 2 +-
modules/enterprise/server/plugins/alert-email/pom.xml | 2 +-
modules/enterprise/server/plugins/alert-irc/pom.xml | 2 +-
modules/enterprise/server/plugins/alert-microblog/pom.xml | 2 +-
modules/enterprise/server/plugins/alert-mobicents/pom.xml | 2 +-
modules/enterprise/server/plugins/alert-operations/pom.xml | 2 +-
modules/enterprise/server/plugins/alert-roles/pom.xml | 2 +-
modules/enterprise/server/plugins/alert-snmp/pom.xml | 2 +-
modules/enterprise/server/plugins/alert-subject/pom.xml | 2 +-
modules/enterprise/server/plugins/ant-bundle/pom.xml | 2 +-
modules/enterprise/server/plugins/cobbler/pom.xml | 2 +-
modules/enterprise/server/plugins/disk/pom.xml | 2 +-
modules/enterprise/server/plugins/filetemplate-bundle/pom.xml | 2 +-
modules/enterprise/server/plugins/jboss-software/pom.xml | 2 +-
modules/enterprise/server/plugins/perspectives/core/perspective/pom.xml | 2 +-
modules/enterprise/server/plugins/perspectives/core/pom.xml | 2 +-
modules/enterprise/server/plugins/pom.xml | 2 +-
modules/enterprise/server/plugins/rhnhosted/pom.xml | 2 +-
modules/enterprise/server/plugins/url/pom.xml | 2 +-
modules/enterprise/server/plugins/validate-all-serverplugins/pom.xml | 2 +-
modules/enterprise/server/plugins/yum/pom.xml | 2 +-
modules/enterprise/server/safe-invoker/pom.xml | 2 +-
modules/enterprise/server/sars/agent-sar/pom.xml | 2 +-
modules/enterprise/server/sars/pom.xml | 2 +-
modules/enterprise/server/xml-schemas/pom.xml | 2 +-
modules/helpers/pluginAnnotations/pom.xml | 2 +-
modules/helpers/pluginGen/pom.xml | 2 +-
modules/helpers/pom.xml | 2 +-
modules/helpers/rtfilter/pom.xml | 2 +-
modules/plugins/aliases/pom.xml | 2 +-
modules/plugins/ant-bundle/pom.xml | 2 +-
modules/plugins/apache/pom.xml | 2 +-
modules/plugins/augeas/pom.xml | 2 +-
modules/plugins/cobbler/pom.xml | 2 +-
modules/plugins/cron/pom.xml | 2 +-
modules/plugins/database/pom.xml | 2 +-
modules/plugins/filetemplate-bundle/pom.xml | 2 +-
modules/plugins/grub/pom.xml | 2 +-
modules/plugins/hibernate/pom.xml | 2 +-
modules/plugins/hosts/pom.xml | 2 +-
modules/plugins/hudson/pom.xml | 2 +-
modules/plugins/iis/pom.xml | 2 +-
modules/plugins/jboss-as-5/pom.xml | 2 +-
modules/plugins/jboss-as/pom.xml | 2 +-
modules/plugins/jboss-cache-v3/pom.xml | 2 +-
modules/plugins/jboss-cache/pom.xml | 2 +-
modules/plugins/jmx/pom.xml | 2 +-
modules/plugins/mysql/pom.xml | 2 +-
modules/plugins/netservices/pom.xml | 2 +-
modules/plugins/oracle/pom.xml | 2 +-
modules/plugins/perftest/pom.xml | 2 +-
modules/plugins/platform/pom.xml | 2 +-
modules/plugins/pom.xml | 2 +-
modules/plugins/postfix/pom.xml | 2 +-
modules/plugins/postgres/pom.xml | 2 +-
modules/plugins/rhq-agent/pom.xml | 2 +-
modules/plugins/rhq-server/pom.xml | 2 +-
modules/plugins/samba/pom.xml | 2 +-
modules/plugins/script/pom.xml | 2 +-
modules/plugins/snmptrapd/pom.xml | 2 +-
modules/plugins/sshd/pom.xml | 2 +-
modules/plugins/sudoers/pom.xml | 2 +-
modules/plugins/tomcat/pom.xml | 2 +-
modules/plugins/twitter/pom.xml | 2 +-
modules/plugins/validate-all-plugins/pom.xml | 2 +-
modules/pom.xml | 2 +-
modules/test-utils/pom.xml | 2 +-
pom.xml | 2 +-
104 files changed, 104 insertions(+), 104 deletions(-)
New commits:
commit 0ffead48d1bfd5833337a2e962e668e44c603997
Author: John Sanda <jsanda(a)redhat.com>
Date: Thu Mar 3 11:04:14 2011 -0500
Reverting version to 3.0.0.GA
diff --git a/modules/cli-tests/pom.xml b/modules/cli-tests/pom.xml
index e2c6fe2..dfd8541 100644
--- a/modules/cli-tests/pom.xml
+++ b/modules/cli-tests/pom.xml
@@ -8,7 +8,7 @@
<parent>
<groupId>org.rhq</groupId>
<artifactId>rhq-parent</artifactId>
- <version>3.0.1.GA</version>
+ <version>3.0.0.GA</version>
</parent>
<artifactId>rhq-cli-tests</artifactId>
diff --git a/modules/common/ant-bundle/pom.xml b/modules/common/ant-bundle/pom.xml
index e16c969..97ef93b 100644
--- a/modules/common/ant-bundle/pom.xml
+++ b/modules/common/ant-bundle/pom.xml
@@ -5,7 +5,7 @@
<parent>
<groupId>org.rhq</groupId>
<artifactId>rhq-common-parent</artifactId>
- <version>3.0.1.GA</version>
+ <version>3.0.0.GA</version>
</parent>
<groupId>org.rhq</groupId>
diff --git a/modules/common/filetemplate-bundle/pom.xml b/modules/common/filetemplate-bundle/pom.xml
index 284b2d0..3b26a39 100644
--- a/modules/common/filetemplate-bundle/pom.xml
+++ b/modules/common/filetemplate-bundle/pom.xml
@@ -5,7 +5,7 @@
<parent>
<groupId>org.rhq</groupId>
<artifactId>rhq-common-parent</artifactId>
- <version>3.0.1.GA</version>
+ <version>3.0.0.GA</version>
</parent>
<groupId>org.rhq</groupId>
diff --git a/modules/common/jboss-as/pom.xml b/modules/common/jboss-as/pom.xml
index f857ff9..688d5e4 100644
--- a/modules/common/jboss-as/pom.xml
+++ b/modules/common/jboss-as/pom.xml
@@ -5,7 +5,7 @@
<parent>
<groupId>org.rhq</groupId>
<artifactId>rhq-common-parent</artifactId>
- <version>3.0.1.GA</version>
+ <version>3.0.0.GA</version>
</parent>
<groupId>org.rhq</groupId>
diff --git a/modules/common/pom.xml b/modules/common/pom.xml
index b506670..2ddc4af 100644
--- a/modules/common/pom.xml
+++ b/modules/common/pom.xml
@@ -4,7 +4,7 @@
<parent>
<groupId>org.rhq</groupId>
<artifactId>rhq-parent</artifactId>
- <version>3.0.1.GA</version>
+ <version>3.0.0.GA</version>
</parent>
<groupId>org.rhq</groupId>
diff --git a/modules/core/client-api/pom.xml b/modules/core/client-api/pom.xml
index da5d92d..a27161b 100644
--- a/modules/core/client-api/pom.xml
+++ b/modules/core/client-api/pom.xml
@@ -5,7 +5,7 @@
<parent>
<groupId>org.rhq</groupId>
<artifactId>rhq-core-parent</artifactId>
- <version>3.0.1.GA</version>
+ <version>3.0.0.GA</version>
</parent>
<groupId>org.rhq</groupId>
diff --git a/modules/core/comm-api/pom.xml b/modules/core/comm-api/pom.xml
index 8adbb53..4589d42 100644
--- a/modules/core/comm-api/pom.xml
+++ b/modules/core/comm-api/pom.xml
@@ -5,7 +5,7 @@
<parent>
<groupId>org.rhq</groupId>
<artifactId>rhq-core-parent</artifactId>
- <version>3.0.1.GA</version>
+ <version>3.0.0.GA</version>
</parent>
<groupId>org.rhq</groupId>
diff --git a/modules/core/dbutils/pom.xml b/modules/core/dbutils/pom.xml
index 48b6346..e8782c8 100644
--- a/modules/core/dbutils/pom.xml
+++ b/modules/core/dbutils/pom.xml
@@ -5,7 +5,7 @@
<parent>
<groupId>org.rhq</groupId>
<artifactId>rhq-core-parent</artifactId>
- <version>3.0.1.GA</version>
+ <version>3.0.0.GA</version>
</parent>
<groupId>org.rhq</groupId>
diff --git a/modules/core/domain/pom.xml b/modules/core/domain/pom.xml
index cbdef52..dc75145 100644
--- a/modules/core/domain/pom.xml
+++ b/modules/core/domain/pom.xml
@@ -5,7 +5,7 @@
<parent>
<groupId>org.rhq</groupId>
<artifactId>rhq-core-parent</artifactId>
- <version>3.0.1.GA</version>
+ <version>3.0.0.GA</version>
</parent>
<groupId>org.rhq</groupId>
diff --git a/modules/core/gui/pom.xml b/modules/core/gui/pom.xml
index f2abcbe..0f6412e 100644
--- a/modules/core/gui/pom.xml
+++ b/modules/core/gui/pom.xml
@@ -5,7 +5,7 @@
<parent>
<groupId>org.rhq</groupId>
<artifactId>rhq-core-parent</artifactId>
- <version>3.0.1.GA</version>
+ <version>3.0.0.GA</version>
</parent>
<groupId>org.rhq</groupId>
diff --git a/modules/core/native-system/pom.xml b/modules/core/native-system/pom.xml
index 7a93130..f72bc2f 100644
--- a/modules/core/native-system/pom.xml
+++ b/modules/core/native-system/pom.xml
@@ -5,7 +5,7 @@
<parent>
<groupId>org.rhq</groupId>
<artifactId>rhq-parent</artifactId>
- <version>3.0.1.GA</version>
+ <version>3.0.0.GA</version>
</parent>
<groupId>org.rhq</groupId>
diff --git a/modules/core/plugin-api/pom.xml b/modules/core/plugin-api/pom.xml
index 6f1649f..967b21a 100644
--- a/modules/core/plugin-api/pom.xml
+++ b/modules/core/plugin-api/pom.xml
@@ -5,7 +5,7 @@
<parent>
<groupId>org.rhq</groupId>
<artifactId>rhq-core-parent</artifactId>
- <version>3.0.1.GA</version>
+ <version>3.0.0.GA</version>
</parent>
<groupId>org.rhq</groupId>
diff --git a/modules/core/plugin-container/pom.xml b/modules/core/plugin-container/pom.xml
index 63ccf25..fbab223 100644
--- a/modules/core/plugin-container/pom.xml
+++ b/modules/core/plugin-container/pom.xml
@@ -5,7 +5,7 @@
<parent>
<groupId>org.rhq</groupId>
<artifactId>rhq-core-parent</artifactId>
- <version>3.0.1.GA</version>
+ <version>3.0.0.GA</version>
</parent>
<groupId>org.rhq</groupId>
diff --git a/modules/core/plugin-validator/pom.xml b/modules/core/plugin-validator/pom.xml
index 6cb6145..996cd8f 100644
--- a/modules/core/plugin-validator/pom.xml
+++ b/modules/core/plugin-validator/pom.xml
@@ -5,7 +5,7 @@
<parent>
<groupId>org.rhq</groupId>
<artifactId>rhq-core-parent</artifactId>
- <version>3.0.1.GA</version>
+ <version>3.0.0.GA</version>
</parent>
<groupId>org.rhq</groupId>
diff --git a/modules/core/plugindoc/pom.xml b/modules/core/plugindoc/pom.xml
index dc0ed50..29abbff 100644
--- a/modules/core/plugindoc/pom.xml
+++ b/modules/core/plugindoc/pom.xml
@@ -5,7 +5,7 @@
<parent>
<groupId>org.rhq</groupId>
<artifactId>rhq-core-parent</artifactId>
- <version>3.0.1.GA</version>
+ <version>3.0.0.GA</version>
</parent>
<groupId>org.rhq</groupId>
diff --git a/modules/core/pom.xml b/modules/core/pom.xml
index ab07d73..b0c399b 100644
--- a/modules/core/pom.xml
+++ b/modules/core/pom.xml
@@ -5,7 +5,7 @@
<parent>
<groupId>org.rhq</groupId>
<artifactId>rhq-parent</artifactId>
- <version>3.0.1.GA</version>
+ <version>3.0.0.GA</version>
</parent>
<groupId>org.rhq</groupId>
diff --git a/modules/core/util/pom.xml b/modules/core/util/pom.xml
index 0ebec9b..37bcda5 100644
--- a/modules/core/util/pom.xml
+++ b/modules/core/util/pom.xml
@@ -5,7 +5,7 @@
<parent>
<groupId>org.rhq</groupId>
<artifactId>rhq-core-parent</artifactId>
- <version>3.0.1.GA</version>
+ <version>3.0.0.GA</version>
</parent>
<groupId>org.rhq</groupId>
diff --git a/modules/enterprise/agent/pom.xml b/modules/enterprise/agent/pom.xml
index e2cba96..5f2742d 100644
--- a/modules/enterprise/agent/pom.xml
+++ b/modules/enterprise/agent/pom.xml
@@ -5,7 +5,7 @@
<parent>
<groupId>org.rhq</groupId>
<artifactId>rhq-parent</artifactId>
- <version>3.0.1.GA</version>
+ <version>3.0.0.GA</version>
</parent>
<groupId>org.rhq</groupId>
diff --git a/modules/enterprise/agentupdate/pom.xml b/modules/enterprise/agentupdate/pom.xml
index 06cecca..127b06f 100644
--- a/modules/enterprise/agentupdate/pom.xml
+++ b/modules/enterprise/agentupdate/pom.xml
@@ -5,7 +5,7 @@
<parent>
<groupId>org.rhq</groupId>
<artifactId>rhq-parent</artifactId>
- <version>3.0.1.GA</version>
+ <version>3.0.0.GA</version>
</parent>
<groupId>org.rhq</groupId>
diff --git a/modules/enterprise/comm/pom.xml b/modules/enterprise/comm/pom.xml
index f385a3f..9f09ff1 100644
--- a/modules/enterprise/comm/pom.xml
+++ b/modules/enterprise/comm/pom.xml
@@ -5,7 +5,7 @@
<parent>
<groupId>org.rhq</groupId>
<artifactId>rhq-parent</artifactId>
- <version>3.0.1.GA</version>
+ <version>3.0.0.GA</version>
</parent>
<groupId>org.rhq</groupId>
diff --git a/modules/enterprise/gui/base-perspective-jar/pom.xml b/modules/enterprise/gui/base-perspective-jar/pom.xml
index 95fd1b2..be0c363 100644
--- a/modules/enterprise/gui/base-perspective-jar/pom.xml
+++ b/modules/enterprise/gui/base-perspective-jar/pom.xml
@@ -5,7 +5,7 @@
<parent>
<groupId>org.rhq</groupId>
<artifactId>rhq-parent</artifactId>
- <version>3.0.1.GA</version>
+ <version>3.0.0.GA</version>
</parent>
<groupId>org.rhq</groupId>
diff --git a/modules/enterprise/gui/base-perspective-war/pom.xml b/modules/enterprise/gui/base-perspective-war/pom.xml
index b6cfbf0..c1c297f 100644
--- a/modules/enterprise/gui/base-perspective-war/pom.xml
+++ b/modules/enterprise/gui/base-perspective-war/pom.xml
@@ -5,7 +5,7 @@
<parent>
<groupId>org.rhq</groupId>
<artifactId>rhq-parent</artifactId>
- <version>3.0.1.GA</version>
+ <version>3.0.0.GA</version>
</parent>
<groupId>org.rhq</groupId>
diff --git a/modules/enterprise/gui/content_http-war/pom.xml b/modules/enterprise/gui/content_http-war/pom.xml
index 03199e5..6be8d8d 100644
--- a/modules/enterprise/gui/content_http-war/pom.xml
+++ b/modules/enterprise/gui/content_http-war/pom.xml
@@ -5,7 +5,7 @@
<parent>
<groupId>org.rhq</groupId>
<artifactId>rhq-enterprise-gui-parent</artifactId>
- <version>3.0.1.GA</version>
+ <version>3.0.0.GA</version>
</parent>
<groupId>org.rhq</groupId>
diff --git a/modules/enterprise/gui/coregui/pom.xml b/modules/enterprise/gui/coregui/pom.xml
index 872d763..709bfe3 100644
--- a/modules/enterprise/gui/coregui/pom.xml
+++ b/modules/enterprise/gui/coregui/pom.xml
@@ -5,7 +5,7 @@
<parent>
<groupId>org.rhq</groupId>
<artifactId>rhq-parent</artifactId>
- <version>3.0.1.GA</version>
+ <version>3.0.0.GA</version>
</parent>
<groupId>org.rhq</groupId>
diff --git a/modules/enterprise/gui/installer-war/pom.xml b/modules/enterprise/gui/installer-war/pom.xml
index 5bdab57..8d33ef0 100644
--- a/modules/enterprise/gui/installer-war/pom.xml
+++ b/modules/enterprise/gui/installer-war/pom.xml
@@ -5,7 +5,7 @@
<parent>
<groupId>org.rhq</groupId>
<artifactId>rhq-parent</artifactId>
- <version>3.0.1.GA</version>
+ <version>3.0.0.GA</version>
</parent>
<groupId>org.rhq</groupId>
diff --git a/modules/enterprise/gui/pom.xml b/modules/enterprise/gui/pom.xml
index 9e9abdf..bf6a9a4 100644
--- a/modules/enterprise/gui/pom.xml
+++ b/modules/enterprise/gui/pom.xml
@@ -5,7 +5,7 @@
<parent>
<groupId>org.rhq</groupId>
<artifactId>rhq-parent</artifactId>
- <version>3.0.1.GA</version>
+ <version>3.0.0.GA</version>
</parent>
<groupId>org.rhq</groupId>
diff --git a/modules/enterprise/gui/portal-war/pom.xml b/modules/enterprise/gui/portal-war/pom.xml
index 90b1a23..7e91a02 100644
--- a/modules/enterprise/gui/portal-war/pom.xml
+++ b/modules/enterprise/gui/portal-war/pom.xml
@@ -4,7 +4,7 @@
<parent>
<groupId>org.rhq</groupId>
<artifactId>rhq-parent</artifactId>
- <version>3.0.1.GA</version>
+ <version>3.0.0.GA</version>
</parent>
<groupId>org.rhq</groupId>
diff --git a/modules/enterprise/gui/webdav-war/pom.xml b/modules/enterprise/gui/webdav-war/pom.xml
index 844eaf4..9bdfc91 100644
--- a/modules/enterprise/gui/webdav-war/pom.xml
+++ b/modules/enterprise/gui/webdav-war/pom.xml
@@ -5,7 +5,7 @@
<parent>
<groupId>org.rhq</groupId>
<artifactId>rhq-parent</artifactId>
- <version>3.0.1.GA</version>
+ <version>3.0.0.GA</version>
</parent>
<groupId>org.rhq</groupId>
diff --git a/modules/enterprise/pom.xml b/modules/enterprise/pom.xml
index d8531c8..77a5685 100644
--- a/modules/enterprise/pom.xml
+++ b/modules/enterprise/pom.xml
@@ -5,7 +5,7 @@
<parent>
<groupId>org.rhq</groupId>
<artifactId>rhq-parent</artifactId>
- <version>3.0.1.GA</version>
+ <version>3.0.0.GA</version>
</parent>
<groupId>org.rhq</groupId>
diff --git a/modules/enterprise/remoting/cli/pom.xml b/modules/enterprise/remoting/cli/pom.xml
index 427373f..dff57e7 100644
--- a/modules/enterprise/remoting/cli/pom.xml
+++ b/modules/enterprise/remoting/cli/pom.xml
@@ -5,7 +5,7 @@
<parent>
<groupId>org.rhq</groupId>
<artifactId>rhq-parent</artifactId>
- <version>3.0.1.GA</version>
+ <version>3.0.0.GA</version>
</parent>
<artifactId>rhq-remoting-cli</artifactId>
diff --git a/modules/enterprise/remoting/client-api/pom.xml b/modules/enterprise/remoting/client-api/pom.xml
index 815c268..6008df1 100644
--- a/modules/enterprise/remoting/client-api/pom.xml
+++ b/modules/enterprise/remoting/client-api/pom.xml
@@ -5,7 +5,7 @@
<parent>
<groupId>org.rhq</groupId>
<artifactId>rhq-parent</artifactId>
- <version>3.0.1.GA</version>
+ <version>3.0.0.GA</version>
</parent>
<artifactId>rhq-remoting-client-api</artifactId>
diff --git a/modules/enterprise/remoting/pom.xml b/modules/enterprise/remoting/pom.xml
index 4dd8834..68d51c0 100644
--- a/modules/enterprise/remoting/pom.xml
+++ b/modules/enterprise/remoting/pom.xml
@@ -5,7 +5,7 @@
<parent>
<groupId>org.rhq</groupId>
<artifactId>rhq-parent</artifactId>
- <version>3.0.1.GA</version>
+ <version>3.0.0.GA</version>
</parent>
<artifactId>rhq-remoting-parent</artifactId>
diff --git a/modules/enterprise/remoting/webservices/pom.xml b/modules/enterprise/remoting/webservices/pom.xml
index 89703b8..444256d 100644
--- a/modules/enterprise/remoting/webservices/pom.xml
+++ b/modules/enterprise/remoting/webservices/pom.xml
@@ -5,7 +5,7 @@
<parent>
<groupId>org.rhq</groupId>
<artifactId>rhq-parent</artifactId>
- <version>3.0.1.GA</version>
+ <version>3.0.0.GA</version>
</parent>
<artifactId>rhq-remoting-webservices</artifactId>
diff --git a/modules/enterprise/server/container-lib/pom.xml b/modules/enterprise/server/container-lib/pom.xml
index fc6d36c..f09e063 100644
--- a/modules/enterprise/server/container-lib/pom.xml
+++ b/modules/enterprise/server/container-lib/pom.xml
@@ -5,7 +5,7 @@
<parent>
<groupId>org.rhq</groupId>
<artifactId>rhq-parent</artifactId>
- <version>3.0.1.GA</version>
+ <version>3.0.0.GA</version>
</parent>
<groupId>org.rhq</groupId>
diff --git a/modules/enterprise/server/container/pom.xml b/modules/enterprise/server/container/pom.xml
index 5ca49e4..f82f881 100644
--- a/modules/enterprise/server/container/pom.xml
+++ b/modules/enterprise/server/container/pom.xml
@@ -5,7 +5,7 @@
<parent>
<groupId>org.rhq</groupId>
<artifactId>rhq-parent</artifactId>
- <version>3.0.1.GA</version>
+ <version>3.0.0.GA</version>
</parent>
<groupId>org.rhq</groupId>
diff --git a/modules/enterprise/server/ear/pom.xml b/modules/enterprise/server/ear/pom.xml
index f8695eb..bdad488 100644
--- a/modules/enterprise/server/ear/pom.xml
+++ b/modules/enterprise/server/ear/pom.xml
@@ -5,7 +5,7 @@
<parent>
<groupId>org.rhq</groupId>
<artifactId>rhq-parent</artifactId>
- <version>3.0.1.GA</version>
+ <version>3.0.0.GA</version>
</parent>
<groupId>org.rhq</groupId>
diff --git a/modules/enterprise/server/jar/pom.xml b/modules/enterprise/server/jar/pom.xml
index e767f5b..ddff575 100644
--- a/modules/enterprise/server/jar/pom.xml
+++ b/modules/enterprise/server/jar/pom.xml
@@ -5,7 +5,7 @@
<parent>
<groupId>org.rhq</groupId>
<artifactId>rhq-parent</artifactId>
- <version>3.0.1.GA</version>
+ <version>3.0.0.GA</version>
</parent>
<groupId>org.rhq</groupId>
diff --git a/modules/enterprise/server/plugins/alert-email/pom.xml b/modules/enterprise/server/plugins/alert-email/pom.xml
index 7da5bfe..ea1eb7b 100644
--- a/modules/enterprise/server/plugins/alert-email/pom.xml
+++ b/modules/enterprise/server/plugins/alert-email/pom.xml
@@ -3,7 +3,7 @@
<parent>
<artifactId>rhq-enterprise-server-plugins-parent</artifactId>
<groupId>org.rhq</groupId>
- <version>3.0.1.GA</version>
+ <version>3.0.0.GA</version>
</parent>
<modelVersion>4.0.0</modelVersion>
diff --git a/modules/enterprise/server/plugins/alert-irc/pom.xml b/modules/enterprise/server/plugins/alert-irc/pom.xml
index 4608407..363ac0a 100644
--- a/modules/enterprise/server/plugins/alert-irc/pom.xml
+++ b/modules/enterprise/server/plugins/alert-irc/pom.xml
@@ -3,7 +3,7 @@
<parent>
<artifactId>rhq-enterprise-server-plugins-parent</artifactId>
<groupId>org.rhq</groupId>
- <version>3.0.1.GA</version>
+ <version>3.0.0.GA</version>
</parent>
<modelVersion>4.0.0</modelVersion>
diff --git a/modules/enterprise/server/plugins/alert-microblog/pom.xml b/modules/enterprise/server/plugins/alert-microblog/pom.xml
index 045540c..b4751ba 100644
--- a/modules/enterprise/server/plugins/alert-microblog/pom.xml
+++ b/modules/enterprise/server/plugins/alert-microblog/pom.xml
@@ -3,7 +3,7 @@
<parent>
<artifactId>rhq-enterprise-server-plugins-parent</artifactId>
<groupId>org.rhq</groupId>
- <version>3.0.1.GA</version>
+ <version>3.0.0.GA</version>
</parent>
<modelVersion>4.0.0</modelVersion>
diff --git a/modules/enterprise/server/plugins/alert-mobicents/pom.xml b/modules/enterprise/server/plugins/alert-mobicents/pom.xml
index fbf1d2f..b0a0c3b 100644
--- a/modules/enterprise/server/plugins/alert-mobicents/pom.xml
+++ b/modules/enterprise/server/plugins/alert-mobicents/pom.xml
@@ -3,7 +3,7 @@
<parent>
<artifactId>rhq-enterprise-server-plugins-parent</artifactId>
<groupId>org.rhq</groupId>
- <version>3.0.1.GA</version>
+ <version>3.0.0.GA</version>
</parent>
<modelVersion>4.0.0</modelVersion>
diff --git a/modules/enterprise/server/plugins/alert-operations/pom.xml b/modules/enterprise/server/plugins/alert-operations/pom.xml
index a4618a5..8419926 100644
--- a/modules/enterprise/server/plugins/alert-operations/pom.xml
+++ b/modules/enterprise/server/plugins/alert-operations/pom.xml
@@ -2,7 +2,7 @@
<parent>
<artifactId>rhq-enterprise-server-plugins-parent</artifactId>
<groupId>org.rhq</groupId>
- <version>3.0.1.GA</version>
+ <version>3.0.0.GA</version>
</parent>
<modelVersion>4.0.0</modelVersion>
diff --git a/modules/enterprise/server/plugins/alert-roles/pom.xml b/modules/enterprise/server/plugins/alert-roles/pom.xml
index 2673436..d2d0060 100644
--- a/modules/enterprise/server/plugins/alert-roles/pom.xml
+++ b/modules/enterprise/server/plugins/alert-roles/pom.xml
@@ -3,7 +3,7 @@
<parent>
<artifactId>rhq-enterprise-server-plugins-parent</artifactId>
<groupId>org.rhq</groupId>
- <version>3.0.1.GA</version>
+ <version>3.0.0.GA</version>
</parent>
<modelVersion>4.0.0</modelVersion>
diff --git a/modules/enterprise/server/plugins/alert-snmp/pom.xml b/modules/enterprise/server/plugins/alert-snmp/pom.xml
index 9b90e7b..6398092 100644
--- a/modules/enterprise/server/plugins/alert-snmp/pom.xml
+++ b/modules/enterprise/server/plugins/alert-snmp/pom.xml
@@ -3,7 +3,7 @@
<parent>
<artifactId>rhq-enterprise-server-plugins-parent</artifactId>
<groupId>org.rhq</groupId>
- <version>3.0.1.GA</version>
+ <version>3.0.0.GA</version>
</parent>
<modelVersion>4.0.0</modelVersion>
diff --git a/modules/enterprise/server/plugins/alert-subject/pom.xml b/modules/enterprise/server/plugins/alert-subject/pom.xml
index 781d5ad..c78247d 100644
--- a/modules/enterprise/server/plugins/alert-subject/pom.xml
+++ b/modules/enterprise/server/plugins/alert-subject/pom.xml
@@ -3,7 +3,7 @@
<parent>
<artifactId>rhq-enterprise-server-plugins-parent</artifactId>
<groupId>org.rhq</groupId>
- <version>3.0.1.GA</version>
+ <version>3.0.0.GA</version>
</parent>
<modelVersion>4.0.0</modelVersion>
diff --git a/modules/enterprise/server/plugins/ant-bundle/pom.xml b/modules/enterprise/server/plugins/ant-bundle/pom.xml
index 3f59440..30efb5a 100644
--- a/modules/enterprise/server/plugins/ant-bundle/pom.xml
+++ b/modules/enterprise/server/plugins/ant-bundle/pom.xml
@@ -5,7 +5,7 @@
<parent>
<groupId>org.rhq</groupId>
<artifactId>rhq-enterprise-server-plugins-parent</artifactId>
- <version>3.0.1.GA</version>
+ <version>3.0.0.GA</version>
</parent>
<groupId>org.rhq</groupId>
diff --git a/modules/enterprise/server/plugins/cobbler/pom.xml b/modules/enterprise/server/plugins/cobbler/pom.xml
index 7dd6631..8464662 100644
--- a/modules/enterprise/server/plugins/cobbler/pom.xml
+++ b/modules/enterprise/server/plugins/cobbler/pom.xml
@@ -4,7 +4,7 @@
<parent>
<groupId>org.rhq</groupId>
<artifactId>rhq-enterprise-server-plugins-parent</artifactId>
- <version>3.0.1.GA</version>
+ <version>3.0.0.GA</version>
</parent>
<modelVersion>4.0.0</modelVersion>
diff --git a/modules/enterprise/server/plugins/disk/pom.xml b/modules/enterprise/server/plugins/disk/pom.xml
index 31adf15..40ab2a2 100644
--- a/modules/enterprise/server/plugins/disk/pom.xml
+++ b/modules/enterprise/server/plugins/disk/pom.xml
@@ -5,7 +5,7 @@
<parent>
<groupId>org.rhq</groupId>
<artifactId>rhq-enterprise-server-plugins-parent</artifactId>
- <version>3.0.1.GA</version>
+ <version>3.0.0.GA</version>
</parent>
<groupId>org.rhq</groupId>
diff --git a/modules/enterprise/server/plugins/filetemplate-bundle/pom.xml b/modules/enterprise/server/plugins/filetemplate-bundle/pom.xml
index 9efc65d..0c5fb51 100644
--- a/modules/enterprise/server/plugins/filetemplate-bundle/pom.xml
+++ b/modules/enterprise/server/plugins/filetemplate-bundle/pom.xml
@@ -5,7 +5,7 @@
<parent>
<groupId>org.rhq</groupId>
<artifactId>rhq-enterprise-server-plugins-parent</artifactId>
- <version>3.0.1.GA</version>
+ <version>3.0.0.GA</version>
</parent>
<groupId>org.rhq</groupId>
diff --git a/modules/enterprise/server/plugins/jboss-software/pom.xml b/modules/enterprise/server/plugins/jboss-software/pom.xml
index 17522cf..3f1e165 100644
--- a/modules/enterprise/server/plugins/jboss-software/pom.xml
+++ b/modules/enterprise/server/plugins/jboss-software/pom.xml
@@ -5,7 +5,7 @@
<parent>
<groupId>org.rhq</groupId>
<artifactId>rhq-enterprise-server-plugins-parent</artifactId>
- <version>3.0.1.GA</version>
+ <version>3.0.0.GA</version>
</parent>
<groupId>org.rhq</groupId>
diff --git a/modules/enterprise/server/plugins/perspectives/core/perspective/pom.xml b/modules/enterprise/server/plugins/perspectives/core/perspective/pom.xml
index 9ed8b81..25917cc 100644
--- a/modules/enterprise/server/plugins/perspectives/core/perspective/pom.xml
+++ b/modules/enterprise/server/plugins/perspectives/core/perspective/pom.xml
@@ -7,7 +7,7 @@
<parent>
<groupId>org.rhq</groupId>
<artifactId>rhq-parent</artifactId>
- <version>3.0.1.GA</version>
+ <version>3.0.0.GA</version>
</parent>
<groupId>org.rhq</groupId>
diff --git a/modules/enterprise/server/plugins/perspectives/core/pom.xml b/modules/enterprise/server/plugins/perspectives/core/pom.xml
index f8568cd..40c066f 100644
--- a/modules/enterprise/server/plugins/perspectives/core/pom.xml
+++ b/modules/enterprise/server/plugins/perspectives/core/pom.xml
@@ -5,7 +5,7 @@
<parent>
<groupId>org.rhq</groupId>
<artifactId>rhq-parent</artifactId>
- <version>3.0.1.GA</version>
+ <version>3.0.0.GA</version>
</parent>
<groupId>org.rhq</groupId>
diff --git a/modules/enterprise/server/plugins/pom.xml b/modules/enterprise/server/plugins/pom.xml
index e11ef9c..9832288 100644
--- a/modules/enterprise/server/plugins/pom.xml
+++ b/modules/enterprise/server/plugins/pom.xml
@@ -5,7 +5,7 @@
<parent>
<groupId>org.rhq</groupId>
<artifactId>rhq-parent</artifactId>
- <version>3.0.1.GA</version>
+ <version>3.0.0.GA</version>
</parent>
<groupId>org.rhq</groupId>
diff --git a/modules/enterprise/server/plugins/rhnhosted/pom.xml b/modules/enterprise/server/plugins/rhnhosted/pom.xml
index 53e0508..26e985a 100644
--- a/modules/enterprise/server/plugins/rhnhosted/pom.xml
+++ b/modules/enterprise/server/plugins/rhnhosted/pom.xml
@@ -5,7 +5,7 @@
<parent>
<groupId>org.rhq</groupId>
<artifactId>rhq-enterprise-server-plugins-parent</artifactId>
- <version>3.0.1.GA</version>
+ <version>3.0.0.GA</version>
</parent>
<groupId>org.rhq</groupId>
diff --git a/modules/enterprise/server/plugins/url/pom.xml b/modules/enterprise/server/plugins/url/pom.xml
index 4ca964a..14e52de 100644
--- a/modules/enterprise/server/plugins/url/pom.xml
+++ b/modules/enterprise/server/plugins/url/pom.xml
@@ -5,7 +5,7 @@
<parent>
<groupId>org.rhq</groupId>
<artifactId>rhq-enterprise-server-plugins-parent</artifactId>
- <version>3.0.1.GA</version>
+ <version>3.0.0.GA</version>
</parent>
<groupId>org.rhq</groupId>
diff --git a/modules/enterprise/server/plugins/validate-all-serverplugins/pom.xml b/modules/enterprise/server/plugins/validate-all-serverplugins/pom.xml
index d12f06f..e160aa6 100644
--- a/modules/enterprise/server/plugins/validate-all-serverplugins/pom.xml
+++ b/modules/enterprise/server/plugins/validate-all-serverplugins/pom.xml
@@ -5,7 +5,7 @@
<parent>
<groupId>org.rhq</groupId>
<artifactId>rhq-enterprise-server-plugins-parent</artifactId>
- <version>3.0.1.GA</version>
+ <version>3.0.0.GA</version>
</parent>
<groupId>org.rhq</groupId>
diff --git a/modules/enterprise/server/plugins/yum/pom.xml b/modules/enterprise/server/plugins/yum/pom.xml
index f4767d1..344a215 100644
--- a/modules/enterprise/server/plugins/yum/pom.xml
+++ b/modules/enterprise/server/plugins/yum/pom.xml
@@ -5,7 +5,7 @@
<parent>
<groupId>org.rhq</groupId>
<artifactId>rhq-enterprise-server-plugins-parent</artifactId>
- <version>3.0.1.GA</version>
+ <version>3.0.0.GA</version>
</parent>
<groupId>org.rhq</groupId>
diff --git a/modules/enterprise/server/safe-invoker/pom.xml b/modules/enterprise/server/safe-invoker/pom.xml
index 9b40679..bb1abdd 100644
--- a/modules/enterprise/server/safe-invoker/pom.xml
+++ b/modules/enterprise/server/safe-invoker/pom.xml
@@ -5,7 +5,7 @@
<parent>
<groupId>org.rhq</groupId>
<artifactId>rhq-parent</artifactId>
- <version>3.0.1.GA</version>
+ <version>3.0.0.GA</version>
</parent>
<groupId>org.rhq</groupId>
diff --git a/modules/enterprise/server/sars/agent-sar/pom.xml b/modules/enterprise/server/sars/agent-sar/pom.xml
index 8217a38..2458369 100644
--- a/modules/enterprise/server/sars/agent-sar/pom.xml
+++ b/modules/enterprise/server/sars/agent-sar/pom.xml
@@ -5,7 +5,7 @@
<parent>
<groupId>org.rhq</groupId>
<artifactId>rhq-enterprise-server-sars-parent</artifactId>
- <version>3.0.1.GA</version>
+ <version>3.0.0.GA</version>
</parent>
<groupId>org.rhq</groupId>
diff --git a/modules/enterprise/server/sars/pom.xml b/modules/enterprise/server/sars/pom.xml
index 3e4e5be..4ac7f43 100644
--- a/modules/enterprise/server/sars/pom.xml
+++ b/modules/enterprise/server/sars/pom.xml
@@ -5,7 +5,7 @@
<parent>
<groupId>org.rhq</groupId>
<artifactId>rhq-parent</artifactId>
- <version>3.0.1.GA</version>
+ <version>3.0.0.GA</version>
</parent>
<groupId>org.rhq</groupId>
diff --git a/modules/enterprise/server/xml-schemas/pom.xml b/modules/enterprise/server/xml-schemas/pom.xml
index c9e116f..21ccc78 100644
--- a/modules/enterprise/server/xml-schemas/pom.xml
+++ b/modules/enterprise/server/xml-schemas/pom.xml
@@ -5,7 +5,7 @@
<parent>
<groupId>org.rhq</groupId>
<artifactId>rhq-parent</artifactId>
- <version>3.0.1.GA</version>
+ <version>3.0.0.GA</version>
</parent>
<groupId>org.rhq</groupId>
diff --git a/modules/helpers/pluginAnnotations/pom.xml b/modules/helpers/pluginAnnotations/pom.xml
index bb2d153..366d1aa 100644
--- a/modules/helpers/pluginAnnotations/pom.xml
+++ b/modules/helpers/pluginAnnotations/pom.xml
@@ -6,7 +6,7 @@
<parent>
<groupId>org.rhq.helpers</groupId>
<artifactId>rhq-helpers</artifactId>
- <version>3.0.1.GA</version>
+ <version>3.0.0.GA</version>
</parent>
<groupId>org.rhq.helpers</groupId>
diff --git a/modules/helpers/pluginGen/pom.xml b/modules/helpers/pluginGen/pom.xml
index 4c9a457..d992e29 100644
--- a/modules/helpers/pluginGen/pom.xml
+++ b/modules/helpers/pluginGen/pom.xml
@@ -6,7 +6,7 @@
<parent>
<groupId>org.rhq.helpers</groupId>
<artifactId>rhq-helpers</artifactId>
- <version>3.0.1.GA</version>
+ <version>3.0.0.GA</version>
</parent>
<groupId>org.rhq.helpers</groupId>
diff --git a/modules/helpers/pom.xml b/modules/helpers/pom.xml
index b3a39b8..c5e5ae2 100644
--- a/modules/helpers/pom.xml
+++ b/modules/helpers/pom.xml
@@ -5,7 +5,7 @@
<parent>
<groupId>org.rhq</groupId>
<artifactId>rhq-parent</artifactId>
- <version>3.0.1.GA</version>
+ <version>3.0.0.GA</version>
</parent>
<groupId>org.rhq.helpers</groupId>
diff --git a/modules/helpers/rtfilter/pom.xml b/modules/helpers/rtfilter/pom.xml
index 2c93677..ffac476 100644
--- a/modules/helpers/rtfilter/pom.xml
+++ b/modules/helpers/rtfilter/pom.xml
@@ -5,7 +5,7 @@
<parent>
<groupId>org.rhq.helpers</groupId>
<artifactId>rhq-helpers</artifactId>
- <version>3.0.1.GA</version>
+ <version>3.0.0.GA</version>
</parent>
<groupId>org.rhq</groupId>
diff --git a/modules/plugins/aliases/pom.xml b/modules/plugins/aliases/pom.xml
index 4567647..c475e5e 100644
--- a/modules/plugins/aliases/pom.xml
+++ b/modules/plugins/aliases/pom.xml
@@ -7,7 +7,7 @@
<parent>
<groupId>org.rhq</groupId>
<artifactId>rhq-plugins-parent</artifactId>
- <version>3.0.1.GA</version>
+ <version>3.0.0.GA</version>
</parent>
<groupId>org.rhq</groupId>
diff --git a/modules/plugins/ant-bundle/pom.xml b/modules/plugins/ant-bundle/pom.xml
index b2eb7ee..5fa4596 100644
--- a/modules/plugins/ant-bundle/pom.xml
+++ b/modules/plugins/ant-bundle/pom.xml
@@ -5,7 +5,7 @@
<parent>
<groupId>org.rhq</groupId>
<artifactId>rhq-plugins-parent</artifactId>
- <version>3.0.1.GA</version>
+ <version>3.0.0.GA</version>
</parent>
<groupId>org.rhq</groupId>
diff --git a/modules/plugins/apache/pom.xml b/modules/plugins/apache/pom.xml
index 0d873a0..8ed7fce 100644
--- a/modules/plugins/apache/pom.xml
+++ b/modules/plugins/apache/pom.xml
@@ -5,7 +5,7 @@
<parent>
<groupId>org.rhq</groupId>
<artifactId>rhq-plugins-parent</artifactId>
- <version>3.0.1.GA</version>
+ <version>3.0.0.GA</version>
</parent>
<groupId>org.rhq</groupId>
diff --git a/modules/plugins/augeas/pom.xml b/modules/plugins/augeas/pom.xml
index 7b07bff..51580cd 100644
--- a/modules/plugins/augeas/pom.xml
+++ b/modules/plugins/augeas/pom.xml
@@ -7,7 +7,7 @@
<parent>
<groupId>org.rhq</groupId>
<artifactId>rhq-plugins-parent</artifactId>
- <version>3.0.1.GA</version>
+ <version>3.0.0.GA</version>
</parent>
<groupId>org.rhq</groupId>
diff --git a/modules/plugins/cobbler/pom.xml b/modules/plugins/cobbler/pom.xml
index 2f7afc9..a140f5d 100644
--- a/modules/plugins/cobbler/pom.xml
+++ b/modules/plugins/cobbler/pom.xml
@@ -7,7 +7,7 @@
<parent>
<groupId>org.rhq</groupId>
<artifactId>rhq-plugins-parent</artifactId>
- <version>3.0.1.GA</version>
+ <version>3.0.0.GA</version>
</parent>
<groupId>org.rhq</groupId>
diff --git a/modules/plugins/cron/pom.xml b/modules/plugins/cron/pom.xml
index 1764232..9119492 100644
--- a/modules/plugins/cron/pom.xml
+++ b/modules/plugins/cron/pom.xml
@@ -5,7 +5,7 @@
<parent>
<groupId>org.rhq</groupId>
<artifactId>rhq-plugins-parent</artifactId>
- <version>3.0.1.GA</version>
+ <version>3.0.0.GA</version>
</parent>
<groupId>org.rhq</groupId>
diff --git a/modules/plugins/database/pom.xml b/modules/plugins/database/pom.xml
index be21346..714ad7a 100644
--- a/modules/plugins/database/pom.xml
+++ b/modules/plugins/database/pom.xml
@@ -5,7 +5,7 @@
<parent>
<groupId>org.rhq</groupId>
<artifactId>rhq-plugins-parent</artifactId>
- <version>3.0.1.GA</version>
+ <version>3.0.0.GA</version>
</parent>
<groupId>org.rhq</groupId>
diff --git a/modules/plugins/filetemplate-bundle/pom.xml b/modules/plugins/filetemplate-bundle/pom.xml
index 8544158..e01b311 100644
--- a/modules/plugins/filetemplate-bundle/pom.xml
+++ b/modules/plugins/filetemplate-bundle/pom.xml
@@ -5,7 +5,7 @@
<parent>
<groupId>org.rhq</groupId>
<artifactId>rhq-plugins-parent</artifactId>
- <version>3.0.1.GA</version>
+ <version>3.0.0.GA</version>
</parent>
<groupId>org.rhq</groupId>
diff --git a/modules/plugins/grub/pom.xml b/modules/plugins/grub/pom.xml
index 7e7ff13..aef1858 100644
--- a/modules/plugins/grub/pom.xml
+++ b/modules/plugins/grub/pom.xml
@@ -5,7 +5,7 @@
<parent>
<groupId>org.rhq</groupId>
<artifactId>rhq-plugins-parent</artifactId>
- <version>3.0.1.GA</version>
+ <version>3.0.0.GA</version>
</parent>
<groupId>org.rhq</groupId>
diff --git a/modules/plugins/hibernate/pom.xml b/modules/plugins/hibernate/pom.xml
index b3b0de7..4f87dfe 100644
--- a/modules/plugins/hibernate/pom.xml
+++ b/modules/plugins/hibernate/pom.xml
@@ -6,7 +6,7 @@
<groupId>org.rhq</groupId>
<!-- Bypass the jopr-plugins-parent which can not have children. It must build after the plugins in order to execute integration tests on them. -->
<artifactId>rhq-plugins-parent</artifactId>
- <version>3.0.1.GA</version>
+ <version>3.0.0.GA</version>
</parent>
<groupId>org.jboss.on</groupId>
diff --git a/modules/plugins/hosts/pom.xml b/modules/plugins/hosts/pom.xml
index 16524ff..157119f 100644
--- a/modules/plugins/hosts/pom.xml
+++ b/modules/plugins/hosts/pom.xml
@@ -7,7 +7,7 @@
<parent>
<groupId>org.rhq</groupId>
<artifactId>rhq-plugins-parent</artifactId>
- <version>3.0.1.GA</version>
+ <version>3.0.0.GA</version>
</parent>
<groupId>org.rhq</groupId>
diff --git a/modules/plugins/hudson/pom.xml b/modules/plugins/hudson/pom.xml
index 4b6b349..eed10bc 100644
--- a/modules/plugins/hudson/pom.xml
+++ b/modules/plugins/hudson/pom.xml
@@ -6,7 +6,7 @@
<parent>
<artifactId>rhq-plugins-parent</artifactId>
<groupId>org.rhq</groupId>
- <version>3.0.1.GA</version>
+ <version>3.0.0.GA</version>
</parent>
<groupId>org.rhq</groupId>
diff --git a/modules/plugins/iis/pom.xml b/modules/plugins/iis/pom.xml
index 8e9e712..9a9c2f0 100644
--- a/modules/plugins/iis/pom.xml
+++ b/modules/plugins/iis/pom.xml
@@ -5,7 +5,7 @@
<parent>
<groupId>org.rhq</groupId>
<artifactId>rhq-plugins-parent</artifactId>
- <version>3.0.1.GA</version>
+ <version>3.0.0.GA</version>
</parent>
<groupId>org.rhq</groupId>
diff --git a/modules/plugins/jboss-as-5/pom.xml b/modules/plugins/jboss-as-5/pom.xml
index 6754dcd..befe74c 100644
--- a/modules/plugins/jboss-as-5/pom.xml
+++ b/modules/plugins/jboss-as-5/pom.xml
@@ -9,7 +9,7 @@
<parent>
<groupId>org.rhq</groupId>
<artifactId>rhq-plugins-parent</artifactId>
- <version>3.0.1.GA</version>
+ <version>3.0.0.GA</version>
</parent>
<groupId>org.jboss.on</groupId>
diff --git a/modules/plugins/jboss-as/pom.xml b/modules/plugins/jboss-as/pom.xml
index 4d20b23..ac9b3f6 100644
--- a/modules/plugins/jboss-as/pom.xml
+++ b/modules/plugins/jboss-as/pom.xml
@@ -5,7 +5,7 @@
<parent>
<groupId>org.rhq</groupId>
<artifactId>rhq-plugins-parent</artifactId>
- <version>3.0.1.GA</version>
+ <version>3.0.0.GA</version>
</parent>
<groupId>org.jboss.on</groupId>
diff --git a/modules/plugins/jboss-cache-v3/pom.xml b/modules/plugins/jboss-cache-v3/pom.xml
index 1e3cc97..61f4e11 100644
--- a/modules/plugins/jboss-cache-v3/pom.xml
+++ b/modules/plugins/jboss-cache-v3/pom.xml
@@ -5,7 +5,7 @@
<parent>
<groupId>org.rhq</groupId>
<artifactId>rhq-plugins-parent</artifactId>
- <version>3.0.1.GA</version>
+ <version>3.0.0.GA</version>
</parent>
<groupId>org.jboss.on</groupId>
diff --git a/modules/plugins/jboss-cache/pom.xml b/modules/plugins/jboss-cache/pom.xml
index f88f00d..684e8e3 100644
--- a/modules/plugins/jboss-cache/pom.xml
+++ b/modules/plugins/jboss-cache/pom.xml
@@ -5,7 +5,7 @@
<parent>
<groupId>org.rhq</groupId>
<artifactId>rhq-plugins-parent</artifactId>
- <version>3.0.1.GA</version>
+ <version>3.0.0.GA</version>
</parent>
<groupId>org.jboss.on</groupId>
diff --git a/modules/plugins/jmx/pom.xml b/modules/plugins/jmx/pom.xml
index f8c6cee..a9874cc 100644
--- a/modules/plugins/jmx/pom.xml
+++ b/modules/plugins/jmx/pom.xml
@@ -5,7 +5,7 @@
<parent>
<groupId>org.rhq</groupId>
<artifactId>rhq-plugins-parent</artifactId>
- <version>3.0.1.GA</version>
+ <version>3.0.0.GA</version>
</parent>
<groupId>org.rhq</groupId>
diff --git a/modules/plugins/mysql/pom.xml b/modules/plugins/mysql/pom.xml
index f4f7e35..5a02364 100644
--- a/modules/plugins/mysql/pom.xml
+++ b/modules/plugins/mysql/pom.xml
@@ -5,7 +5,7 @@
<parent>
<groupId>org.rhq</groupId>
<artifactId>rhq-plugins-parent</artifactId>
- <version>3.0.1.GA</version>
+ <version>3.0.0.GA</version>
</parent>
<groupId>org.rhq</groupId>
diff --git a/modules/plugins/netservices/pom.xml b/modules/plugins/netservices/pom.xml
index aff86c9..3d937e7 100644
--- a/modules/plugins/netservices/pom.xml
+++ b/modules/plugins/netservices/pom.xml
@@ -5,7 +5,7 @@
<parent>
<groupId>org.rhq</groupId>
<artifactId>rhq-plugins-parent</artifactId>
- <version>3.0.1.GA</version>
+ <version>3.0.0.GA</version>
</parent>
<groupId>org.rhq</groupId>
diff --git a/modules/plugins/oracle/pom.xml b/modules/plugins/oracle/pom.xml
index d60a5fd..e915511 100644
--- a/modules/plugins/oracle/pom.xml
+++ b/modules/plugins/oracle/pom.xml
@@ -5,7 +5,7 @@
<parent>
<groupId>org.rhq</groupId>
<artifactId>rhq-plugins-parent</artifactId>
- <version>3.0.1.GA</version>
+ <version>3.0.0.GA</version>
</parent>
<groupId>org.rhq</groupId>
diff --git a/modules/plugins/perftest/pom.xml b/modules/plugins/perftest/pom.xml
index 505c001..f65ad5a 100644
--- a/modules/plugins/perftest/pom.xml
+++ b/modules/plugins/perftest/pom.xml
@@ -5,7 +5,7 @@
<parent>
<groupId>org.rhq</groupId>
<artifactId>rhq-plugins-parent</artifactId>
- <version>3.0.1.GA</version>
+ <version>3.0.0.GA</version>
</parent>
<groupId>org.rhq</groupId>
diff --git a/modules/plugins/platform/pom.xml b/modules/plugins/platform/pom.xml
index 2204d6f..aadd8bf 100644
--- a/modules/plugins/platform/pom.xml
+++ b/modules/plugins/platform/pom.xml
@@ -5,7 +5,7 @@
<parent>
<groupId>org.rhq</groupId>
<artifactId>rhq-plugins-parent</artifactId>
- <version>3.0.1.GA</version>
+ <version>3.0.0.GA</version>
</parent>
<groupId>org.rhq</groupId>
diff --git a/modules/plugins/pom.xml b/modules/plugins/pom.xml
index fc15af8..f32c52d 100644
--- a/modules/plugins/pom.xml
+++ b/modules/plugins/pom.xml
@@ -5,7 +5,7 @@
<parent>
<groupId>org.rhq</groupId>
<artifactId>rhq-parent</artifactId>
- <version>3.0.1.GA</version>
+ <version>3.0.0.GA</version>
</parent>
<groupId>org.rhq</groupId>
diff --git a/modules/plugins/postfix/pom.xml b/modules/plugins/postfix/pom.xml
index cbe2b75..639838b 100644
--- a/modules/plugins/postfix/pom.xml
+++ b/modules/plugins/postfix/pom.xml
@@ -5,7 +5,7 @@
<parent>
<groupId>org.rhq</groupId>
<artifactId>rhq-plugins-parent</artifactId>
- <version>3.0.1.GA</version>
+ <version>3.0.0.GA</version>
</parent>
<groupId>org.rhq</groupId>
diff --git a/modules/plugins/postgres/pom.xml b/modules/plugins/postgres/pom.xml
index 1b4321c..beb98f2 100644
--- a/modules/plugins/postgres/pom.xml
+++ b/modules/plugins/postgres/pom.xml
@@ -5,7 +5,7 @@
<parent>
<groupId>org.rhq</groupId>
<artifactId>rhq-plugins-parent</artifactId>
- <version>3.0.1.GA</version>
+ <version>3.0.0.GA</version>
</parent>
<groupId>org.rhq</groupId>
diff --git a/modules/plugins/rhq-agent/pom.xml b/modules/plugins/rhq-agent/pom.xml
index 648e108..fdb0991 100644
--- a/modules/plugins/rhq-agent/pom.xml
+++ b/modules/plugins/rhq-agent/pom.xml
@@ -5,7 +5,7 @@
<parent>
<groupId>org.rhq</groupId>
<artifactId>rhq-plugins-parent</artifactId>
- <version>3.0.1.GA</version>
+ <version>3.0.0.GA</version>
</parent>
<groupId>org.rhq</groupId>
diff --git a/modules/plugins/rhq-server/pom.xml b/modules/plugins/rhq-server/pom.xml
index 421827f..8fb6fee 100644
--- a/modules/plugins/rhq-server/pom.xml
+++ b/modules/plugins/rhq-server/pom.xml
@@ -5,7 +5,7 @@
<parent>
<groupId>org.rhq</groupId>
<artifactId>rhq-plugins-parent</artifactId>
- <version>3.0.1.GA</version>
+ <version>3.0.0.GA</version>
</parent>
<groupId>org.jboss.on</groupId>
diff --git a/modules/plugins/samba/pom.xml b/modules/plugins/samba/pom.xml
index a6df78c..9411143 100644
--- a/modules/plugins/samba/pom.xml
+++ b/modules/plugins/samba/pom.xml
@@ -5,7 +5,7 @@
<parent>
<groupId>org.rhq</groupId>
<artifactId>rhq-plugins-parent</artifactId>
- <version>3.0.1.GA</version>
+ <version>3.0.0.GA</version>
</parent>
<groupId>org.rhq</groupId>
diff --git a/modules/plugins/script/pom.xml b/modules/plugins/script/pom.xml
index 4201a72..0ec4d51 100644
--- a/modules/plugins/script/pom.xml
+++ b/modules/plugins/script/pom.xml
@@ -5,7 +5,7 @@
<parent>
<groupId>org.rhq</groupId>
<artifactId>rhq-plugins-parent</artifactId>
- <version>3.0.1.GA</version>
+ <version>3.0.0.GA</version>
</parent>
<groupId>org.rhq</groupId>
diff --git a/modules/plugins/snmptrapd/pom.xml b/modules/plugins/snmptrapd/pom.xml
index c86b9b2..f5106f0 100644
--- a/modules/plugins/snmptrapd/pom.xml
+++ b/modules/plugins/snmptrapd/pom.xml
@@ -2,7 +2,7 @@
<parent>
<artifactId>rhq-plugins-parent</artifactId>
<groupId>org.rhq</groupId>
- <version>3.0.1.GA</version>
+ <version>3.0.0.GA</version>
</parent>
<modelVersion>4.0.0</modelVersion>
diff --git a/modules/plugins/sshd/pom.xml b/modules/plugins/sshd/pom.xml
index f28b447..b637f0d 100644
--- a/modules/plugins/sshd/pom.xml
+++ b/modules/plugins/sshd/pom.xml
@@ -5,7 +5,7 @@
<parent>
<groupId>org.rhq</groupId>
<artifactId>rhq-plugins-parent</artifactId>
- <version>3.0.1.GA</version>
+ <version>3.0.0.GA</version>
</parent>
<groupId>org.rhq</groupId>
diff --git a/modules/plugins/sudoers/pom.xml b/modules/plugins/sudoers/pom.xml
index 25c56ab..55c3b49 100644
--- a/modules/plugins/sudoers/pom.xml
+++ b/modules/plugins/sudoers/pom.xml
@@ -5,7 +5,7 @@
<parent>
<groupId>org.rhq</groupId>
<artifactId>rhq-plugins-parent</artifactId>
- <version>3.0.1.GA</version>
+ <version>3.0.0.GA</version>
</parent>
<groupId>org.rhq</groupId>
diff --git a/modules/plugins/tomcat/pom.xml b/modules/plugins/tomcat/pom.xml
index abd7251..9de8802 100644
--- a/modules/plugins/tomcat/pom.xml
+++ b/modules/plugins/tomcat/pom.xml
@@ -5,7 +5,7 @@
<parent>
<groupId>org.rhq</groupId>
<artifactId>rhq-plugins-parent</artifactId>
- <version>3.0.1.GA</version>
+ <version>3.0.0.GA</version>
</parent>
<groupId>org.jboss.on</groupId>
diff --git a/modules/plugins/twitter/pom.xml b/modules/plugins/twitter/pom.xml
index e385f66..9ee6ac3 100644
--- a/modules/plugins/twitter/pom.xml
+++ b/modules/plugins/twitter/pom.xml
@@ -5,7 +5,7 @@
<parent>
<groupId>org.rhq</groupId>
<artifactId>rhq-plugins-parent</artifactId>
- <version>3.0.1.GA</version>
+ <version>3.0.0.GA</version>
</parent>
<groupId>org.rhq</groupId>
diff --git a/modules/plugins/validate-all-plugins/pom.xml b/modules/plugins/validate-all-plugins/pom.xml
index 539a63e..93e847c 100644
--- a/modules/plugins/validate-all-plugins/pom.xml
+++ b/modules/plugins/validate-all-plugins/pom.xml
@@ -5,7 +5,7 @@
<parent>
<groupId>org.rhq</groupId>
<artifactId>rhq-plugins-parent</artifactId>
- <version>3.0.1.GA</version>
+ <version>3.0.0.GA</version>
</parent>
<groupId>org.rhq</groupId>
diff --git a/modules/pom.xml b/modules/pom.xml
index a1285fd..a6af192 100644
--- a/modules/pom.xml
+++ b/modules/pom.xml
@@ -6,7 +6,7 @@
<parent>
<groupId>org.rhq</groupId>
<artifactId>rhq-parent</artifactId>
- <version>3.0.1.GA</version>
+ <version>3.0.0.GA</version>
</parent>
<groupId>org.rhq</groupId>
diff --git a/modules/test-utils/pom.xml b/modules/test-utils/pom.xml
index 0cf13f0..5b243a9 100644
--- a/modules/test-utils/pom.xml
+++ b/modules/test-utils/pom.xml
@@ -4,7 +4,7 @@
<parent>
<artifactId>rhq-modules-parent</artifactId>
<groupId>org.rhq</groupId>
- <version>3.0.1.GA</version>
+ <version>3.0.0.GA</version>
</parent>
<artifactId>test-utils</artifactId>
<name>RHQ Test Utils</name>
diff --git a/pom.xml b/pom.xml
index 5e5a302..94400f5 100644
--- a/pom.xml
+++ b/pom.xml
@@ -6,7 +6,7 @@
<groupId>org.rhq</groupId>
<artifactId>rhq-parent</artifactId>
- <version>3.0.1.GA</version>
+ <version>3.0.0.GA</version>
<packaging>pom</packaging>
<name>RHQ</name>
13 years, 2 months
[rhq] 82 commits - modules/core modules/enterprise
by lkrejci
modules/core/dbutils/pom.xml | 2
modules/core/dbutils/src/main/scripts/dbsetup/authz-data.xml | 1
modules/core/dbutils/src/main/scripts/dbsetup/content-schema.xml | 6
modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml | 37
modules/core/domain/src/main/java/org/rhq/core/domain/alert/notification/AlertNotification.java | 17
modules/core/domain/src/main/java/org/rhq/core/domain/auth/Subject.java | 12
modules/core/domain/src/main/java/org/rhq/core/domain/authz/Permission.java | 8
modules/core/domain/src/main/java/org/rhq/core/domain/content/PackageType.java | 7
modules/core/domain/src/main/java/org/rhq/core/domain/content/PackageVersion.java | 79
modules/core/domain/src/main/java/org/rhq/core/domain/content/PackageVersionContentSource.java | 11
modules/core/domain/src/main/java/org/rhq/core/domain/content/PackageVersionFormatDescription.java | 91 +
modules/core/domain/src/main/java/org/rhq/core/domain/content/Repo.java | 90 -
modules/core/domain/src/main/java/org/rhq/core/domain/content/RepoPackageVersion.java | 14
modules/core/domain/src/main/java/org/rhq/core/domain/content/ValidatablePackageDetailsKey.java | 107 +
modules/core/domain/src/main/java/org/rhq/core/domain/content/composite/PackageAndLatestVersionComposite.java | 85
modules/core/domain/src/main/java/org/rhq/core/domain/content/composite/PackageTypeAndVersionFormatComposite.java | 68
modules/core/domain/src/main/java/org/rhq/core/domain/criteria/AlertDefinitionCriteria.java | 21
modules/core/domain/src/main/java/org/rhq/core/domain/criteria/PackageCriteria.java | 92 +
modules/core/domain/src/main/java/org/rhq/core/domain/criteria/RepoCriteria.java | 13
modules/core/domain/src/main/java/org/rhq/core/domain/resource/composite/DisambiguationReport.java | 43
modules/core/domain/src/main/java/org/rhq/core/domain/util/DisambiguationReportRenderer.java | 683 +++++++
modules/core/domain/src/main/java/org/rhq/core/domain/util/OSGiVersion.java | 169 +
modules/core/domain/src/main/java/org/rhq/core/domain/util/OSGiVersionComparator.java | 68
modules/core/domain/src/test/java/org/rhq/core/domain/test/QueriesTest.java | 2
modules/core/domain/src/test/java/org/rhq/core/domain/util/DisambiguationReportRendererTest.java | 184 ++
modules/core/domain/src/test/java/org/rhq/core/domain/util/OSGiVersionComparatorTest.java | 82
modules/core/util/src/main/java/org/rhq/core/util/OSGiVersionComparator.java | 94 -
modules/core/util/src/test/java/org/rhq/core/util/OSGiVersionComparatorTest.java | 80
modules/enterprise/binding/pom.xml | 388 ++++
modules/enterprise/binding/src/main/java/org/rhq/bindings/SandboxedScriptEngine.java | 193 ++
modules/enterprise/binding/src/main/java/org/rhq/bindings/ScriptEngineFactory.java | 142 +
modules/enterprise/binding/src/main/java/org/rhq/bindings/StandardBindings.java | 178 +
modules/enterprise/binding/src/main/java/org/rhq/bindings/StandardScriptPermissions.java | 107 +
modules/enterprise/binding/src/main/java/org/rhq/bindings/client/AbstractRhqFacadeProxy.java | 103 +
modules/enterprise/binding/src/main/java/org/rhq/bindings/client/ResourceClientFactory.java | 213 ++
modules/enterprise/binding/src/main/java/org/rhq/bindings/client/ResourceClientProxy.java | 657 +++++++
modules/enterprise/binding/src/main/java/org/rhq/bindings/client/RhqFacade.java | 132 +
modules/enterprise/binding/src/main/java/org/rhq/bindings/client/RhqManagers.java | 116 +
modules/enterprise/binding/src/main/java/org/rhq/bindings/engine/JsEngineInitializer.java | 73
modules/enterprise/binding/src/main/java/org/rhq/bindings/engine/ScriptEngineInitializer.java | 60
modules/enterprise/binding/src/main/java/org/rhq/bindings/export/ExportException.java | 43
modules/enterprise/binding/src/main/java/org/rhq/bindings/export/Exporter.java | 121 +
modules/enterprise/binding/src/main/java/org/rhq/bindings/output/TabularWriter.java | 708 +++++++
modules/enterprise/binding/src/main/java/org/rhq/bindings/util/ConfigurationClassBuilder.java | 158 +
modules/enterprise/binding/src/main/java/org/rhq/bindings/util/InterfaceSimplifier.java | 128 +
modules/enterprise/binding/src/main/java/org/rhq/bindings/util/LazyLoadScenario.java | 44
modules/enterprise/binding/src/main/java/org/rhq/bindings/util/PackageFinder.java | 144 +
modules/enterprise/binding/src/main/java/org/rhq/bindings/util/ResourceTypeFingerprint.java | 182 ++
modules/enterprise/binding/src/main/java/org/rhq/bindings/util/ScriptAssert.java | 421 ++++
modules/enterprise/binding/src/main/java/org/rhq/bindings/util/ScriptAssertionException.java | 57
modules/enterprise/binding/src/main/java/org/rhq/bindings/util/ScriptUtil.java | 181 ++
modules/enterprise/binding/src/main/java/org/rhq/bindings/util/ShortOutput.java | 27
modules/enterprise/binding/src/main/java/org/rhq/bindings/util/SummaryFilter.java | 127 +
modules/enterprise/binding/src/test/java/org/rhq/bindings/FakeRhqFacade.java | 185 ++
modules/enterprise/binding/src/test/java/org/rhq/bindings/ScriptEngineTest.java | 111 +
modules/enterprise/binding/src/test/java/org/rhq/bindings/TabularWriterTest.java | 397 ++++
modules/enterprise/binding/src/test/java/org/rhq/bindings/util/ScriptAssertTest.java | 92 +
modules/enterprise/binding/src/test/java/org/rhq/bindings/util/ScriptUtilTest.java | 40
modules/enterprise/binding/src/test/java/org/rhq/bindings/util/SummaryFilterTest.java | 103 +
modules/enterprise/binding/src/test/resources/allow-all.policy | 3
modules/enterprise/gui/base-perspective-jar/src/main/java/org/rhq/enterprise/server/perspective/AbstractPerspectiveResourceUIBean.java | 2
modules/enterprise/gui/base-perspective-jar/src/main/java/org/rhq/enterprise/server/perspective/PerspectiveClientUIBean.java | 4
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/AdministrationView.java | 9
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/roles/PermissionsEditor.java | 5
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/AbstractNotificationSenderForm.java | 14
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/CliNotificationSenderForm.java | 704 +++++++
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/NewNotificationEditor.java | 20
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/ResourceOperationNotificationSenderForm.java | 11
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/SimpleNotificationSenderForm.java | 11
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/SystemRolesNotificationSenderForm.java | 9
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/SystemUsersNotificationSenderForm.java | 9
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/form/RadioGroupWithComponentsItem.java | 92 -
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/upload/FileUploadForm.java | 22
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/upload/PackageVersionFileUploadForm.java | 104 -
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/ContentGWTService.java | 12
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/SubjectGWTService.java | 8
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/factory/ResourceFactoryPackageStep.java | 4
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/ContentGWTServiceImpl.java | 33
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/PackageVersionFileUploadServlet.java | 24
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/SubjectGWTServiceImpl.java | 8
modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages.properties | 14
modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/content/CreateContentSourceUIBean.java | 2
modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/content/CreateNewPackageUIBean.java | 90 -
modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/content/CreateRepoUIBean.java | 65
modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/content/RepoDetailsUIBean.java | 66
modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/content/RepoPackageVersionsUIBean.java | 25
modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/inventory/resource/CreateNewPackageChildResourceUIBean.java | 13
modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/legacy/portlet/recentlyApproved/ViewAction.java | 2
modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/util/EnterpriseFacesContextUtility.java | 18
modules/enterprise/gui/portal-war/src/main/webapp/rhq/content/advisoryInfo-plain.xhtml | 137 +
modules/enterprise/gui/portal-war/src/main/webapp/rhq/content/contentProvider-add-map-plain.xhtml | 58
modules/enterprise/gui/portal-war/src/main/webapp/rhq/content/contentProvider-edit-map-plain.xhtml | 59
modules/enterprise/gui/portal-war/src/main/webapp/rhq/content/contentProvider-plain.xhtml | 512 +++++
modules/enterprise/gui/portal-war/src/main/webapp/rhq/content/contentProvider-view-map-plain.xhtml | 58
modules/enterprise/gui/portal-war/src/main/webapp/rhq/content/createContentProvider-add-map-plain.xhtml | 57
modules/enterprise/gui/portal-war/src/main/webapp/rhq/content/createContentProvider-edit-map-plain.xhtml | 58
modules/enterprise/gui/portal-war/src/main/webapp/rhq/content/createContentProvider-plain.xhtml | 152 +
modules/enterprise/gui/portal-war/src/main/webapp/rhq/content/createRepo-plain.xhtml | 90 +
modules/enterprise/gui/portal-war/src/main/webapp/rhq/content/createRepo.xhtml | 15
modules/enterprise/gui/portal-war/src/main/webapp/rhq/content/importRepos-plain.xhtml | 118 +
modules/enterprise/gui/portal-war/src/main/webapp/rhq/content/listContentProviders-plain.xhtml | 171 +
modules/enterprise/gui/portal-war/src/main/webapp/rhq/content/listRepos-plain.xhtml | 151 +
modules/enterprise/gui/portal-war/src/main/webapp/rhq/content/packageVersion-plain.xhtml | 192 ++
modules/enterprise/gui/portal-war/src/main/webapp/rhq/content/repo-plain.xhtml | 893 ++++++++++
modules/enterprise/gui/portal-war/src/main/webapp/rhq/content/repo.xhtml | 118 +
modules/enterprise/gui/portal-war/src/main/webapp/rhq/content/repoAssociations-plain.xhtml | 288 +++
modules/enterprise/gui/portal-war/src/main/webapp/rhq/content/repoSubscriptions-plain.xhtml | 282 +++
modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/content/audit-trail-item-plain.xhtml | 83
modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/content/confirm-create-plain.xhtml | 196 ++
modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/content/confirm-delete-plain.xhtml | 70
modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/content/create-plain.xhtml | 149 +
modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/content/history-request-item-plain.xhtml | 131 +
modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/content/history-request-plain.xhtml | 189 ++
modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/content/history-request-step-details-plain.xhtml | 57
modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/content/subscription_packages-plain.xhtml | 114 +
modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/content/update-plain.xhtml | 154 +
modules/enterprise/pom.xml | 4
modules/enterprise/remoting/cli/pom.xml | 8
modules/enterprise/remoting/cli/src/main/java/org/rhq/enterprise/client/SummaryFilter.java | 127 -
modules/enterprise/remoting/cli/src/main/java/org/rhq/enterprise/client/TabularWriter.java | 708 -------
modules/enterprise/remoting/cli/src/main/java/org/rhq/enterprise/client/commands/HelpCommand.java | 2
modules/enterprise/remoting/cli/src/main/java/org/rhq/enterprise/client/commands/LoginCommand.java | 8
modules/enterprise/remoting/cli/src/main/java/org/rhq/enterprise/client/commands/ScriptCommand.java | 163 -
modules/enterprise/remoting/cli/src/main/java/org/rhq/enterprise/client/export/ExportException.java | 43
modules/enterprise/remoting/cli/src/main/java/org/rhq/enterprise/client/export/Exporter.java | 86
modules/enterprise/remoting/cli/src/main/java/org/rhq/enterprise/client/proxy/ConfigurationEditor.java | 2
modules/enterprise/remoting/cli/src/main/java/org/rhq/enterprise/client/proxy/EditableResourceClientFactory.java | 61
modules/enterprise/remoting/cli/src/main/java/org/rhq/enterprise/client/proxy/EditableResourceClientProxy.java | 71
modules/enterprise/remoting/cli/src/main/java/org/rhq/enterprise/client/proxy/ResourceClientFactory.java | 134 -
modules/enterprise/remoting/cli/src/main/java/org/rhq/enterprise/client/proxy/ResourceClientProxy.java | 669 -------
modules/enterprise/remoting/cli/src/main/java/org/rhq/enterprise/client/utility/ConfigurationClassBuilder.java | 158 -
modules/enterprise/remoting/cli/src/main/java/org/rhq/enterprise/client/utility/LazyLoadScenario.java | 44
modules/enterprise/remoting/cli/src/main/java/org/rhq/enterprise/client/utility/PackageFinder.java | 140 -
modules/enterprise/remoting/cli/src/main/java/org/rhq/enterprise/client/utility/ScriptAssert.java | 413 ----
modules/enterprise/remoting/cli/src/main/java/org/rhq/enterprise/client/utility/ScriptAssertionException.java | 57
modules/enterprise/remoting/cli/src/main/java/org/rhq/enterprise/client/utility/ScriptUtil.java | 159 -
modules/enterprise/remoting/cli/src/main/java/org/rhq/enterprise/client/utility/ShortOutput.java | 27
modules/enterprise/remoting/cli/src/main/scripts/rhq-client.build.xml | 3
modules/enterprise/remoting/cli/src/test/java/org/rhq/enterprise/client/SummaryFilterTest.java | 101 -
modules/enterprise/remoting/cli/src/test/java/org/rhq/enterprise/client/TabularWriterTest.java | 396 ----
modules/enterprise/remoting/cli/src/test/java/org/rhq/enterprise/client/commands/ScriptCommandTest.java | 34
modules/enterprise/remoting/cli/src/test/java/org/rhq/enterprise/client/utility/ScriptAssertTest.java | 90 -
modules/enterprise/remoting/cli/src/test/java/org/rhq/enterprise/client/utility/ScriptUtilTest.java | 38
modules/enterprise/remoting/client-api/pom.xml | 96 -
modules/enterprise/remoting/client-api/src/main/java/org/rhq/enterprise/client/RemoteClient.java | 186 --
modules/enterprise/remoting/client-api/src/main/java/org/rhq/enterprise/client/RemoteClientProxy.java | 186 --
modules/enterprise/server/client-api/pom.xml | 228 ++
modules/enterprise/server/client-api/src/main/java/org/rhq/enterprise/client/LocalClient.java | 229 ++
modules/enterprise/server/client-api/src/main/java/org/rhq/enterprise/client/LocalClientProxy.java | 67
modules/enterprise/server/container/src/main/bin-resources/bin/rhq-server.security-policy | 10
modules/enterprise/server/container/src/main/bin-resources/bin/rhq-server.sh | 3
modules/enterprise/server/container/src/main/bin-resources/bin/wrapper/rhq-server-wrapper.conf | 3
modules/enterprise/server/ear/pom.xml | 27
modules/enterprise/server/jar/pom.xml | 8
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertDefinitionManagerBean.java | 18
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertNotificationManagerBean.java | 89
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertNotificationManagerLocal.java | 33
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertNotificationValidationException.java | 49
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertTemplateManagerBean.java | 2
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/auth/SubjectManagerBean.java | 45
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/auth/SubjectManagerLocal.java | 9
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/authz/AuthorizationManagerBean.java | 25
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/authz/AuthorizationManagerLocal.java | 22
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerBean.java | 4
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerBean.java | 238 ++
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerHelper.java | 57
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerLocal.java | 86
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerRemote.java | 67
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentSourceManagerBean.java | 114 -
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentSourceManagerLocal.java | 3
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentUIManagerBean.java | 12
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentUIManagerLocal.java | 5
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/RepoManagerBean.java | 262 ++
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/RepoManagerLocal.java | 22
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/RepoManagerRemote.java | 38
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/MasterServerPluginContainer.java | 2
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/AlertSender.java | 20
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/AlertSenderValidationResults.java | 46
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/content/AbstractPackageTypeBehavior.java | 33
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/content/ContentProviderPackageDetailsKey.java | 11
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/content/PackageDetailsValidationException.java | 47
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/content/PackageSource.java | 1
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/content/PackageTypeBehavior.java | 67
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/content/PackageTypePluginManager.java | 155 +
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/content/PackageTypeServerPluginContainer.java | 56
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/content/sync/PackageSourceSynchronizer.java | 6
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceFactoryManagerBean.java | 8
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/disambiguation/MutableDisambiguationReport.java | 4
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/webservices/WebservicesManagerBean.java | 33
modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/plugin/pc/content/TestContentProvider.java | 4
modules/enterprise/server/plugins/alert-cli/pom.xml | 248 ++
modules/enterprise/server/plugins/alert-cli/src/main/java/org/rhq/enterprise/server/plugins/alertCli/CliComponent.java | 360 ++++
modules/enterprise/server/plugins/alert-cli/src/main/java/org/rhq/enterprise/server/plugins/alertCli/CliSender.java | 403 ++++
modules/enterprise/server/plugins/alert-cli/src/main/resources/META-INF/rhq-serverplugin.xml | 73
modules/enterprise/server/plugins/disk/src/main/java/org/rhq/enterprise/server/plugins/disk/DiskSource.java | 2
modules/enterprise/server/plugins/packagetype-cli/pom.xml | 217 ++
modules/enterprise/server/plugins/packagetype-cli/src/main/java/org/rhq/enterprise/server/plugins/packagetypeCli/CliPackageTypeBehavior.java | 132 +
modules/enterprise/server/plugins/packagetype-cli/src/main/resources/META-INF/rhq-serverplugin.xml | 24
modules/enterprise/server/plugins/pom.xml | 2
modules/enterprise/server/pom.xml | 1
modules/enterprise/server/xml-schemas/src/main/java/org/rhq/enterprise/server/xmlschema/ServerPluginDescriptorUtil.java | 3
modules/enterprise/server/xml-schemas/src/main/java/org/rhq/enterprise/server/xmlschema/XmlSchemas.java | 4
modules/enterprise/server/xml-schemas/src/main/resources/rhq-serverplugin-packagetype.xsd | 144 +
203 files changed, 17431 insertions(+), 4416 deletions(-)
New commits:
commit 3fc1998054a6390702a46d4db4f71689e2f723e6
Merge: 51f82ef... d470c4f...
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Thu Mar 3 13:17:34 2011 +0100
Merge remote branch 'origin/master' into cli-alert-notifs
commit 51f82ef62d7124f40c84d9b95606d3e983517855
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Thu Mar 3 13:15:51 2011 +0100
fixing db-upgrade to successfully add the "is_private" column on rhq_repo.
diff --git a/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml b/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml
index 71ca67e..f0d6cc5 100644
--- a/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml
+++ b/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml
@@ -3348,6 +3348,16 @@
<schemaSpec version="2.105">
<schema-addColumn table="RHQ_REPO" column="OWNER_ID" columnType="INTEGER" />
<schema-addColumn table="RHQ_REPO" column="IS_PRIVATE" columnType="BOOLEAN" />
+ <schema-directSQL>
+ <statement targetDBVendor="postgresql" desc="Set is_private flag for existing repos to false">
+ UPDATE RHQ_REPO
+ SET IS_PRIVATE = false
+ </statement>
+ <statement targetDBVendor="oracle" desc="Set is_private flag for existing repos to false">
+ UPDATE RHQ_REPO
+ SET IS_PRIVATE = 0
+ </statement>
+ </schema-directSQL>
<schema-alterColumn table="RHQ_REPO" column="IS_PRIVATE" nullable="FALSE" default="TRUE"/>
<schema-directSQL>
<statement desc="Creating OWNER_ID foreign key relation on RHQ_REPO">
commit c3a40646af0bae0dc917631cb421a824ab4180f7
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Thu Mar 3 13:15:13 2011 +0100
Creating *-plain.xhtml views for rhq/resource/content pages. These are *NOT* finished as they still contain links to "full" views.
diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/content/audit-trail-item-plain.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/content/audit-trail-item-plain.xhtml
new file mode 100644
index 0000000..796f038
--- /dev/null
+++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/content/audit-trail-item-plain.xhtml
@@ -0,0 +1,83 @@
+<?xml version="1.0"?>
+
+<!DOCTYPE html
+ PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml"
+ xmlns:h="http://java.sun.com/jsf/html"
+ xmlns:f="http://java.sun.com/jsf/core"
+ xmlns:ui="http://java.sun.com/jsf/facelets"
+ xmlns:c="http://java.sun.com/jstl/core"
+ xmlns:onc="http://jboss.org/on/component"
+ xmlns:onf="http://jboss.org/on/function"
+ xmlns:rich="http://richfaces.ajax4jsf.org/rich">
+
+<ui:composition template="/rhq/resource/layout/main-plain.xhtml">
+
+<ui:param name="pageTitle" value="Audit Trail for Resource '#{ResourceUIBean.name}'"/>
+<ui:param name="selectedTabName" value="Content.History"/>
+
+<ui:define name="content">
+
+<!-- Content Requests Table -->
+
+<h:form id="contentRequestsForm">
+<input type="hidden" name="id" value="${param.id}"/>
+
+<rich:panel>
+ <f:facet name="header"><h:outputText value="Package Details"/></f:facet>
+
+ <table class="revision-data-table" width="100%">
+ <tr class="revision-data-table-even-row">
+ <td><b>Package Name</b></td>
+ <td>
+ <h:outputText value="#{AuditTrailItemUIBean.history.packageVersion.displayName}"
+ rendered="#{!empty AuditTrailItemUIBean.history.packageVersion.displayName}"/>
+ <h:outputText value="#{AuditTrailItemUIBean.history.packageVersion.generalPackage.name}"
+ rendered="#{empty AuditTrailItemUIBean.history.packageVersion.displayName}"/>
+
+ </td>
+ </tr>
+ <tr class="revision-data-table-odd-row">
+ <td><b>Version</b></td>
+ <td>
+ <h:outputText value="#{AuditTrailItemUIBean.history.packageVersion.displayVersion}"
+ rendered="#{!empty AuditTrailItemUIBean.history.packageVersion.displayVersion}"/>
+ <h:outputText value="#{AuditTrailItemUIBean.history.packageVersion.version}"
+ rendered="#{empty AuditTrailItemUIBean.history.packageVersion.displayVersion}"/>
+ </td>
+ </tr>
+ <tr class="revision-data-table-even-row">
+ <td><b>Architecture</b></td>
+ <td>
+ <h:outputText value="#{AuditTrailItemUIBean.history.packageVersion.architecture.name}"/>
+ </td>
+ </tr>
+ <tr class="revision-data-table-odd-row">
+ <td><b>Result</b></td>
+ <td>
+ <h:outputText value="#{AuditTrailItemUIBean.history.status.displayName}"/>
+ </td>
+ </tr>
+ <tr class="revision-data-table-even-row">
+ <td valign="top"><b>Error Message</b></td>
+ <td><pre><h:outputText value="#{AuditTrailItemUIBean.history.errorMessage}" rendered="#{!empty AuditTrailItemUIBean.history.errorMessage}"/></pre></td>
+ </tr>
+ </table>
+</rich:panel>
+
+<p align="center">
+ <h:outputLink value="../content/history.xhtml">
+ <f:param name="id" value="${param.id}"/>
+ <h:outputText value="Return to Package History"/>
+ </h:outputLink>
+</p>
+
+</h:form>
+
+
+</ui:define>
+</ui:composition>
+
+</html>
diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/content/confirm-create-plain.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/content/confirm-create-plain.xhtml
new file mode 100644
index 0000000..3ba40b0
--- /dev/null
+++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/content/confirm-create-plain.xhtml
@@ -0,0 +1,196 @@
+<?xml version="1.0"?>
+
+<!DOCTYPE html
+ PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml"
+ xmlns:h="http://java.sun.com/jsf/html"
+ xmlns:f="http://java.sun.com/jsf/core"
+ xmlns:ui="http://java.sun.com/jsf/facelets"
+ xmlns:c="http://java.sun.com/jstl/core"
+ xmlns:onc="http://jboss.org/on/component"
+ xmlns:rich="http://richfaces.ajax4jsf.org/rich">
+
+<ui:composition template="/rhq/resource/layout/main-plain.xhtml">
+
+ <ui:param name="pageTitle" value="Confirm Deploy Package"/>
+ <ui:param name="selectedTabName" value="Content.New"/>
+ <ui:define name="content">
+
+ <h:form>
+
+ <input type="hidden" name="id" value="${param.id}"/>
+
+ <ui:remove><!-- Package selected for installation steps and they were returned from the plugin. --></ui:remove>
+ <rich:panel rendered="#{!empty InstallationStepsUIBean.packageVersion and !empty InstallationStepsUIBean.deploySteps}">
+
+ <f:facet name="header"><h:outputText value="Installation Steps"/></f:facet>
+
+ <p><b><h:outputText value="Package: #{InstallationStepsUIBean.packageVersion.generalPackage.name} #{InstallationStepsUIBean.packageVersion.displayVersion}"/></b></p>
+
+ <p>The following steps were provided by the plugin. They describe the steps that will take place during
+ the deployment of this package. Please review the steps before deciding whether or not to continue
+ with the deployment.</p>
+
+ <h:dataTable value="#{InstallationStepsUIBean.deploySteps}"
+ var="item"
+ styleClass="instructions-data-table"
+ headerClass="instructions-data-table-header"
+ columnClasses="instructions-data-table-number-col, instructions-data-table-description-col"
+ rowClasses="instructions-data-table-even-row, instructions-data-table-odd-row"
+ cellpadding="3"
+ cellspacing="0"
+ width="100%">
+
+ <h:column>
+ <f:facet name="header">Step Number</f:facet>
+ <h:outputText value="#{InstallationStepsUIBean.stepsData.rowIndex + 1}"/>
+ </h:column>
+
+ <h:column>
+ <f:facet name="header">Description</f:facet>
+ <h:outputText value="#{item.description}"/>
+ </h:column>
+
+ </h:dataTable>
+
+ </rich:panel>
+
+ <ui:remove><!-- Package selected but no installation steps were returned. --></ui:remove>
+ <rich:panel rendered="#{!empty InstallationStepsUIBean.packageVersion and empty InstallationStepsUIBean.deploySteps}">
+
+ <f:facet name="header"><h:outputText value="Installation Steps"/></f:facet>
+
+ <p><b><h:outputText value="Package: #{InstallationStepsUIBean.packageVersion.generalPackage.name} #{InstallationStepsUIBean.packageVersion.displayVersion}"/></b></p>
+
+ <p>No installation steps were provided by the plugin for this package.</p>
+ </rich:panel>
+
+ <ui:remove><!-- Table of packages that are to be deployed in this request. --></ui:remove>
+ <rich:panel>
+ <f:facet name="header"><h:outputText value="Review Packages"/></f:facet>
+ <p>The following packages will be deployed. For each package, the plugin may be able to generate a
+ list of what steps will be performed in the deployment. Click the 'view' button on the desired package
+ to request the instructions from the agent. Note that this will make a live call to the agent
+ and thus may take some time.</p>
+
+ <ui:param name="packagesToDeployDataModel" value="#{DeployPackagesUIBean.dataModel}"/>
+ <rich:dataTable id="packagesToDeployDataTable"
+ rows="#{PageControl.PackagesToDeployList.pageSize}"
+ value="#{packagesToDeployDataModel}"
+ var="item"
+ width="100%"
+ columnsWidth="20%, 15%, 15%, 10%, 32%, 8%"
+ headerClass="tableRowHeader"
+ footerClass="on-pager-footer"
+ onRowMouseOver="this.style.backgroundColor='#E7E7E7'"
+ onRowMouseOut="this.style.backgroundColor='#{a4jSkin.tableBackgroundColor}'">
+
+ <f:facet name="PageControlView">
+ <onc:paginationControl id="PackagesToDeployList" />
+ </f:facet>
+
+ <rich:column>
+ <f:facet name="header">
+ <onc:sortableColumnHeader sort="pv.generalPackage.name">
+ <h:outputText styleClass="headerText" value="Package Name" />
+ </onc:sortableColumnHeader>
+ </f:facet>
+
+ <h:outputText value="#{item.packageName}"/>
+ </rich:column>
+
+ <rich:column>
+ <f:facet name="header">
+ <onc:sortableColumnHeader sort="pv.displayVersion">
+ <h:outputText styleClass="headerText" value="Version" />
+ </onc:sortableColumnHeader>
+ </f:facet>
+
+ <h:outputText value="#{item.packageVersion.displayVersion}"/>
+ </rich:column>
+
+ <rich:column>
+ <f:facet name="header">
+ <onc:sortableColumnHeader sort="pv.generalPackage.packageType.displayName">
+ <h:outputText styleClass="headerText" value="Type" />
+ </onc:sortableColumnHeader>
+ </f:facet>
+
+ <h:outputText value="#{item.packageTypeName}"/>
+ </rich:column>
+
+ <rich:column>
+ <f:facet name="header">
+ <onc:sortableColumnHeader sort="pv.architecture">
+ <h:outputText styleClass="headerText" value="Architecture" />
+ </onc:sortableColumnHeader>
+ </f:facet>
+
+ <h:outputText value="#{item.architectureName}"/>
+ </rich:column>
+
+ <rich:column>
+ <f:facet name="header">
+ <h:outputText styleClass="headerText" value="Description" />
+ </f:facet>
+
+ <h:outputText value="#{item.packageVersion.shortDescription}" escape="false"/>
+ </rich:column>
+
+ <rich:column style="text-align: center;">
+ <f:facet name="header">
+ <h:outputText styleClass="headerText" value="Instructions"/>
+ </f:facet>
+
+ <h:commandLink style="margin-top: 10px;" value="VIEW"
+ action="#{InstallationStepsUIBean.loadSteps}">
+ <f:param name="selectedPackageId" value="#{item.packageVersion.id}"/>
+ </h:commandLink>
+
+ </rich:column>
+
+ <f:facet name="footer">
+ <rich:columnGroup>
+ <rich:column colspan="6" width="100%">
+ <ui:include src="/rhq/resource/include/pagination.xhtml">
+ <ui:param name="paginationDataTableName" value="packagesToDeployDataTable"/>
+ <ui:param name="paginationDataModel" value="#{packagesToDeployDataModel}"/>
+ <ui:param name="paginationPageControl" value="#{PageControl.PackagesToDeployList}"/>
+ </ui:include>
+ </rich:column>
+ </rich:columnGroup>
+ </f:facet>
+
+ </rich:dataTable>
+
+ </rich:panel>
+
+ <rich:panel>
+ <f:facet name="header"><h:outputText value="Packages Deployment Notes"/></f:facet>
+ <p>Notes specified below will be displayed when tracking the status of this request in order to help
+ further identify the purpose of this request. They are not sent to the plugin for use during the
+ installation. </p>
+
+ <h:inputTextarea value="#{DeployPackagesUIBean.notes}" rows="5" cols="80"/>
+
+ </rich:panel>
+
+ <rich:panel>
+ <h:panelGrid id="buttonGrid" columns="2" styleClass="buttons-table" columnClasses="button-cell">
+ <h:commandButton style="margin-top: 10px;" value="CANCEL"
+ action="cancel" styleClass="buttonmed"/>
+
+ <h:commandButton style="margin-top: 10px;" value="CONTINUE"
+ action="#{DeployPackagesUIBean.deployPackages}" styleClass="buttonmed"
+ rendered="${ResourceUIBean.permissions.content}"/>
+ </h:panelGrid>
+ </rich:panel>
+
+ </h:form>
+
+ </ui:define>
+</ui:composition>
+
+</html>
diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/content/confirm-delete-plain.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/content/confirm-delete-plain.xhtml
new file mode 100644
index 0000000..7f410a1
--- /dev/null
+++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/content/confirm-delete-plain.xhtml
@@ -0,0 +1,70 @@
+<?xml version="1.0"?>
+
+<!DOCTYPE html
+ PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml"
+ xmlns:h="http://java.sun.com/jsf/html"
+ xmlns:f="http://java.sun.com/jsf/core"
+ xmlns:ui="http://java.sun.com/jsf/facelets"
+ xmlns:c="http://java.sun.com/jstl/core"
+ xmlns:onc="http://jboss.org/on/component"
+ xmlns:rich="http://richfaces.ajax4jsf.org/rich">
+
+<ui:composition template="/rhq/resource/layout/main-plain.xhtml">
+
+ <ui:param name="pageTitle" value="Confirm Delete Package"/>
+ <ui:param name="selectedTabName" value="Content.Deployed"/>
+ <ui:define name="content">
+
+ <h:form>
+ <input type="hidden" name="id" value="${param.id}"/>
+
+ <rich:panel>
+
+ <f:facet name="header"><h:outputText value="Packages to be Deleted"/></f:facet>
+
+ <p>The following packages will be deleted on the resource.</p>
+
+ <ul>
+ <c:forEach items="#{DeletePackagesUIBean.packagesToDelete}" var="installedPackage">
+ <li>
+ <h:outputText value="${installedPackage.packageVersion.displayName} " rendered="${!empty installedPackage.packageVersion.displayName}"/>
+ <h:outputText value="${installedPackage.packageVersion.generalPackage.name} " rendered="${empty installedPackage.packageVersion.displayName}"/>
+
+ <h:outputText value="${installedPackage.packageVersion.displayVersion}" rendered="${!empty installedPackage.packageVersion.displayVersion}"/>
+ <h:outputText value="${installedPackage.packageVersion.version}" rendered="${empty installedPackage.packageVersion.displayVersion}"/>
+ </li>
+ </c:forEach>
+ </ul>
+
+ </rich:panel>
+
+ <rich:panel>
+ <f:facet name="header"><h:outputText value="Packages Delete Notes"/></f:facet>
+ <p>Notes specified below will be displayed when tracking the status of this request in order to help
+ further identify the purpose of this request. They are not sent to the plugin for use during the
+ the delete attempt. </p>
+
+ <h:inputTextarea value="#{DeletePackagesUIBean.notes}" rows="5" cols="80"/>
+
+ </rich:panel>
+
+ <rich:panel>
+ <h:panelGrid id="buttonGrid" columns="2" styleClass="buttons-table" columnClasses="button-cell">
+ <h:commandButton style="margin-top: 10px;" value="CANCEL"
+ action="cancel" styleClass="buttonmed"/>
+
+ <h:commandButton style="margin-top: 10px;" value="CONTINUE"
+ action="#{DeletePackagesUIBean.deleteSelectedInstalledPackages}" styleClass="buttonmed"
+ rendered="${ResourceUIBean.permissions.content}"/>
+ </h:panelGrid>
+ </rich:panel>
+
+ </h:form>
+
+ </ui:define>
+</ui:composition>
+
+</html>
diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/content/history-request-item-plain.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/content/history-request-item-plain.xhtml
new file mode 100644
index 0000000..de42127
--- /dev/null
+++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/content/history-request-item-plain.xhtml
@@ -0,0 +1,131 @@
+<?xml version="1.0"?>
+
+<!DOCTYPE html
+ PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml"
+ xmlns:h="http://java.sun.com/jsf/html"
+ xmlns:f="http://java.sun.com/jsf/core"
+ xmlns:ui="http://java.sun.com/jsf/facelets"
+ xmlns:c="http://java.sun.com/jstl/core"
+ xmlns:onc="http://jboss.org/on/component"
+ xmlns:onf="http://jboss.org/on/function"
+ xmlns:rich="http://richfaces.ajax4jsf.org/rich">
+
+<ui:composition template="/rhq/resource/layout/main-plain.xhtml">
+
+<ui:param name="pageTitle" value="View Content for Resource '#{ResourceUIBean.name}'"/>
+<ui:param name="selectedTabName" value="Content.History"/>
+
+<ui:define name="content">
+
+<!-- Content Requests Table -->
+
+<h:form id="contentRequestsForm">
+<input type="hidden" name="id" value="${param.id}"/>
+
+<rich:panel>
+ <f:facet name="header"><h:outputText value="Package Details"/></f:facet>
+
+ <ui:remove><!-- Ultimately, this page should display the deployment time configuration values specified by
+ the user. --></ui:remove>
+
+ <table class="revision-data-table" width="100%">
+ <tr class="revision-data-table-even-row">
+ <td><b>Package Name</b></td>
+ <td>
+ <h:outputText value="#{ShowInstalledPackageHistoryUIBean.history.packageVersion.displayName}"
+ rendered="#{!empty ShowInstalledPackageHistoryUIBean.history.packageVersion.displayName}"/>
+ <h:outputText value="#{ShowInstalledPackageHistoryUIBean.history.packageVersion.generalPackage.name}"
+ rendered="#{empty ShowInstalledPackageHistoryUIBean.history.packageVersion.displayName}"/>
+
+ </td>
+ </tr>
+ <tr class="revision-data-table-odd-row">
+ <td><b>Version</b></td>
+ <td>
+ <h:outputText value="#{ShowInstalledPackageHistoryUIBean.history.packageVersion.displayVersion}"
+ rendered="#{!empty ShowInstalledPackageHistoryUIBean.history.packageVersion.displayVersion}"/>
+ <h:outputText value="#{ShowInstalledPackageHistoryUIBean.history.packageVersion.version}"
+ rendered="#{empty ShowInstalledPackageHistoryUIBean.history.packageVersion.displayVersion}"/>
+ </td>
+ </tr>
+ <tr class="revision-data-table-even-row">
+ <td><b>Architecture</b></td>
+ <td>
+ <h:outputText value="#{ShowInstalledPackageHistoryUIBean.history.packageVersion.architecture.name}"/>
+ </td>
+ </tr>
+ <tr class="revision-data-table-odd-row">
+ <td><b>Result</b></td>
+ <td>
+ <h:outputText value="#{ShowInstalledPackageHistoryUIBean.history.status.displayName}"/>
+ </td>
+ </tr>
+ <tr class="revision-data-table-even-row">
+ <td valign="top"><b>Error Message</b></td>
+ <td><pre><h:outputText value="#{ShowInstalledPackageHistoryUIBean.history.errorMessage}" rendered="#{!empty ShowInstalledPackageHistoryUIBean.history.errorMessage}"/></pre></td>
+ </tr>
+ </table>
+</rich:panel>
+
+<rich:panel rendered="#{!empty ShowInstalledPackageHistoryUIBean.installationSteps}">
+ <f:facet name="header"><h:outputText value="Installation Step Details"/></f:facet>
+
+ <h:dataTable value="#{ShowInstalledPackageHistoryUIBean.installationSteps}"
+ var="item"
+ styleClass="instructions-data-table"
+ headerClass="instructions-data-table-header"
+ columnClasses="instructions-data-table-number-col, instructions-data-table-description-col"
+ rowClasses="instructions-data-table-even-row, instructions-data-table-odd-row"
+ cellpadding="3"
+ cellspacing="0"
+ width="100%">
+
+ <h:column>
+ <f:facet name="header">Step Number</f:facet>
+ <h:outputText value="#{ShowInstalledPackageHistoryUIBean.stepsData.rowIndex + 1}"/>
+ </h:column>
+
+ <h:column>
+ <f:facet name="header">Description</f:facet>
+ <h:outputText value="#{item.description}"/>
+ </h:column>
+
+ <h:column>
+ <f:facet name="header">Errors</f:facet>
+
+ <h:commandLink action="stepDetails" value="View" rendered="#{!empty item.errorMessage}">
+ <f:param name="id" value="${param.id}"/>
+ <f:param name="stepId" value="#{item.id}"/>
+ <f:param name="selectedRequestId" value="${param.selectedRequestId}"/>
+ <f:param name="selectedHistoryId" value="${param.selectedHistoryId}"/>
+ </h:commandLink>
+
+ </h:column>
+
+ <h:column>
+ <f:facet name="header">Result</f:facet>
+ <h:outputText value="#{item.result}"/>
+ </h:column>
+
+ </h:dataTable>
+
+</rich:panel>
+
+<p align="center">
+ <h:commandLink action="returnToRequest" value="Return to Request Details">
+ <f:param name="id" value="${param.id}"/>
+ <f:param name="selectedRequestId" value="${param.selectedRequestId}"/>
+ <f:param name="selectedHistoryId" value="${param.selectedHistoryId}"/>
+ </h:commandLink>
+</p>
+
+</h:form>
+
+
+</ui:define>
+</ui:composition>
+
+</html>
diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/content/history-request-plain.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/content/history-request-plain.xhtml
new file mode 100644
index 0000000..1419931
--- /dev/null
+++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/content/history-request-plain.xhtml
@@ -0,0 +1,189 @@
+<?xml version="1.0"?>
+
+<!DOCTYPE html
+ PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml"
+ xmlns:h="http://java.sun.com/jsf/html"
+ xmlns:f="http://java.sun.com/jsf/core"
+ xmlns:ui="http://java.sun.com/jsf/facelets"
+ xmlns:c="http://java.sun.com/jstl/core"
+ xmlns:onc="http://jboss.org/on/component"
+ xmlns:onf="http://jboss.org/on/function"
+ xmlns:rich="http://richfaces.ajax4jsf.org/rich">
+
+<ui:composition template="/rhq/resource/layout/main-plain.xhtml">
+
+<ui:param name="pageTitle" value="View Content for Resource '#{ResourceUIBean.name}'"/>
+<ui:param name="selectedTabName" value="Content.History"/>
+
+<ui:define name="metaHeaders">
+ <meta http-equiv="refresh" content="10"/>
+</ui:define>
+
+<ui:define name="content">
+
+<!-- Content Requests Table -->
+
+<h:form id="contentRequestsForm">
+<input type="hidden" name="id" value="${param.id}"/>
+
+<rich:panel>
+ <f:facet name="header"><h:outputText value="Request Details"/></f:facet>
+ <ui:param name="csr" value="#{ShowContentServiceRequestUIBean.contentServiceRequest}"/>
+
+ <table class="revision-data-table" width="100%">
+
+ <tr class="revision-data-table-even-row">
+ <td valign="top"><b>Status</b></td>
+ <td><h:outputText value="#{csr.status}"/></td>
+ </tr>
+
+ <tr class="revision-data-table-odd-row">
+ <td valign="top"><b>Request Type</b></td>
+ <td><h:outputText value="#{csr.contentRequestType}"/></td>
+ </tr>
+
+ <tr class="revision-data-table-even-row">
+ <td valign="top"><b>Timestamp</b></td>
+ <td><h:outputText value="#{csr.createdDate}"/></td>
+ </tr>
+
+ <tr class="revision-data-table-odd-row">
+ <td valign="top"><b>User</b></td>
+ <td><h:outputText value="#{csr.subjectName}"/></td>
+ </tr>
+
+ <tr class="revision-data-table-even-row">
+ <td valign="top"><b>Notes</b></td>
+ <td><h:outputText value="#{csr.notes}"/></td>
+ </tr>
+
+ <tr class="revision-data-table-odd-row">
+ <td valign="top"><b>Error</b></td>
+ <td><pre><h:outputText value="#{csr.errorMessage}"/></pre></td>
+ </tr>
+
+ </table>
+
+</rich:panel>
+
+<rich:panel>
+ <f:facet name="header"><h:outputText value="Package Audit Trail"/></f:facet>
+
+ <p>The following is a complete listing of all of the package operations that took place during this request.
+ By default, they are ordered from newest to oldest. In other words, for packages that are referenced more than
+ one time in this list, the most recent item indicates the current status of the package.</p>
+
+ <ui:param name="packageHistoryDataModel" value="#{ShowContentServiceRequestUIBean.dataModel}"/>
+ <rich:dataTable id="packageHistoryDataTable"
+ rows="#{PageControl.InstalledPackageHistoryList.pageSize}"
+ value="#{packageHistoryDataModel}"
+ var="item"
+ width="100%"
+ columnsWidth="20%, 20%, 20%, 10%, 20%, 10%"
+ headerClass="tableRowHeader"
+ footerClass="on-pager-footer"
+ onRowMouseOver="this.style.backgroundColor='#E7E7E7'"
+ onRowMouseOut="this.style.backgroundColor='#{a4jSkin.tableBackgroundColor}'">
+
+ <f:facet name="PageControlView">
+ <onc:paginationControl id="PackagesToDeployList" />
+ </f:facet>
+
+ <rich:column>
+ <f:facet name="header">
+ <onc:sortableColumnHeader sort="iph.packageVersion.displayName">
+ <h:outputText styleClass="headerText" value="Package Name" />
+ </onc:sortableColumnHeader>
+ </f:facet>
+
+ <h:outputText value="#{item.packageVersion.displayName}" rendered="#{!empty item.packageVersion.displayName}"/>
+ <h:outputText value="#{item.packageVersion.generalPackage.name}" rendered="#{empty item.packageVersion.displayName}"/>
+ </rich:column>
+
+ <rich:column>
+ <f:facet name="header">
+ <onc:sortableColumnHeader sort="iph.packageVersion.displayVersion">
+ <h:outputText styleClass="headerText" value="Version" />
+ </onc:sortableColumnHeader>
+ </f:facet>
+
+ <h:outputText value="#{item.packageVersion.displayVersion}"/>
+ </rich:column>
+
+ <rich:column>
+ <f:facet name="header">
+ <onc:sortableColumnHeader sort="iph.packageVersion.architecture">
+ <h:outputText styleClass="headerText" value="Architecture" />
+ </onc:sortableColumnHeader>
+ </f:facet>
+
+ <h:outputText value="#{item.packageVersion.architecture.name}"/>
+ </rich:column>
+
+ <rich:column>
+ <f:facet name="header">
+ <onc:sortableColumnHeader sort="iph.status.displayName">
+ <h:outputText styleClass="headerText" value="Status" />
+ </onc:sortableColumnHeader>
+ </f:facet>
+
+ <h:outputText value="#{item.status.displayName}"/>
+ </rich:column>
+
+ <rich:column>
+ <f:facet name="header">
+ <onc:sortableColumnHeader sort="iph.timestamp">
+ <h:outputText styleClass="headerText" value="Timestamp" />
+ </onc:sortableColumnHeader>
+ </f:facet>
+
+ <h:outputText value="#{item.timestamp}">
+ <f:converter converterId="UserDateTimeConverter" />
+ </h:outputText>
+ </rich:column>
+
+ <rich:column>
+ <f:facet name="header">
+ <h:outputText styleClass="headerText" value="Details" />
+ </f:facet>
+
+ <h:commandLink style="margin-top: 10px;" value="VIEW"
+ action="showHistoryItem">
+ <f:param name="selectedRequestId" value="#{ShowContentServiceRequestUIBean.selectedRequestId}"/>
+ <f:param name="selectedHistoryId" value="#{item.id}"/>
+ </h:commandLink>
+
+ </rich:column>
+
+ <f:facet name="footer">
+ <rich:columnGroup>
+ <rich:column colspan="6" width="100%">
+ <ui:include src="/rhq/resource/include/pagination.xhtml">
+ <ui:param name="paginationDataTableName" value="packageHistoryDataTable"/>
+ <ui:param name="paginationDataModel" value="#{packageHistoryDataModel}"/>
+ <ui:param name="paginationPageControl" value="#{PageControl.InstalledPackageHistoryList}"/>
+ </ui:include>
+ </rich:column>
+ </rich:columnGroup>
+ </f:facet>
+
+ </rich:dataTable>
+
+</rich:panel>
+
+<p align="center">
+ <h:commandLink action="returnToAllRequests" value="Return to Request List">
+ <f:param name="id" value="${param.id}"/>
+ <f:param name="selectedRequestId" value="${param.selectedRequestId}"/>
+ </h:commandLink>
+</p>
+
+</h:form>
+
+</ui:define>
+</ui:composition>
+
+</html>
diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/content/history-request-step-details-plain.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/content/history-request-step-details-plain.xhtml
new file mode 100644
index 0000000..c7631e2
--- /dev/null
+++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/content/history-request-step-details-plain.xhtml
@@ -0,0 +1,57 @@
+<?xml version="1.0"?>
+
+<!DOCTYPE html
+ PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml"
+ xmlns:h="http://java.sun.com/jsf/html"
+ xmlns:f="http://java.sun.com/jsf/core"
+ xmlns:ui="http://java.sun.com/jsf/facelets"
+ xmlns:c="http://java.sun.com/jstl/core"
+ xmlns:onc="http://jboss.org/on/component"
+ xmlns:onf="http://jboss.org/on/function"
+ xmlns:rich="http://richfaces.ajax4jsf.org/rich">
+
+<ui:composition template="/rhq/resource/layout/main-plain.xhtml">
+
+<ui:param name="pageTitle" value="View Content for Resource '#{ResourceUIBean.name}'"/>
+<ui:param name="selectedTabName" value="Content.History"/>
+
+<ui:define name="content">
+
+<!-- Content Requests Table -->
+
+<h:form id="contentRequestsForm">
+<input type="hidden" name="id" value="${param.id}"/>
+
+<rich:panel>
+ <f:facet name="header"><h:outputText value="Step Error"/></f:facet>
+
+ <p>
+ <b>Step Description:</b><br/>
+ <h:outputText value="#{ShowInstalledPackageHistoryUIBean.step.description}"/>
+ </p>
+
+ <b>Error Message:</b><br/>
+ <pre>
+ <h:outputText value="#{ShowInstalledPackageHistoryUIBean.step.errorMessage}"/>
+ </pre>
+
+ <p align="center">
+ <h:commandLink action="returnToHistory" value="Return to History Entry">
+ <f:param name="id" value="${param.id}"/>
+ <f:param name="selectedRequestId" value="${param.selectedRequestId}"/>
+ <f:param name="selectedHistoryId" value="${param.selectedHistoryId}"/>
+ </h:commandLink>
+ </p>
+
+</rich:panel>
+
+</h:form>
+
+
+</ui:define>
+</ui:composition>
+
+</html>
diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/content/subscription_packages-plain.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/content/subscription_packages-plain.xhtml
new file mode 100644
index 0000000..6bb83b6
--- /dev/null
+++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/content/subscription_packages-plain.xhtml
@@ -0,0 +1,114 @@
+<?xml version="1.0"?>
+
+<!DOCTYPE html
+ PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml"
+ xmlns:h="http://java.sun.com/jsf/html"
+ xmlns:f="http://java.sun.com/jsf/core"
+ xmlns:ui="http://java.sun.com/jsf/facelets"
+ xmlns:c="http://java.sun.com/jstl/core"
+ xmlns:onc="http://jboss.org/on/component"
+ xmlns:onf="http://jboss.org/on/function"
+ xmlns:rich="http://richfaces.ajax4jsf.org/rich">
+
+<ui:composition template="/rhq/resource/layout/main-plain.xhtml">
+
+ <ui:param name="pageTitle" value="View Repo Subscriptions for Resource '#{ResourceUIBean.name}'"/>
+ <ui:param name="selectedTabName" value="Content.Subscriptions"/>
+
+ <ui:define name="content">
+
+ <!-- CURRENT REPOS -->
+ <h:form id="currentPackageVersionsForm">
+ <input type="hidden" name="id" value="${param.id}"/>
+
+ <rich:panel styleClass="BlockContent">
+ <f:facet name="header"><h:outputText value="Currently Subscribed Resource Packages"/></f:facet>
+
+ <ui:param name="resourcePackageVersionsDataModel" value="#{ResourcePackageVersionsUIBean.dataModel}"/>
+ <rich:dataTable id="resourcePackageVersionsDataTable"
+ rows="#{PageControl.ResourcePackageVersionsList.pageSize}"
+ value="#{resourcePackageVersionsDataModel}"
+ var="item"
+ width="100%"
+ columnsWidth="17%, 11%, 9%"
+ headerClass="tableRowHeader"
+ footerClass="on-pager-footer"
+ onRowMouseOver="this.style.backgroundColor='#E7E7E7'"
+ onRowMouseOut="this.style.backgroundColor='#{a4jSkin.tableBackgroundColor}'">
+
+ <f:facet name="PageControlView">
+ <onc:paginationControl id="ResourcePackageVersionsList" />
+ </f:facet>
+
+ <rich:column rendered="#{param.debug}">
+ <f:facet name="header">
+ <onc:sortableColumnHeader sort="pv.id">
+ <h:outputText styleClass="headerText" value="ID" />
+ </onc:sortableColumnHeader>
+ </f:facet>
+
+ <h:outputText value="#{item.id}"/>
+ </rich:column>
+
+ <rich:column>
+ <f:facet name="header">
+ <onc:sortableColumnHeader sort="pv.fileName">
+ <h:outputText styleClass="headerText" value="File Name" />
+ </onc:sortableColumnHeader>
+ </f:facet>
+
+ <h:outputText value="#{item.packageVersion.fileName}"/>
+ </rich:column>
+
+ <rich:column>
+ <f:facet name="header">
+ <onc:sortableColumnHeader sort="pv.displayVersion">
+ <h:outputText styleClass="headerText" value="Version" />
+ </onc:sortableColumnHeader>
+ </f:facet>
+
+ <h:outputText value="#{item.packageVersion.displayVersion}"/>
+ </rich:column>
+
+ <rich:column>
+ <f:facet name="header">
+ <onc:sortableColumnHeader sort="pv.generalPackage.packageType.name">
+ <h:outputText styleClass="headerText" value="Type" />
+ </onc:sortableColumnHeader>
+ </f:facet>
+
+ <h:outputText value="#{item.packageTypeName}"/>
+ </rich:column>
+
+ <f:facet name="footer">
+ <rich:columnGroup>
+ <rich:column colspan="#{param.debug ? 4 : 3}" width="100%">
+
+ <ui:include src="/rhq/resource/include/pagination.xhtml">
+ <ui:param name="paginationDataTableName" value="resourcePackageVersionsDataTable"/>
+ <ui:param name="paginationDataModel" value="#{resourcePackageVersionsDataModel}"/>
+ <ui:param name="paginationPageControl" value="#{PageControl.ResourcePackageVersionsList}"/>
+ </ui:include>
+ </rich:column>
+ </rich:columnGroup>
+ </f:facet>
+
+ </rich:dataTable>
+
+ </rich:panel>
+ </h:form>
+
+ <p align="center">
+ <h:outputLink value="/rhq/resource/content/subscription.xhtml">
+ <f:param name="id" value="${param.id}"/>
+ <h:outputText value="Switch To Repo Mode" />
+ </h:outputLink>
+ </p>
+
+ </ui:define>
+</ui:composition>
+
+</html>
diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/content/update-plain.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/content/update-plain.xhtml
new file mode 100644
index 0000000..ab99878
--- /dev/null
+++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/content/update-plain.xhtml
@@ -0,0 +1,154 @@
+<?xml version="1.0"?>
+
+<!DOCTYPE html
+ PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml"
+ xmlns:h="http://java.sun.com/jsf/html"
+ xmlns:f="http://java.sun.com/jsf/core"
+ xmlns:ui="http://java.sun.com/jsf/facelets"
+ xmlns:c="http://java.sun.com/jstl/core"
+ xmlns:onc="http://jboss.org/on/component"
+ xmlns:a4j="https://ajax4jsf.dev.java.net/ajax"
+ xmlns:rich="http://richfaces.ajax4jsf.org/rich">
+
+<ui:composition template="/rhq/resource/layout/main-plain.xhtml">
+
+ <ui:param name="pageTitle" value="Update Existing Package"/>
+ <ui:param name="selectedTabName" value="Content.Update"/>
+ <ui:define name="content">
+
+ <h:form id="currentPackageVersionsForm">
+ <input type="hidden" name="id" value="${param.id}"/>
+
+ <rich:panel styleClass="BlockContent">
+ <f:facet name="header"><h:outputText value="Packages Eligible for Update"/></f:facet>
+
+ <p>The following packages were found from the repositories currently subscribed to by this resource. In order
+ to enable more existing packages for deployment, use the subscriptions sub-tab to subscribe this resource
+ to more repositories.</p>
+
+ <a4j:keepAlive beanName="ResourceUpdatePackageVersionsUIBean"/>
+
+ <ui:param name="resourceUpdatePackageVersionsDataModel" value="#{ResourceUpdatePackageVersionsUIBean.dataModel}"/>
+ <rich:dataTable id="resourceUpdatePackageVersionsDataTable"
+ rows="#{PageControl.ResourceUpdatePackageVersionsList.pageSize}"
+ value="#{resourceUpdatePackageVersionsDataModel}"
+ var="item"
+ width="100%"
+ columnsWidth="1%, 15%, 10%, 10%, 10%, 54%"
+ headerClass="tableRowHeader"
+ footerClass="on-pager-footer"
+ onRowMouseOver="this.style.backgroundColor='#E7E7E7'"
+ onRowMouseOut="this.style.backgroundColor='#{a4jSkin.tableBackgroundColor}'">
+
+ <f:facet name="PageControlView">
+ <onc:paginationControl id="ResourceUpdatePackageVersionsList" />
+ </f:facet>
+
+ <rich:column>
+ <f:facet name="header">
+ <onc:allSelect target="selectedPackages" />
+ </f:facet>
+
+ <onc:select name="selectedPackages" value="#{item.packageVersion.id}"/>
+ </rich:column>
+
+ <rich:column>
+ <f:facet name="header">
+ <onc:sortableColumnHeader sort="pv.generalPackage.name">
+ <h:outputText styleClass="headerText" value="Package Name" />
+ </onc:sortableColumnHeader>
+ </f:facet>
+
+ <h:outputLink value="../../content/packageVersion.xhtml">
+ <f:param name="id" value="#{item.packageVersion.id}"/>
+ <h:outputText value="#{item.packageName}"/>
+ </h:outputLink>
+
+ </rich:column>
+
+ <rich:column>
+ <f:facet name="header">
+ <onc:sortableColumnHeader sort="pv.displayVersion">
+ <h:outputText styleClass="headerText" value="Version" />
+ </onc:sortableColumnHeader>
+ </f:facet>
+
+ <h:outputText value="#{item.packageVersion.displayVersion}"/>
+ </rich:column>
+
+ <rich:column>
+ <f:facet name="header">
+ <onc:sortableColumnHeader sort="pv.generalPackage.packageType.displayName">
+ <h:outputText styleClass="headerText" value="Type" />
+ </onc:sortableColumnHeader>
+ </f:facet>
+
+ <h:outputText value="#{item.packageTypeName}"/>
+ </rich:column>
+
+ <rich:column>
+ <f:facet name="header">
+ <onc:sortableColumnHeader sort="pv.architecture">
+ <h:outputText styleClass="headerText" value="Architecture" />
+ </onc:sortableColumnHeader>
+ </f:facet>
+
+ <h:outputText value="#{item.architectureName}"/>
+ </rich:column>
+
+ <rich:column>
+ <f:facet name="header">
+ <h:outputText styleClass="headerText" value="Description" />
+ </f:facet>
+
+ <h:outputText value="#{item.packageVersion.shortDescription}" escape="false"/>
+ </rich:column>
+
+ <f:facet name="footer">
+ <rich:columnGroup>
+ <rich:column colspan="6" width="100%">
+ <onc:selectCommandButton action="#{CreateNewPackageUIBean.deployExisting}"
+ value="DEPLOY SELECTED" target="selectedPackages" styleClass="on-pager-button buttonsmall"
+ rendered="${ResourceUIBean.permissions.content}"/>
+
+ <ui:include src="/rhq/resource/include/pagination.xhtml">
+ <ui:param name="paginationDataTableName" value="resourceUpdatePackageVersionsDataTable"/>
+ <ui:param name="paginationDataModel" value="#{resourceUpdatePackageVersionsDataModel}"/>
+ <ui:param name="paginationPageControl" value="#{PageControl.ResourceUpdatePackageVersionsList}"/>
+ </ui:include>
+ </rich:column>
+ </rich:columnGroup>
+ </f:facet>
+
+ </rich:dataTable>
+
+
+ </rich:panel>
+
+ <rich:panel styleClass="BlockContent"
+ rendered="${ResourceUIBean.permissions.content}">
+ <f:facet name="header"><h:outputText value="Upload New Package"/></f:facet>
+
+ <p>The following option will begin the workflow to upload a new package into the system. Once
+ the package information has been specified and the file uploaded, the workflow to deploy the newly
+ created package to this resource will resume.</p>
+
+ <h:panelGrid columns="1" styleClass="buttons-table" columnClasses="button-cell">
+ <h:commandButton action="uploadNew"
+ value="UPLOAD NEW PACKAGE" styleClass="buttonmed"/>
+ </h:panelGrid>
+
+ <br/>
+ </rich:panel>
+
+
+ </h:form>
+
+
+ </ui:define>
+</ui:composition>
+
+</html>
commit 03a95ebff5116019ccece5604550ced776a1ce2e
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Thu Mar 3 13:14:12 2011 +0100
Fixing the ContentManagerLocal.getUploadedPackageVersion() and thus enabling the content upload from the resource content tab again.
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/PackageVersionFileUploadServlet.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/PackageVersionFileUploadServlet.java
index 02d69a4..9aed016 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/PackageVersionFileUploadServlet.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/PackageVersionFileUploadServlet.java
@@ -85,7 +85,7 @@ public class PackageVersionFileUploadServlet extends FileUploadServlet {
metaData.put(ContentManagerLocal.UPLOAD_FILE_INSTALL_DATE, Long.toString(file.lastModified()));
metaData.put(ContentManagerLocal.UPLOAD_FILE_NAME, packageName);
PackageVersion packageVersion = contentManager.getUploadedPackageVersion(subject, packageName,
- packageTypeId, version, architectureId, fileStream, metaData, null, repoId);
+ packageTypeId, version, architectureId, fileStream, metaData, repoId);
successMsg = "success [packageVersionId=" + packageVersion.getId() + ",packageId=" + packageVersion.getGeneralPackage().getId() + "]";
} catch (Exception e) {
diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/content/CreateNewPackageUIBean.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/content/CreateNewPackageUIBean.java
index 7c1cf1d..17ada7a 100644
--- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/content/CreateNewPackageUIBean.java
+++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/content/CreateNewPackageUIBean.java
@@ -240,15 +240,12 @@ public class CreateNewPackageUIBean {
packageUploadDetails.put(ContentManagerLocal.UPLOAD_SHA256, new MessageDigestGenerator(
MessageDigestGenerator.SHA_256).calcDigestString(fileItem.getFile()));
} catch (IOException e1) {
- log.warn("Error calculating file digest(s) : " + e1.getMessage());
- e1.printStackTrace();
+ log.warn("Error calculating file digest(s)", e1);
}
- //TODO: need to get parent id instead right? ref to app server inst itself?
- Integer newResourceTypeId = resource == null ? null : resource.getResourceType().getId();
Integer iRepoId = usingARepo ? Integer.parseInt(repoId) : null;
packageVersion = contentManager.getUploadedPackageVersion(subject, packageName, packageTypeId,
- version, architectureId, packageStream, packageUploadDetails, newResourceTypeId, iRepoId);
+ version, architectureId, packageStream, packageUploadDetails, iRepoId);
} catch (NoResultException nre) {
//eat the exception. Some of the queries return no results if no package yet exists which is fine.
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerBean.java
index 2713ff4..9915959 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerBean.java
@@ -1617,10 +1617,9 @@ public class ContentManagerBean implements ContentManagerLocal, ContentManagerRe
@SuppressWarnings("unchecked")
public PackageVersion getUploadedPackageVersion(Subject subject, String packageName, int packageTypeId,
String version, int architectureId, InputStream packageBitStream,
- Map<String, String> packageUploadDetails, Integer newResourceTypeId, Integer repoId) {
+ Map<String, String> packageUploadDetails, Integer repoId) {
PackageVersion packageVersion = null;
- PackageType packageType = null;
//default version to 1.0 if is null, not provided for any reason.
if ((version == null) || (version.trim().length() == 0)) {
@@ -1628,31 +1627,33 @@ public class ContentManagerBean implements ContentManagerLocal, ContentManagerRe
}
Architecture architecture = entityManager.find(Architecture.class, architectureId);
+ PackageType packageType = entityManager.find(PackageType.class, packageTypeId);
// See if package version already exists for the resource package
- if (newResourceTypeId != null) {
- Query packageVersionQuery = null;
+ Query packageVersionQuery = null;
+ if (packageType.getResourceType() != null) {
packageVersionQuery = entityManager.createNamedQuery(PackageVersion.QUERY_FIND_BY_PACKAGE_DETAILS_KEY_WITH_NON_NULL_RESOURCE_TYPE);
- packageVersionQuery.setParameter("resourceTypeId", newResourceTypeId);
-
- packageVersionQuery.setFlushMode(FlushModeType.COMMIT);
- packageVersionQuery.setParameter("packageName", packageName);
+ packageVersionQuery.setParameter("resourceTypeId", packageType.getResourceType().getId());
- packageType = contentManager.getResourceCreationPackageType(newResourceTypeId);
- packageVersionQuery.setParameter("packageTypeName", packageType.getName());
+ } else {
+ packageVersionQuery = entityManager.createNamedQuery(PackageVersion.QUERY_FIND_BY_PACKAGE_DETAILS_KEY);
+ packageVersionQuery.setParameter("resourceType", null);
+ }
- packageVersionQuery.setParameter("architectureName", architecture.getName());
- packageVersionQuery.setParameter("version", version);
+ packageVersionQuery.setFlushMode(FlushModeType.COMMIT);
+ packageVersionQuery.setParameter("packageName", packageName);
+
+ packageVersionQuery.setParameter("packageTypeName", packageType.getName());
- // Result of the query should be either 0 or 1
- List<PackageVersion> existingPackageVersionList = packageVersionQuery.getResultList();
+ packageVersionQuery.setParameter("architectureName", architecture.getName());
+ packageVersionQuery.setParameter("version", version);
- if (existingPackageVersionList.size() > 0) {
- packageVersion = existingPackageVersionList.get(0);
- }
- } else {
- packageType = entityManager.find(PackageType.class, packageTypeId);
+ // Result of the query should be either 0 or 1
+ List<PackageVersion> existingPackageVersionList = packageVersionQuery.getResultList();
+
+ if (existingPackageVersionList.size() > 0) {
+ packageVersion = existingPackageVersionList.get(0);
}
try {
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerLocal.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerLocal.java
index b4644d0..4295e3a 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerLocal.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerLocal.java
@@ -241,9 +241,9 @@ public interface ContentManagerLocal {
int architectureId, InputStream packageBitStream);
/**
- * This method is similar to the {@link #createPackageVersion(Subject, String, int, String, int, InputStream)} but fails if
- * the package version with the provided details already exists which is a desired behaviour for the GUI originating
- * requests.
+ * This method is essentially the same as {@link #createPackageVersion(Subject, String, int, String, int, InputStream)}
+ * but will update the package bits if a package version with the provided identification already exists.
+ *
* @param subject the current user
* @param packageName the name of the package (the general package will be created if none exists)
* @param packageTypeId the id of the package type. This is ignored if the <code>newResourceTypeId</code> is not null
@@ -251,14 +251,11 @@ public interface ContentManagerLocal {
* @param architectureId the architecture of the package version
* @param packageBitStream the input stream with the package bits
* @param packageUploadDetails additional details about the package. See the constants defined in this interface
- * @param newResourceTypeId the resource type id the package version should be bound to. This is to support the usecase
- * where a package version is being created as the backing content of a resource.
* @param repoId an optional id of the repo to insert the package version in
- *
* @return the newly create package version
*/
PackageVersion getUploadedPackageVersion(Subject subject, String packageName, int packageTypeId, String version,
- int architectureId, InputStream packageBitStream, Map<String, String> packageUploadDetails, Integer newResourceTypeId, Integer repoId);
+ int architectureId, InputStream packageBitStream, Map<String, String> packageUploadDetails, Integer repoId);
/**
* Very simple method that persists the given package version within its own transaction.
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceFactoryManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceFactoryManagerBean.java
index 8d5fad4..cad1e08 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceFactoryManagerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceFactoryManagerBean.java
@@ -467,7 +467,7 @@ public class ResourceFactoryManagerBean implements ResourceFactoryManagerLocal,
newPackageType.getId(), packageVersionNumber, architectureId, packageBitStream);
} else {
packageVersion = contentManager.getUploadedPackageVersion(user, packageName,
- newPackageType.getId(), packageVersionNumber, architectureId, packageBitStream, packageUploadDetails, newResourceTypeId, null);
+ newPackageType.getId(), packageVersionNumber, architectureId, packageBitStream, packageUploadDetails, null);
}
return doCreatePackageBackedResource(user, parentResource, newResourceType, newResourceName,
commit 04806d4a5dc6a9ce36b45bf5fd6cfa50bdf68812
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Wed Mar 2 14:02:19 2011 +0100
Finish i18n of the CLI notification form + a minor correction in setting the version field.
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/CliNotificationSenderForm.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/CliNotificationSenderForm.java
index dd18191..38dbf8b 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/CliNotificationSenderForm.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/CliNotificationSenderForm.java
@@ -139,7 +139,7 @@ public class CliNotificationSenderForm extends AbstractNotificationSenderForm {
protected List<FormItem> getOnDrawItems() {
List<FormItem> items = super.getOnDrawItems();
- TextItem version = new TextItem("editableVersion", "Version"); //TODO i18n
+ TextItem version = new TextItem("editableVersion", MSG.view_alert_definition_notification_cliScript_editor_newScriptVersion());
version.setColSpan(getNumCols());
version.addChangedHandler(new ChangedHandler() {
public void onChanged(ChangedEvent event) {
@@ -225,7 +225,7 @@ public class CliNotificationSenderForm extends AbstractNotificationSenderForm {
SectionItem userSection = new SectionItem("userSection");
userSection.setDefaultValue(MSG.view_alert_definition_notification_cliScript_editor_whichUser());
- repoSelector = new SelectItem(extendLocatorId("repoSelector"), "Select the repository to look for the script in"); //TODO i18n
+ repoSelector = new SelectItem(extendLocatorId("repoSelector"), MSG.view_alert_definition_notification_cliScript_editor_selectRepo());
repoSelector.setDefaultToFirstOption(true);
repoSelector.setWrapTitle(false);
repoSelector.setWidth(400);
@@ -594,6 +594,7 @@ public class CliNotificationSenderForm extends AbstractNotificationSenderForm {
if (event.getItem() instanceof UploadItem) {
if (event.getNewValue() == null) {
uploadForm.getField("editableVersion").setValue("");
+ uploadForm.getField("version").setValue("");
return;
}
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 c20d997..a0d6421 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
@@ -1012,6 +1012,8 @@ view_alert_definition_notification_cliScript_editor_loadFailed = Loading the CLI
view_alert_definition_notification_cliScript_editor_selectRepoFirst = Select a repo first.
view_alert_definition_notification_cliScript_editor_existingScript = Existing Script
view_alert_definition_notification_cliScript_editor_uploadNewScript = Upload New Script
+view_alert_definition_notification_cliScript_editor_newScriptVersion = Version
+view_alert_definition_notification_cliScript_editor_selectRepo = Select the repository where the script should reside
view_alert_definition_recovery_editor_disable_when_fired = Disable When Fired
view_alert_definition_recovery_editor_disable_when_fired_tooltip = Indicates if this alert will be disabled after it fires. Once disabled, the alert can be manually re-enabled or a recovery alert can be set up to automatically re-enable it. If this alert is a recovery alert itself, this setting cannot be turned on.
view_alert_definition_recovery_editor_recovery_alert = Recover Alert
commit 219e643126f785902ea29530d3601442103e0fe4
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Wed Mar 2 13:51:45 2011 +0100
forgot to change the cli package type name to the new value in the cli package type plugin itself, d'oh! :)
diff --git a/modules/enterprise/server/plugins/packagetype-cli/src/main/java/org/rhq/enterprise/server/plugins/packagetypeCli/CliPackageTypeBehavior.java b/modules/enterprise/server/plugins/packagetype-cli/src/main/java/org/rhq/enterprise/server/plugins/packagetypeCli/CliPackageTypeBehavior.java
index ea9c376..634539a 100644
--- a/modules/enterprise/server/plugins/packagetype-cli/src/main/java/org/rhq/enterprise/server/plugins/packagetypeCli/CliPackageTypeBehavior.java
+++ b/modules/enterprise/server/plugins/packagetype-cli/src/main/java/org/rhq/enterprise/server/plugins/packagetypeCli/CliPackageTypeBehavior.java
@@ -54,7 +54,7 @@ public class CliPackageTypeBehavior extends AbstractPackageTypeBehavior<ServerPl
private static final String OSGI_EXTRACT_REGEX = "^([^:]+:)?(\\d+(\\.\\d+(\\.\\d+(\\..*)?)?)?)$";
private static final int OSGI_EXTRACT_VERSION_GROUP = 2;
- private static final String PACKAGETYPE_NAME = "__SERVER_SIDE_CLI_SCRIPT";
+ private static final String PACKAGETYPE_NAME = "org.rhq.enterprise.server.plugins.packagetypeCli.SERVER_SIDE_CLI_SCRIPT";
private static final Comparator<PackageVersion> VERSION_COMPARATOR = new Comparator<PackageVersion>() {
private final OSGiVersionComparator OSGI_COMPARATOR = new OSGiVersionComparator();
commit d6a305ee3d3e9e2ae9a1e5d018e5e8116b019695
Merge: f786a5d... 239280b...
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Wed Mar 2 11:40:31 2011 +0100
Merge remote branch 'origin/master' into cli-alert-notifs
diff --cc modules/core/dbutils/pom.xml
index 9e27c56,bf65ffb..e2b59a9
--- a/modules/core/dbutils/pom.xml
+++ b/modules/core/dbutils/pom.xml
@@@ -22,7 -22,7 +22,7 @@@
<properties>
<scm.module.path>modules/core/dbutils/</scm.module.path>
- <db.schema.version>2.104</db.schema.version>
- <db.schema.version>2.103</db.schema.version>
++ <db.schema.version>2.105</db.schema.version>
</properties>
<dependencies>
diff --cc modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml
index 88b53c2,e9b78a8..71ca67e
--- a/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml
+++ b/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml
@@@ -3297,32 -3297,49 +3297,76 @@@
</schemaSpec>
<schemaSpec version="2.103">
- <!-- package types no longer require to be coupled with a resource type. They can exist on their own. -->
- <schema-alterColumn table="RHQ_PACKAGE_TYPE" column="RESOURCE_TYPE_ID" nullable="true"/>
+ <!-- add FK for owning Subject -->
+ <schema-directSQL>
+ <statement desc="Creating RHQ_DASHBOARD foreign key relation to RHQ_SUBJECT for resource dashboards">
+ ALTER TABLE RHQ_DASHBOARD
+ ADD CONSTRAINT RHQ_DB_SUBJECT_ID_FK
+ FOREIGN KEY (SUBJECT_ID)
+ REFERENCES RHQ_SUBJECT (ID)
+ </statement>
+ </schema-directSQL>
+
+ <!-- Support resource specific dashboards -->
+ <schema-addColumn table="RHQ_DASHBOARD" column="RESOURCE_ID" columnType="INTEGER" />
+ <schema-directSQL>
+ <statement desc="Creating RHQ_DASHBOARD foreign key relation to RHQ_RESOURCE for resource dashboards">
+ ALTER TABLE RHQ_DASHBOARD
+ ADD CONSTRAINT RHQ_DB_RESOURCE_ID_FK
+ FOREIGN KEY (RESOURCE_ID)
+ REFERENCES RHQ_RESOURCE (ID)
+ </statement>
+ </schema-directSQL>
+
+ <!-- Support group specific dashboards -->
+ <schema-addColumn table="RHQ_DASHBOARD" column="GROUP_ID" columnType="INTEGER" />
+ <schema-directSQL>
+ <statement desc="Creating RHQ_DASHBOARD foreign key relation to RHQ_RESOURCE_GROUP for group dashboards">
+ ALTER TABLE RHQ_DASHBOARD
+ ADD CONSTRAINT RHQ_DB_RG_ID_FK
+ FOREIGN KEY (GROUP_ID)
+ REFERENCES RHQ_RESOURCE_GROUP (ID)
+ </statement>
+ </schema-directSQL>
+
+ <!-- Add category for distinguishing what kind of dashboard this is -->
+ <schema-addColumn table="RHQ_DASHBOARD" column="CATEGORY" columnType="VARCHAR2" precision="20"/>
+ <schema-directSQL>
+ <statement desc="Set dashboard category for existing dashboards to INVENTORY">
+ UPDATE RHQ_DASHBOARD
+ SET CATEGORY = 'INVENTORY'
+ </statement>
+ </schema-directSQL>
+ <schema-alterColumn table="RHQ_DASHBOARD" column="CATEGORY" nullable="FALSE" />
</schemaSpec>
+ <schemaSpec version="2.104">
++ <!-- package types no longer require to be coupled with a resource type. They can exist on their own. -->
++ <schema-alterColumn table="RHQ_PACKAGE_TYPE" column="RESOURCE_TYPE_ID" nullable="true"/>
++ </schemaSpec>
++
++ <schemaSpec version="2.105">
+ <schema-addColumn table="RHQ_REPO" column="OWNER_ID" columnType="INTEGER" />
+ <schema-addColumn table="RHQ_REPO" column="IS_PRIVATE" columnType="BOOLEAN" />
- <schema-alterColumn table="RHQ_REPO" column="IS_PRIVATE" nullable="FALSE" default="TRUE"/>
++ <schema-alterColumn table="RHQ_REPO" column="IS_PRIVATE" nullable="FALSE" default="TRUE"/>
+ <schema-directSQL>
+ <statement desc="Creating OWNER_ID foreign key relation on RHQ_REPO">
+ ALTER TABLE RHQ_REPO
+ ADD CONSTRAINT RHQ_REPO_OWNER_ID_FK
+ FOREIGN KEY (OWNER_ID)
+ REFERENCES RHQ_SUBJECT (ID)
+ </statement>
+ </schema-directSQL>
+
+ <!-- Now add modify the permissions to give all the roles with MANAGE_INVENTORY
+ the new MANAGE_REPOSITORIES privilege so that people's privs remain unchanged. -->
+ <schema-directSQL>
+ <statement>
+ INSERT INTO RHQ_PERMISSION (role_id, operation)
+ SELECT role_id, 15 FROM RHQ_PERMISSION WHERE operation = 1
+ </statement>
+ </schema-directSQL>
+ </schemaSpec>
</dbupgrade>
</target>
</project>
diff --cc modules/core/domain/src/main/java/org/rhq/core/domain/auth/Subject.java
index e9b9e58,dd66c1b..1ae43ca
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/auth/Subject.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/auth/Subject.java
@@@ -50,7 -50,7 +50,8 @@@ import org.jetbrains.annotations.NotNul
import org.rhq.core.domain.authz.Role;
import org.rhq.core.domain.configuration.Configuration;
+import org.rhq.core.domain.content.Repo;
+ import org.rhq.core.domain.dashboard.Dashboard;
import org.rhq.core.domain.resource.group.ResourceGroup;
/**
@@@ -310,9 -310,10 +311,13 @@@ public class Subject implements Seriali
@OneToMany(mappedBy = "subject", fetch = FetchType.LAZY)
private List<ResourceGroup> ownedGroups = null;
+ @OneToMany(mappedBy = "owner", fetch = FetchType.LAZY)
+ private Set<Repo> ownedRepos;
+
+ // When a subject is removed any owned dashboards are removed automatically
+ @OneToMany(mappedBy = "owner", fetch = FetchType.LAZY, cascade = CascadeType.REMOVE)
+ private List<Dashboard> ownedDashboards = null;
+
@Transient
private Integer sessionId = null;
@@@ -507,6 -508,14 +512,22 @@@
this.ownedGroups = ownedGroups;
}
++ protected Set<Repo> getOwnedrepos(){
++ return ownedRepos;
++ }
++
++ protected void setOwnedRepos(Set<Repo> repos) {
++ ownedRepos = repos;
++ }
++
+ protected List<Dashboard> getOwnedDashboards() {
+ return ownedDashboards;
+ }
+
+ protected void setOwnedDashboards(List<Dashboard> ownedDashboards) {
+ this.ownedDashboards = ownedDashboards;
+ }
+
@Override
public String toString() {
return "Subject[id=" + id + ",name=" + name + "]";
diff --cc modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/ContentGWTService.java
index e9428a4,080d749..d6322a6
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/ContentGWTService.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/ContentGWTService.java
@@@ -28,12 -28,9 +28,13 @@@ import com.google.gwt.user.client.rpc.R
import org.rhq.core.domain.content.Architecture;
import org.rhq.core.domain.content.InstalledPackageHistory;
+import org.rhq.core.domain.content.Package;
import org.rhq.core.domain.content.PackageType;
import org.rhq.core.domain.content.PackageVersion;
+import org.rhq.core.domain.content.composite.PackageAndLatestVersionComposite;
+import org.rhq.core.domain.content.composite.PackageTypeAndVersionFormatComposite;
+import org.rhq.core.domain.criteria.PackageCriteria;
+ import org.rhq.core.domain.criteria.InstalledPackageHistoryCriteria;
import org.rhq.core.domain.criteria.PackageVersionCriteria;
import org.rhq.core.domain.util.PageList;
@@@ -47,12 -43,10 +48,14 @@@ public interface ContentGWTService exte
PageList<PackageVersion> findPackageVersionsByCriteria(PackageVersionCriteria criteria) throws RuntimeException;
+ PageList<Package> findPackagesByCriteria(PackageCriteria criteria);
+
+ PageList<PackageAndLatestVersionComposite> findPackagesWithLatestVersion(PackageCriteria criteria);
+
PageList<InstalledPackageHistory> getInstalledPackageHistoryForResource(int resourceId, int count);
+ PageList<InstalledPackageHistory> findInstalledPackageHistoryByCriteria(InstalledPackageHistoryCriteria criteria);
+
List<Architecture> getArchitectures() throws RuntimeException;
PackageType getResourceCreationPackageType(int resourceTypeId) throws RuntimeException;
diff --cc modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/ContentGWTServiceImpl.java
index 7a66cff,603288e..69c5d20
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/ContentGWTServiceImpl.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/ContentGWTServiceImpl.java
@@@ -26,13 -26,9 +26,13 @@@ import java.util.List
import org.rhq.core.domain.content.Architecture;
import org.rhq.core.domain.content.InstalledPackageHistory;
+import org.rhq.core.domain.content.Package;
import org.rhq.core.domain.content.PackageType;
import org.rhq.core.domain.content.PackageVersion;
- import org.rhq.core.domain.content.PackageVersionFormatDescription;
+import org.rhq.core.domain.content.composite.PackageAndLatestVersionComposite;
+import org.rhq.core.domain.content.composite.PackageTypeAndVersionFormatComposite;
+ import org.rhq.core.domain.criteria.InstalledPackageHistoryCriteria;
+import org.rhq.core.domain.criteria.PackageCriteria;
import org.rhq.core.domain.criteria.PackageVersionCriteria;
import org.rhq.core.domain.util.PageControl;
import org.rhq.core.domain.util.PageList;
@@@ -73,24 -70,18 +74,35 @@@ public class ContentGWTServiceImpl exte
}
}
+ public PageList<Package> findPackagesByCriteria(PackageCriteria criteria) {
+ try {
+ return SerialUtility.prepare(contentManager.findPackagesByCriteria(getSessionSubject(), criteria),
+ "ContentService.findPackagesByCriteria");
+ } catch (Throwable t) {
+ throw new RuntimeException(ThrowableUtil.getAllMessages(t));
+ }
+ }
++
+ public PageList<InstalledPackageHistory> findInstalledPackageHistoryByCriteria(
+ InstalledPackageHistoryCriteria criteria) throws RuntimeException {
+ try {
+ PageList<InstalledPackageHistory> results = SerialUtility.prepare(contentUiManager
+ .findInstalledPackageHistoryByCriteria(getSessionSubject(), criteria),
+ "ContentService.findInstalledPackageHistoryByCriteria");
+ return results;
+ } catch (Throwable t) {
+ throw new RuntimeException(ThrowableUtil.getAllMessages(t));
+ }
+ }
-
+
+ public PageList<PackageAndLatestVersionComposite> findPackagesWithLatestVersion(PackageCriteria criteria) {
+ try {
+ return SerialUtility.prepare(contentManager.findPackagesWithLatestVersion(getSessionSubject(), criteria),
+ "ContentService.findPackagesByCriteria");
+ } catch (Throwable t) {
+ throw new RuntimeException(ThrowableUtil.getAllMessages(t));
+ }
+ }
-
public PageList<InstalledPackageHistory> getInstalledPackageHistoryForResource(int resourceId, int count)
throws RuntimeException {
try {
commit f786a5d381aa060eaa7b365f78b8571b259e1ca4
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Wed Mar 2 10:39:43 2011 +0100
Updating the CLI notification form to make use of the version formatting info provided by the package type behaviors.
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/util/OSGiVersion.java b/modules/core/domain/src/main/java/org/rhq/core/domain/util/OSGiVersion.java
index 0c9d664..eedadc2 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/util/OSGiVersion.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/util/OSGiVersion.java
@@ -36,6 +36,22 @@ public class OSGiVersion {
}
+ public static boolean isValid(String version) {
+ try {
+ new OSGiVersion(version);
+ return true;
+ } catch (IllegalArgumentException e) {
+ return false;
+ }
+ }
+
+ /**
+ * Creates new OSGiVersion instance from the version string.
+ *
+ * @param version
+ *
+ * @throws IllegalArgumentException if the version string isn't a well-formed OSGi version string.
+ */
public OSGiVersion(String version) {
String[] parts = version.split("\\.");
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/CliNotificationSenderForm.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/CliNotificationSenderForm.java
index e8d1c1c..dd18191 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/CliNotificationSenderForm.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/CliNotificationSenderForm.java
@@ -30,8 +30,6 @@ import com.smartgwt.client.widgets.form.events.FormSubmitFailedEvent;
import com.smartgwt.client.widgets.form.events.FormSubmitFailedHandler;
import com.smartgwt.client.widgets.form.events.ItemChangeEvent;
import com.smartgwt.client.widgets.form.events.ItemChangeHandler;
-import com.smartgwt.client.widgets.form.events.ItemChangedEvent;
-import com.smartgwt.client.widgets.form.events.ItemChangedHandler;
import com.smartgwt.client.widgets.form.fields.ButtonItem;
import com.smartgwt.client.widgets.form.fields.FormItem;
import com.smartgwt.client.widgets.form.fields.FormItemIcon;
@@ -48,9 +46,10 @@ import com.smartgwt.client.widgets.form.fields.events.ClickHandler;
import org.rhq.core.domain.alert.notification.AlertNotification;
import org.rhq.core.domain.auth.Subject;
import org.rhq.core.domain.configuration.PropertySimple;
-import org.rhq.core.domain.content.PackageType;
+import org.rhq.core.domain.content.PackageVersionFormatDescription;
import org.rhq.core.domain.content.Repo;
import org.rhq.core.domain.content.composite.PackageAndLatestVersionComposite;
+import org.rhq.core.domain.content.composite.PackageTypeAndVersionFormatComposite;
import org.rhq.core.domain.criteria.PackageCriteria;
import org.rhq.core.domain.criteria.RepoCriteria;
import org.rhq.core.domain.criteria.SubjectCriteria;
@@ -78,7 +77,7 @@ public class CliNotificationSenderForm extends AbstractNotificationSenderForm {
private static final String PROP_USER_ID = "userId";
private static final String PROP_USER_NAME = "userName";
private static final String PROP_USER_PASSWORD = "userPassword";
- private static final String PACKAGE_TYPE_NAME = "__SERVER_SIDE_CLI_SCRIPT";
+ private static final String PACKAGE_TYPE_NAME = "org.rhq.enterprise.server.plugins.packagetypeCli.SERVER_SIDE_CLI_SCRIPT";
private static class Config {
List<Repo> allRepos;
@@ -185,12 +184,12 @@ public class CliNotificationSenderForm extends AbstractNotificationSenderForm {
private SelectItem existingPackageSelector;
private RadioGroupWithComponentsItem userSelector;
private PackageVersionFileUploadFormWithVersion uploadForm;
- private PackageType cliScriptPackageType;
+ private PackageTypeAndVersionFormatComposite cliScriptPackageType;
private TextItem anotherUserName;
private TextItem anotherUserPassword;
private ButtonItem verifyUserButton;
- private FormItemIcon authSuccessIcon;
- private FormItemIcon authFailureIcon;
+ private FormItemIcon successIcon;
+ private FormItemIcon failureIcon;
private ForwardingSubmitFailedHandler uploadFailureHandler;
private ForwardingDynamicFormHandler uploadSuccessHandler;
@@ -205,13 +204,13 @@ public class CliNotificationSenderForm extends AbstractNotificationSenderForm {
super.onInit();
if (!formBuilt) {
- loadPackageType(new AsyncCallback<PackageType>() {
+ loadPackageType(new AsyncCallback<PackageTypeAndVersionFormatComposite>() {
public void onFailure(Throwable t) {
CoreGUI.getErrorHandler().handleError(MSG.view_alert_definition_notification_cliScript_editor_loadFailed(),
t);
}
- public void onSuccess(PackageType result) {
+ public void onSuccess(PackageTypeAndVersionFormatComposite result) {
cliScriptPackageType = result;
LocatableDynamicForm form = new LocatableDynamicForm(extendLocatorId("form"));
@@ -346,7 +345,7 @@ public class CliNotificationSenderForm extends AbstractNotificationSenderForm {
PackageCriteria pc = new PackageCriteria();
pc.addFilterRepoId(repoId);
- pc.addFilterPackageTypeId(cliScriptPackageType.getId());
+ pc.addFilterPackageTypeId(cliScriptPackageType.getPackageType().getId());
packageSelector.setDisabled(false);
existingPackageSelector.setDisabled(true);
@@ -404,6 +403,20 @@ public class CliNotificationSenderForm extends AbstractNotificationSenderForm {
getConfiguration().put(new PropertySimple(PROP_PACKAGE_ID, config.selectedPackage.getGeneralPackage().getId()));
callback.onSuccess(null);
} else {
+ if (cliScriptPackageType.getVersionFormat() != null) {
+ String versionRegex = cliScriptPackageType.getVersionFormat().getFullFormatRegex();
+ if (versionRegex != null) {
+ if (!matches(uploadForm.getField("version").getValue().toString(), versionRegex)) {
+ uploadForm.getItem("editableVersion").setIcons(failureIcon);
+ callback.onFailure(null);
+ return;
+ } else {
+ uploadForm.getItem("editableVersion").setIcons(successIcon);
+ }
+ } else {
+ uploadForm.getItem("editableVersion").setIcons();
+ }
+ }
uploadFailureHandler.setCallback(callback);
uploadSuccessHandler.setCallback(new AsyncCallback<Void>() {
public void onFailure(Throwable caught) {
@@ -449,7 +462,7 @@ public class CliNotificationSenderForm extends AbstractNotificationSenderForm {
if (repoId != null && repoId.trim().length() > 0) {
PackageCriteria pc = new PackageCriteria();
pc.addFilterRepoId(Integer.parseInt(repoId));
- pc.addFilterPackageTypeId(cliScriptPackageType.getId());
+ pc.addFilterPackageTypeId(cliScriptPackageType.getPackageType().getId());
GWTServiceLookup.getContentService().findPackagesWithLatestVersion(pc, new AsyncCallback<PageList<PackageAndLatestVersionComposite>>() {
public void onSuccess(PageList<PackageAndLatestVersionComposite> result) {
config.allPackages = result;
@@ -505,15 +518,15 @@ public class CliNotificationSenderForm extends AbstractNotificationSenderForm {
anotherUserPassword = new PasswordItem("password", MSG.dataSource_users_field_password());
verifyUserButton = new ButtonItem("verify", MSG.view_alert_definition_notification_cliScript_editor_verifyAuthentication());
- authSuccessIcon = new FormItemIcon();
- authSuccessIcon.setSrc(ImageManager.getAvailabilityIcon(Boolean.TRUE));
- authSuccessIcon.setWidth(16);
- authSuccessIcon.setHeight(16);
+ successIcon = new FormItemIcon();
+ successIcon.setSrc(ImageManager.getAvailabilityIcon(Boolean.TRUE));
+ successIcon.setWidth(16);
+ successIcon.setHeight(16);
- authFailureIcon = new FormItemIcon();
- authFailureIcon.setSrc(ImageManager.getAvailabilityIcon(Boolean.FALSE));
- authFailureIcon.setWidth(16);
- authFailureIcon.setHeight(16);
+ failureIcon = new FormItemIcon();
+ failureIcon.setSrc(ImageManager.getAvailabilityIcon(Boolean.FALSE));
+ failureIcon.setWidth(16);
+ failureIcon.setHeight(16);
form.setFields(anotherUserName, anotherUserPassword, verifyUserButton);
@@ -548,9 +561,9 @@ public class CliNotificationSenderForm extends AbstractNotificationSenderForm {
}
private DynamicForm createUploadNewScriptForm() {
- uploadForm = new PackageVersionFileUploadFormWithVersion(extendLocatorId("uploadForm"), cliScriptPackageType.getId());
+ uploadForm = new PackageVersionFileUploadFormWithVersion(extendLocatorId("uploadForm"), cliScriptPackageType.getPackageType().getId());
uploadForm.setTitleOrientation(TitleOrientation.TOP);
- uploadForm.setPackageTypeId(cliScriptPackageType.getId());
+ uploadForm.setPackageTypeId(cliScriptPackageType.getPackageType().getId());
uploadFailureHandler = (new ForwardingSubmitFailedHandler() {
public void onFormSubmitFailed(FormSubmitFailedEvent event) {
@@ -579,13 +592,34 @@ public class CliNotificationSenderForm extends AbstractNotificationSenderForm {
uploadForm.addItemChangeHandler(new ItemChangeHandler() {
public void onItemChange(ItemChangeEvent event) {
if (event.getItem() instanceof UploadItem) {
+ if (event.getNewValue() == null) {
+ uploadForm.getField("editableVersion").setValue("");
+ return;
+ }
+
String fileName = event.getNewValue().toString();
if (config.allPackages != null) {
for(PackageAndLatestVersionComposite plv : config.allPackages) {
if (plv.getGeneralPackage().getName().equals(fileName)) {
try {
- OSGiVersion v = new OSGiVersion(plv.getLatestPackageVersion().getVersion());
+ String version = plv.getLatestPackageVersion().getVersion();
+
+ PackageVersionFormatDescription format = cliScriptPackageType.getVersionFormat();
+ if (format == null) {
+ return;
+ }
+
+ if (format.getOsgiVersionExtractionRegex() == null) {
+ return;
+ }
+
+ String regex = format.getOsgiVersionExtractionRegex();
+ int group = format.getOsgiVersionGroupIndex();
+ String oldOsgiVersion = getOsgiVersion(version, regex, group);
+
+
+ OSGiVersion v = new OSGiVersion(oldOsgiVersion);
if (v.getMicroIfDefined() != null) {
v.setMicro(v.getMicro() + 1);
} else if (v.getMinorIfDefined() != null) {
@@ -593,10 +627,13 @@ public class CliNotificationSenderForm extends AbstractNotificationSenderForm {
} else {
v.setMajor(v.getMajor() + 1);
}
+
+ String newVersion = version.replace(oldOsgiVersion, v.toString());
- uploadForm.getField("editableVersion").setValue(v.toString());
+ uploadForm.getField("editableVersion").setValue(newVersion);
+ uploadForm.getField("version").setValue(newVersion);
return;
- } catch (IllegalArgumentException e) {
+ } catch (Exception e) {
//ok, can't suggest anything
return;
}
@@ -604,8 +641,17 @@ public class CliNotificationSenderForm extends AbstractNotificationSenderForm {
}
//no existing package exists with the same name as the file being uploaded
- uploadForm.getField("editableVersion").setValue("1.0");
- }
+
+ String defaultVersion = "";
+ if (cliScriptPackageType.getVersionFormat() != null && cliScriptPackageType.getVersionFormat().getOsgiVersionExtractionRegex() != null) {
+ //check if the package format understands plain OSGi versioning
+ if (matches("1.0", cliScriptPackageType.getVersionFormat().getFullFormatRegex())) {
+ defaultVersion = "1.0";
+ }
+ }
+ uploadForm.getField("editableVersion").setValue(defaultVersion);
+ uploadForm.getField("version").setValue(defaultVersion);
+ }
}
}
});
@@ -613,7 +659,7 @@ public class CliNotificationSenderForm extends AbstractNotificationSenderForm {
return uploadForm;
}
- private void loadPackageType(AsyncCallback<PackageType> handler) {
+ private void loadPackageType(AsyncCallback<PackageTypeAndVersionFormatComposite> handler) {
GWTServiceLookup.getContentService().findPackageType(null, PACKAGE_TYPE_NAME, handler);
}
@@ -624,14 +670,14 @@ public class CliNotificationSenderForm extends AbstractNotificationSenderForm {
GWTServiceLookup.getSubjectService().checkAuthentication(username, password, new AsyncCallback<Subject>() {
public void onFailure(Throwable caught) {
config.selectedSubject = null;
- verifyUserButton.setIcons(authFailureIcon);
+ verifyUserButton.setIcons(failureIcon);
markForRedraw();
action.onFailure(caught);
}
public void onSuccess(Subject result) {
config.selectedSubject = result;
- verifyUserButton.setIcons(result == null ? authFailureIcon : authSuccessIcon);
+ verifyUserButton.setIcons(result == null ? failureIcon : successIcon);
markForRedraw();
if (result == null) {
action.onFailure(null);
@@ -641,4 +687,17 @@ public class CliNotificationSenderForm extends AbstractNotificationSenderForm {
}
});
}
+
+ private static native String getOsgiVersion(String version, String osgiRegex, int groupIdx) /*-{
+ var re = new RegExp(osgiRegex);
+ var groupRef = '$' + groupIdx;
+ version = version.replace(re, groupRef);
+
+ return version;
+ }-*/;
+
+ private static native boolean matches(String string, String regex) /*-{
+ var re = new RegExp(regex);
+ return re.test(string);
+ }-*/;
}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/ContentGWTService.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/ContentGWTService.java
index 27f6bad..e9428a4 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/ContentGWTService.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/ContentGWTService.java
@@ -32,6 +32,7 @@ import org.rhq.core.domain.content.Package;
import org.rhq.core.domain.content.PackageType;
import org.rhq.core.domain.content.PackageVersion;
import org.rhq.core.domain.content.composite.PackageAndLatestVersionComposite;
+import org.rhq.core.domain.content.composite.PackageTypeAndVersionFormatComposite;
import org.rhq.core.domain.criteria.PackageCriteria;
import org.rhq.core.domain.criteria.PackageVersionCriteria;
import org.rhq.core.domain.util.PageList;
@@ -56,6 +57,6 @@ public interface ContentGWTService extends RemoteService {
PackageType getResourceCreationPackageType(int resourceTypeId) throws RuntimeException;
- PackageType findPackageType(Integer resourceTypeId, String packageTypeName) throws RuntimeException;
+ PackageTypeAndVersionFormatComposite findPackageType(Integer resourceTypeId, String packageTypeName) throws RuntimeException;
}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/ContentGWTServiceImpl.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/ContentGWTServiceImpl.java
index 6a0f3eb..7a66cff 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/ContentGWTServiceImpl.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/ContentGWTServiceImpl.java
@@ -29,7 +29,9 @@ import org.rhq.core.domain.content.InstalledPackageHistory;
import org.rhq.core.domain.content.Package;
import org.rhq.core.domain.content.PackageType;
import org.rhq.core.domain.content.PackageVersion;
+import org.rhq.core.domain.content.PackageVersionFormatDescription;
import org.rhq.core.domain.content.composite.PackageAndLatestVersionComposite;
+import org.rhq.core.domain.content.composite.PackageTypeAndVersionFormatComposite;
import org.rhq.core.domain.criteria.PackageCriteria;
import org.rhq.core.domain.criteria.PackageVersionCriteria;
import org.rhq.core.domain.util.PageControl;
@@ -119,9 +121,9 @@ public class ContentGWTServiceImpl extends AbstractGWTServiceImpl implements Con
}
@Override
- public PackageType findPackageType(Integer resourceTypeId, String packageTypeName) throws RuntimeException {
+ public PackageTypeAndVersionFormatComposite findPackageType(Integer resourceTypeId, String packageTypeName) throws RuntimeException {
try {
- return SerialUtility.prepare(contentManager.findPackageType(getSessionSubject(), resourceTypeId, packageTypeName),
+ return SerialUtility.prepare(contentManager.findPackageTypeWithVersionFormat(getSessionSubject(), resourceTypeId, packageTypeName),
"ContentService.findPackageType");
} catch (Throwable t) {
throw new RuntimeException(ThrowableUtil.getAllMessages(t));
commit 557da3b9e2b646883d7793b355a1c662d144b770
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Wed Mar 2 10:37:19 2011 +0100
This rather huge commit contains the following changes:
* a new server-side plugin type is defined - the packagetype plugin that can define new package types and their "behaviors"
* a concept of packagetype behavior is introduced - basically impls of this interface can enforce naming conventions, etc.
* content subsystem is modified to consult the packagetype behaviors when creating package versions in user initiated workflows
* a packagetype plugin for CLI scripts is defined
* changes made to PackageSource iface (and impls) to return package version comparators are reverted because this functionality is now the responsibility of the behaviors
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/content/PackageVersion.java b/modules/core/domain/src/main/java/org/rhq/core/domain/content/PackageVersion.java
index c42862e..76dbff4 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/content/PackageVersion.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/content/PackageVersion.java
@@ -335,8 +335,9 @@ public class PackageVersion implements Serializable {
}
//hmm... there's actually nothing we can sort these two by..
- //pronounce them equal
- return 0;
+ //let's compare them by id - the one inserted sooner will have a lower id
+
+ return Integer.valueOf(p1.getId()).compareTo(p2.getId());
}
};
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/content/PackageVersionFormatDescription.java b/modules/core/domain/src/main/java/org/rhq/core/domain/content/PackageVersionFormatDescription.java
new file mode 100644
index 0000000..3df2748
--- /dev/null
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/content/PackageVersionFormatDescription.java
@@ -0,0 +1,91 @@
+/*
+ * 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 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.core.domain.content;
+
+import java.io.Serializable;
+
+/**
+ * This class describes the qualities of a package version format
+ * and is used by the UI to provide "next version" hints to the user
+ * as well as for checking the version string format validity.
+ * <p>
+ * Note that this is going to be used in UI and therefore the regexes
+ * need to be written using the Javascript regex synax, *NOT* the Java one.
+ *
+ * @author Lukas Krejci
+ */
+public class PackageVersionFormatDescription implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ private String fullFormatRegex;
+ private String osgiVersionExtractionRegex;
+ private int osgiVersionGroupIndex;
+ private String textualDesctiption;
+
+ //GWT mandates a no-arg constructor, even if just private
+ protected PackageVersionFormatDescription() {
+
+ }
+
+ /**
+ *
+ * @param fullFormatRegex the regex the user supplied version must match
+ * @param osgiVersionExtractionRegex a regex to extract the osgi version string from the full version string.
+ * The regex must match the whole version string and have a group enclosing the osgi version string within it.
+ * @param osgiVersionGroupIndex the index of the group in the osgi version regex that contains the actual osgi version string
+ * @param textualDescription the textual description of format
+ */
+ public PackageVersionFormatDescription(String fullFormatRegex, String osgiVersionExtractionRegex, int osgiVersionGroupIndex, String textualDescription) {
+ super();
+ this.fullFormatRegex = fullFormatRegex;
+ this.osgiVersionExtractionRegex = osgiVersionExtractionRegex;
+ this.osgiVersionGroupIndex = osgiVersionGroupIndex;
+ this.textualDesctiption = textualDescription;
+ }
+
+ /**
+ * @return the fullFormatRegex
+ */
+ public String getFullFormatRegex() {
+ return fullFormatRegex;
+ }
+
+ /**
+ * @return the osgiVersionExtractionRegex
+ */
+ public String getOsgiVersionExtractionRegex() {
+ return osgiVersionExtractionRegex;
+ }
+
+ /**
+ * @return the osgiVersionGroupIndex
+ */
+ public int getOsgiVersionGroupIndex() {
+ return osgiVersionGroupIndex;
+ }
+
+ /**
+ * @return the textualDesctiption
+ */
+ public String getTextualDesctiption() {
+ return textualDesctiption;
+ }
+}
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/content/ValidatablePackageDetailsKey.java b/modules/core/domain/src/main/java/org/rhq/core/domain/content/ValidatablePackageDetailsKey.java
new file mode 100644
index 0000000..848df3d
--- /dev/null
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/content/ValidatablePackageDetailsKey.java
@@ -0,0 +1,107 @@
+/*
+ * 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 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.core.domain.content;
+
+/**
+ * This is a mutable version of the {@link PackageDetailsKey} used
+ * for validation purposes.
+ *
+ * @author Lukas Krejci
+ */
+public class ValidatablePackageDetailsKey {
+ private String name;
+ private String version;
+ private String packageTypeName;
+ private String architectureName;
+
+ public ValidatablePackageDetailsKey() {
+
+ }
+
+ public ValidatablePackageDetailsKey(String name, String version, String packageTypeName, String architectureName) {
+ this.name = name;
+ this.version = version;
+ this.packageTypeName = packageTypeName;
+ this.architectureName = architectureName;
+ }
+
+ public ValidatablePackageDetailsKey(PackageDetailsKey key) {
+ this.name = key.getName();
+ this.version = key.getVersion();
+ this.packageTypeName = key.getPackageTypeName();
+ this.architectureName = key.getArchitectureName();
+ }
+
+ /**
+ * @return the name
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * @param name the name to set
+ */
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ /**
+ * @return the version
+ */
+ public String getVersion() {
+ return version;
+ }
+
+ /**
+ * @param version the version to set
+ */
+ public void setVersion(String version) {
+ this.version = version;
+ }
+
+ /**
+ * @return the packageTypeName
+ */
+ public String getPackageTypeName() {
+ return packageTypeName;
+ }
+
+ /**
+ * @param packageTypeName the packageTypeName to set
+ */
+ public void setPackageTypeName(String packageTypeName) {
+ this.packageTypeName = packageTypeName;
+ }
+
+ /**
+ * @return the architectureName
+ */
+ public String getArchitectureName() {
+ return architectureName;
+ }
+
+ /**
+ * @param architectureName the architectureName to set
+ */
+ public void setArchitectureName(String architectureName) {
+ this.architectureName = architectureName;
+ }
+}
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/content/composite/PackageAndLatestVersionComposite.java b/modules/core/domain/src/main/java/org/rhq/core/domain/content/composite/PackageAndLatestVersionComposite.java
index 5c7c88f..62230e1 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/content/composite/PackageAndLatestVersionComposite.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/content/composite/PackageAndLatestVersionComposite.java
@@ -21,6 +21,9 @@ package org.rhq.core.domain.content.composite;
import java.io.Serializable;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+
import org.rhq.core.domain.content.Package;
import org.rhq.core.domain.content.PackageVersion;
@@ -30,6 +33,7 @@ import org.rhq.core.domain.content.PackageVersion;
*
* @author Lukas Krejci
*/
+(a)XmlAccessorType(XmlAccessType.FIELD)
public class PackageAndLatestVersionComposite implements Serializable {
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/content/composite/PackageTypeAndVersionFormatComposite.java b/modules/core/domain/src/main/java/org/rhq/core/domain/content/composite/PackageTypeAndVersionFormatComposite.java
new file mode 100644
index 0000000..e4c9332
--- /dev/null
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/content/composite/PackageTypeAndVersionFormatComposite.java
@@ -0,0 +1,68 @@
+/*
+ * 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 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.core.domain.content.composite;
+
+import java.io.Serializable;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+
+import org.rhq.core.domain.content.PackageType;
+import org.rhq.core.domain.content.PackageVersionFormatDescription;
+
+/**
+ * @author Lukas Krejci
+ */
+(a)XmlAccessorType(XmlAccessType.FIELD)
+public class PackageTypeAndVersionFormatComposite implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ private PackageType packageType;
+ private PackageVersionFormatDescription versionFormat;
+
+ protected PackageTypeAndVersionFormatComposite() {
+
+ }
+
+ /**
+ * @param packageType
+ * @param versionFormat
+ */
+ public PackageTypeAndVersionFormatComposite(PackageType packageType, PackageVersionFormatDescription versionFormat) {
+ super();
+ this.packageType = packageType;
+ this.versionFormat = versionFormat;
+ }
+
+ /**
+ * @return the packageType
+ */
+ public PackageType getPackageType() {
+ return packageType;
+ }
+
+ /**
+ * @return the versionFormat, can be null
+ */
+ public PackageVersionFormatDescription getVersionFormat() {
+ return versionFormat;
+ }
+}
diff --git a/modules/enterprise/server/ear/pom.xml b/modules/enterprise/server/ear/pom.xml
index 78c882d..220eee6 100644
--- a/modules/enterprise/server/ear/pom.xml
+++ b/modules/enterprise/server/ear/pom.xml
@@ -321,6 +321,18 @@
<artifactId>alert-subject</artifactId>
<version>${project.version}</version>
</artifactItem>
+
+ <artifactItem>
+ <groupId>org.rhq</groupId>
+ <artifactId>alert-cli</artifactId>
+ <version>${project.version}</version>
+ </artifactItem>
+
+ <artifactItem>
+ <groupId>org.rhq</groupId>
+ <artifactId>packagetype-cli</artifactId>
+ <version>${project.version}</version>
+ </artifactItem>
</artifactItems>
<outputDirectory>${earDirectory}/rhq-serverplugins</outputDirectory>
</configuration>
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerBean.java
index 157a55d..d0ddc8f 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerBean.java
@@ -704,8 +704,8 @@ public class BundleManagerBean implements BundleManagerLocal, BundleManagerRemot
q.setParameter("name", architecture.getName());
architecture = (Architecture) q.getSingleResult();
}
- PackageVersion packageVersion = contentManager.createPackageVersion(name, packageType.getId(), version,
- architecture.getId(), fileStream);
+ PackageVersion packageVersion = contentManager.createPackageVersion(subject, name, packageType.getId(),
+ version, architecture.getId(), fileStream);
// set the PackageVersion's filename to the bundleFile name, it's left null by default
packageVersion.setFileName(name);
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerBean.java
index 026ea38..2713ff4 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerBean.java
@@ -77,7 +77,10 @@ import org.rhq.core.domain.content.PackageDetailsKey;
import org.rhq.core.domain.content.PackageInstallationStep;
import org.rhq.core.domain.content.PackageType;
import org.rhq.core.domain.content.PackageVersion;
+import org.rhq.core.domain.content.PackageVersionFormatDescription;
+import org.rhq.core.domain.content.ValidatablePackageDetailsKey;
import org.rhq.core.domain.content.composite.PackageAndLatestVersionComposite;
+import org.rhq.core.domain.content.composite.PackageTypeAndVersionFormatComposite;
import org.rhq.core.domain.content.transfer.ContentResponseResult;
import org.rhq.core.domain.content.transfer.DeployIndividualPackageResponse;
import org.rhq.core.domain.content.transfer.DeployPackageStep;
@@ -102,6 +105,8 @@ import org.rhq.enterprise.server.authz.AuthorizationManagerLocal;
import org.rhq.enterprise.server.authz.PermissionException;
import org.rhq.enterprise.server.authz.RequiredPermission;
import org.rhq.enterprise.server.core.AgentManagerLocal;
+import org.rhq.enterprise.server.plugin.pc.content.PackageDetailsValidationException;
+import org.rhq.enterprise.server.plugin.pc.content.PackageTypeBehavior;
import org.rhq.enterprise.server.resource.ResourceTypeManagerLocal;
import org.rhq.enterprise.server.resource.ResourceTypeNotFoundException;
import org.rhq.enterprise.server.util.CriteriaQueryGenerator;
@@ -1142,6 +1147,26 @@ public class ContentManagerBean implements ContentManagerLocal, ContentManagerRe
}
}
+ public PackageTypeAndVersionFormatComposite findPackageTypeWithVersionFormat(Subject subject,
+ Integer resourceTypeId, String packageTypeName) {
+
+ PackageType type = findPackageType(subject, resourceTypeId, packageTypeName);
+
+ PackageVersionFormatDescription format = null;
+
+ try {
+ PackageTypeBehavior behavior = ContentManagerHelper.getPackageTypeBehavior(packageTypeName);
+ if (behavior != null) {
+ format = behavior.getPackageVersionFormat(packageTypeName);
+ }
+ } catch (Exception e) {
+ //well, this shouldn't happen but is not crucial in this case
+ log.info("Failed to obtain the behavior of package type '" + packageTypeName + "'.", e);
+ }
+
+ return new PackageTypeAndVersionFormatComposite(type, format);
+ }
+
@SuppressWarnings("unchecked")
public void checkForTimedOutRequests(Subject subject) {
if (!authorizationManager.isOverlord(subject)) {
@@ -1219,14 +1244,13 @@ public class ContentManagerBean implements ContentManagerLocal, ContentManagerRe
+ "] does not have permission to create package versions");
}
- return createPackageVersion(packageName, packageTypeId, version, (null == architectureId) ? getNoArchitecture()
- .getId() : architectureId, new ByteArrayInputStream(packageBytes));
+ return createPackageVersion(subject, packageName, packageTypeId, version, (null == architectureId) ? getNoArchitecture()
+ .getId() : architectureId, new ByteArrayInputStream(packageBytes));
}
- @SuppressWarnings("unchecked")
@TransactionAttribute(value = TransactionAttributeType.REQUIRES_NEW)
- public PackageVersion createPackageVersion(String packageName, int packageTypeId, String version,
- int architectureId, InputStream packageBitStream) {
+ public PackageVersion createPackageVersion(Subject subject, String packageName, int packageTypeId,
+ String version, int architectureId, InputStream packageBitStream) {
// See if the package version already exists and return that if it does
Query packageVersionQuery = entityManager.createNamedQuery(PackageVersion.QUERY_FIND_BY_PACKAGE_VER_ARCH);
packageVersionQuery.setParameter("name", packageName);
@@ -1240,6 +1264,29 @@ public class ContentManagerBean implements ContentManagerLocal, ContentManagerRe
return (PackageVersion) existingVersionList.get(0);
}
+ Architecture architecture = entityManager.find(Architecture.class, architectureId);
+ PackageType packageType = entityManager.find(PackageType.class, packageTypeId);
+
+ //check the validity of the provided data
+ try {
+ PackageTypeBehavior behavior = ContentManagerHelper.getPackageTypeBehavior(packageTypeId);
+ ValidatablePackageDetailsKey key = new ValidatablePackageDetailsKey(packageName, version, packageType.getName(), architecture.getName());
+ behavior.validateDetails(key, subject);
+
+ packageName = key.getName();
+ version = key.getVersion();
+ if (!architecture.getName().equals(key.getArchitectureName())) {
+ Query q = entityManager.createNamedQuery(Architecture.QUERY_FIND_BY_NAME);
+ q.setParameter("name", key.getArchitectureName());
+ architecture = (Architecture) q.getSingleResult();
+ }
+ } catch (PackageDetailsValidationException e) {
+ throw e;
+ } catch (Exception e) {
+ log.error("Failed to get the package type plugin container. This is a bug.", e);
+ throw new IllegalStateException("Failed to get the package type plugin container.", e);
+ }
+
// If the package doesn't exist, create that here
Query packageQuery = entityManager.createNamedQuery(Package.QUERY_FIND_BY_NAME_PKG_TYPE_ID);
packageQuery.setParameter("name", packageName);
@@ -1250,7 +1297,6 @@ public class ContentManagerBean implements ContentManagerLocal, ContentManagerRe
List existingPackageList = packageQuery.getResultList();
if (existingPackageList.size() == 0) {
- PackageType packageType = entityManager.find(PackageType.class, packageTypeId);
existingPackage = new Package(packageName, packageType);
existingPackage = persistOrMergePackageSafely(existingPackage);
} else {
@@ -1258,8 +1304,6 @@ public class ContentManagerBean implements ContentManagerLocal, ContentManagerRe
}
// Create a package version and add it to the package
- Architecture architecture = entityManager.find(Architecture.class, architectureId);
-
PackageVersion newPackageVersion = new PackageVersion(existingPackage, version, architecture);
newPackageVersion.setDisplayName(existingPackage.getName());
@@ -1611,6 +1655,33 @@ public class ContentManagerBean implements ContentManagerLocal, ContentManagerRe
packageType = entityManager.find(PackageType.class, packageTypeId);
}
+ try {
+ PackageTypeBehavior behavior = ContentManagerHelper.getPackageTypeBehavior(packageTypeId);
+
+ if (behavior != null) {
+ String packageTypeName = packageType.getName();
+ String archName = architecture.getName();
+ ValidatablePackageDetailsKey key = new ValidatablePackageDetailsKey(packageName, version, packageTypeName, archName);
+ behavior.validateDetails(key, subject);
+
+ //update the details from the validation results
+ packageName = key.getName();
+ version = key.getVersion();
+
+ if (!architecture.getName().equals(key.getArchitectureName())) {
+ Query q = entityManager.createNamedQuery(Architecture.QUERY_FIND_BY_NAME);
+ q.setParameter("name", key.getArchitectureName());
+ architecture = (Architecture) q.getSingleResult();
+ }
+ }
+ } catch (PackageDetailsValidationException e) {
+ throw e;
+ } catch (Exception e) {
+ log.error("Failed to get the package type plugin container. This is a bug.", e);
+ throw new IllegalStateException("Failed to get the package type plugin container.", e);
+ }
+
+
Package existingPackage = null;
Query packageQuery = entityManager.createNamedQuery(Package.QUERY_FIND_BY_NAME_PKG_TYPE_ID);
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerHelper.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerHelper.java
index a00a40c..d47dc84 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerHelper.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerHelper.java
@@ -18,21 +18,28 @@
*/
package org.rhq.enterprise.server.content;
+import java.util.Comparator;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.Query;
+import org.rhq.core.domain.auth.Subject;
import org.rhq.core.domain.content.ContentSyncResults;
import org.rhq.core.domain.content.ContentSyncStatus;
import org.rhq.core.domain.content.InstalledPackage;
import org.rhq.core.domain.content.Package;
import org.rhq.core.domain.content.PackageDetailsKey;
import org.rhq.core.domain.content.PackageVersion;
+import org.rhq.core.domain.content.PackageVersionFormatDescription;
+import org.rhq.core.domain.content.ValidatablePackageDetailsKey;
import org.rhq.core.domain.content.transfer.ResourcePackageDetails;
import org.rhq.enterprise.server.plugin.pc.MasterServerPluginContainer;
import org.rhq.enterprise.server.plugin.pc.ServerPluginServiceManagement;
import org.rhq.enterprise.server.plugin.pc.content.ContentServerPluginContainer;
+import org.rhq.enterprise.server.plugin.pc.content.PackageDetailsValidationException;
+import org.rhq.enterprise.server.plugin.pc.content.PackageTypeBehavior;
+import org.rhq.enterprise.server.plugin.pc.content.PackageTypeServerPluginContainer;
import org.rhq.enterprise.server.util.LookupUtil;
/**
@@ -41,6 +48,21 @@ import org.rhq.enterprise.server.util.LookupUtil;
public class ContentManagerHelper {
private EntityManager entityManager;
+ private static class DefaultPackageTypeBehavior implements PackageTypeBehavior {
+ public Comparator<PackageVersion> getPackageVersionComparator(String packageTypeName) {
+ return PackageVersion.DEFAULT_COMPARATOR;
+ }
+
+ public void validateDetails(ValidatablePackageDetailsKey key, Subject origin)
+ throws PackageDetailsValidationException {
+ }
+
+ public PackageVersionFormatDescription getPackageVersionFormat(String packageTypeName) {
+ return null;
+ }
+ }
+ private static final PackageTypeBehavior DEFAULT_PACKAGE_TYPE_BEHAVIOR = new DefaultPackageTypeBehavior();
+
public ContentManagerHelper(EntityManager managerIn) {
this.entityManager = managerIn;
}
@@ -69,6 +91,30 @@ public class ContentManagerHelper {
return pc;
}
+ public static PackageTypeServerPluginContainer getPackageTypePluginContainer() throws Exception {
+ PackageTypeServerPluginContainer pc = null;
+
+ try {
+ ServerPluginServiceManagement mbean = LookupUtil.getServerPluginService();
+ if (!mbean.isMasterPluginContainerStarted()) {
+ throw new IllegalStateException("The master plugin container is not started!");
+ }
+
+ MasterServerPluginContainer master = mbean.getMasterPluginContainer();
+ pc = master.getPluginContainerByClass(PackageTypeServerPluginContainer.class);
+ } catch (IllegalStateException ise) {
+ throw ise;
+ } catch (Exception e) {
+ throw new Exception("Cannot obtain the package type plugin container", e);
+ }
+
+ if (pc == null) {
+ throw new Exception("Package type plugin container is null!");
+ }
+
+ return pc;
+ }
+
public static ResourcePackageDetails installedPackageToDetails(InstalledPackage installedPackage) {
PackageVersion packageVersion = installedPackage.getPackageVersion();
ResourcePackageDetails details = packageVersionToDetails(packageVersion);
@@ -147,4 +193,15 @@ public class ContentManagerHelper {
return persistedResults;
}
+
+ public static PackageTypeBehavior getPackageTypeBehavior(int packageTypeId) throws Exception {
+ PackageTypeBehavior ret = getPackageTypePluginContainer().getPluginManager().getBehavior(packageTypeId);
+ return ret == null ? DEFAULT_PACKAGE_TYPE_BEHAVIOR : ret;
+ }
+
+ public static PackageTypeBehavior getPackageTypeBehavior(String packageTypeName) throws Exception {
+ PackageTypeBehavior ret = getPackageTypePluginContainer().getPluginManager().getBehavior(packageTypeName);
+ return ret == null ? DEFAULT_PACKAGE_TYPE_BEHAVIOR : ret;
+ }
+
}
\ No newline at end of file
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerLocal.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerLocal.java
index 6ae321a..b4644d0 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerLocal.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerLocal.java
@@ -38,6 +38,7 @@ import org.rhq.core.domain.content.PackageDetailsKey;
import org.rhq.core.domain.content.PackageType;
import org.rhq.core.domain.content.PackageVersion;
import org.rhq.core.domain.content.composite.PackageAndLatestVersionComposite;
+import org.rhq.core.domain.content.composite.PackageTypeAndVersionFormatComposite;
import org.rhq.core.domain.content.transfer.DeployPackageStep;
import org.rhq.core.domain.content.transfer.DeployPackagesResponse;
import org.rhq.core.domain.content.transfer.RemovePackagesResponse;
@@ -226,7 +227,8 @@ public interface ContentManagerLocal {
* Creates a new package version in the system. If the parent package (identified by the packageName parameter) does
* not exist, it will be created. If a package version exists with the specified version ID, a new one will not be
* created and the existing package version instance will be returned.
- *
+ *
+ * @param subject the user requesting the package creation
* @param packageName parent package name; uniquely identifies the package under which this version goes
* @param packageTypeId identifies the type of package in case the general package needs to be created
* @param version identifies the version to be create
@@ -235,11 +237,11 @@ public interface ContentManagerLocal {
* @return newly created package version if one did not exist; existing package version that matches these data if
* one was found
*/
- PackageVersion createPackageVersion(String packageName, int packageTypeId, String version, int architectureId,
- InputStream packageBitStream);
+ PackageVersion createPackageVersion(Subject subject, String packageName, int packageTypeId, String version,
+ int architectureId, InputStream packageBitStream);
/**
- * This method is similar to the {@link #createPackageVersion(String, int, String, int, InputStream)} but fails if
+ * This method is similar to the {@link #createPackageVersion(Subject, String, int, String, int, InputStream)} but fails if
* the package version with the provided details already exists which is a desired behaviour for the GUI originating
* requests.
* @param subject the current user
@@ -384,6 +386,11 @@ public interface ContentManagerLocal {
PackageType findPackageType(Subject subject, Integer resourceTypeId, String packageTypeName);
/**
+ * @see {@link ContentManagerRemote#findPackageTypeWithVersionFormat(Subject, Integer, String)}
+ */
+ PackageTypeAndVersionFormatComposite findPackageTypeWithVersionFormat(Subject subject, Integer resourceTypeId, String packageTypeName);
+
+ /**
* @see {@link ContentManagerRemote#findInstalledPackagesByCriteria(Subject, InstalledPackageCriteria)}
*/
PageList<InstalledPackage> findInstalledPackagesByCriteria(Subject subject, InstalledPackageCriteria criteria);
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerRemote.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerRemote.java
index 261accf..edeb2b2 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerRemote.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerRemote.java
@@ -33,6 +33,7 @@ import org.rhq.core.domain.content.Package;
import org.rhq.core.domain.content.PackageType;
import org.rhq.core.domain.content.PackageVersion;
import org.rhq.core.domain.content.composite.PackageAndLatestVersionComposite;
+import org.rhq.core.domain.content.composite.PackageTypeAndVersionFormatComposite;
import org.rhq.core.domain.criteria.InstalledPackageCriteria;
import org.rhq.core.domain.criteria.PackageCriteria;
import org.rhq.core.domain.criteria.PackageVersionCriteria;
@@ -158,6 +159,20 @@ public interface ContentManagerRemote {
);
/**
+ * Similar to {@link #findPackageType(Subject, Integer, String)} but
+ * returns the package type along with the version format specification.
+ *
+ * @param subject
+ * @param resourceTypeId
+ * @param packageTypeName
+ * @return
+ */
+ @WebMethod
+ PackageTypeAndVersionFormatComposite findPackageTypeWithVersionFormat(
+ @WebParam(name = "subject") Subject subject,
+ @WebParam(name ="resourceTypeId") Integer resourceTypeId,
+ @WebParam(name = "packageTypeName") String packageTypeName);
+ /**
* @param subject
* @param criteria {@link InstalledPackageCriteria}
* @return InstalledPackages for the criteria
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/RepoManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/RepoManagerBean.java
index 6eadde8..959b321 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/RepoManagerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/RepoManagerBean.java
@@ -82,6 +82,7 @@ import org.rhq.enterprise.server.plugin.pc.content.ContentProvider;
import org.rhq.enterprise.server.plugin.pc.content.ContentProviderManager;
import org.rhq.enterprise.server.plugin.pc.content.ContentServerPluginContainer;
import org.rhq.enterprise.server.plugin.pc.content.PackageSource;
+import org.rhq.enterprise.server.plugin.pc.content.PackageTypeBehavior;
import org.rhq.enterprise.server.plugin.pc.content.RepoDetails;
import org.rhq.enterprise.server.plugin.pc.content.RepoGroupDetails;
import org.rhq.enterprise.server.plugin.pc.content.RepoImportReport;
@@ -412,51 +413,10 @@ public class RepoManagerBean implements RepoManagerLocal, RepoManagerRemote {
}
public PackageVersion getLatestPackageVersion(Subject subject, int packageId, int repoId) {
- return getLatestPackageVersion(subject, packageId, repoId, null);
- }
-
- public PackageVersion getLatestPackageVersion(Subject subject, int packageId, int repoId, Comparator<PackageVersion> versionComparator) {
if (!authzManager.canViewRepo(subject, repoId)) {
throw new PermissionException("User [" + subject + "] cannot access the repo with id " + repoId);
}
- if (versionComparator == null) {
- Query pvcsQ = entityManager.createNamedQuery(PackageVersionContentSource.QUERY_FIND_BY_PACKAGE_AND_REPO_ID_NO_FETCH);
- pvcsQ.setParameter("package_id", packageId);
- pvcsQ.setParameter("repo_id", repoId);
-
- @SuppressWarnings("unchecked")
- List<PackageVersionContentSource> pvcss = (List<PackageVersionContentSource>) pvcsQ.getResultList();
-
- try {
- ContentProviderManager manager = ContentManagerHelper.getPluginContainer().getAdapterManager();
- for(PackageVersionContentSource pvcs : pvcss) {
- ContentProvider provider = manager.getIsolatedContentProvider(pvcs.getPackageVersionContentSourcePK().getContentSource().getId());
-
- if (provider instanceof PackageSource) {
- versionComparator = ((PackageSource)provider).getPackageVersionComparator();
-
- if (versionComparator != null) {
- //ok, we found one non-default, let's go with that.
- break;
- }
- }
- }
- } catch (Exception e) {
- log.warn("Searching package sources for a version comparator failed. Will use the default comparator.", e);
- }
-
- if (versionComparator == null) {
- versionComparator = PackageVersion.DEFAULT_COMPARATOR;
- }
-
- //even though we can obtain the package versions from the pvcss elements, we can't
- //use just these, because these are not all the package versions there might be present
- //in the repo for this package. Some package versions can have no content source.
- //therefore we need to query the database again in the code below to obtain the full
- //list of package versions.
- }
-
Query q = entityManager.createNamedQuery(PackageVersion.QUERY_FIND_BY_PACKAGE_AND_REPO_ID);
q.setParameter("packageId", packageId);
q.setParameter("repoId", repoId);
@@ -471,6 +431,20 @@ public class RepoManagerBean implements RepoManagerLocal, RepoManagerRemote {
}
PackageVersion latest = results.get(0);
+ String packageTypeName = latest.getGeneralPackage().getPackageType().getName();
+
+ Comparator<PackageVersion> versionComparator = null;
+ try {
+ PackageTypeBehavior behavior = ContentManagerHelper.getPackageTypeBehavior(packageTypeName);
+ versionComparator = behavior.getPackageVersionComparator(packageTypeName);
+ } catch (Exception e) {
+ log.error("Could not get the package type behavior for package type '" + packageTypeName + "'. This should not happen.", e);
+ }
+
+ if (versionComparator == null) {
+ versionComparator = PackageVersion.DEFAULT_COMPARATOR;
+ }
+
Iterator<PackageVersion> it = results.iterator();
it.next(); //skip the first element, we don't have to compare it with itself
while(it.hasNext()) {
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/RepoManagerLocal.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/RepoManagerLocal.java
index bc22d81..51957bd 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/RepoManagerLocal.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/RepoManagerLocal.java
@@ -120,14 +120,6 @@ public interface RepoManagerLocal {
PackageVersion getLatestPackageVersion(Subject subject, int packageId, int repoId);
/**
- * This is an enhanced version of the remoted method that is able to override the default
- * package version comparator.
- *
- * @see RepoManagerRemote#getLatestPackageVersion(Subject, int, int)
- */
- PackageVersion getLatestPackageVersion(Subject subject, int packageId, int repoId, Comparator<PackageVersion> versionComparator);
-
- /**
* Get the overall sync status of this Repository. This is a summation of all the syncs.
*
* There is a weight to the status since this returns the most 'relevant' status:
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/RepoManagerRemote.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/RepoManagerRemote.java
index 54d2732..d144443 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/RepoManagerRemote.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/RepoManagerRemote.java
@@ -135,9 +135,8 @@ public interface RepoManagerRemote {
* Returns the latest package version of the supplied package.
* The latest version is determined using a comparator which is found using the following rules:
* <ol>
- * <li>Find the first content provider defining the package connected to given repo
- * that defines a non-null version comparator
- * <li>If no content provider provides explicit comparator, use {@link PackageVersion#DEFAULT_COMPARATOR}
+ * <li>determine the comparator using the package type behavior if one is setup for the package type
+ * <li>If no package behavior exists, use {@link PackageVersion#DEFAULT_COMPARATOR}
* </ol>
*
* @param subject the authenticated user
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/MasterServerPluginContainer.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/MasterServerPluginContainer.java
index bd4feac..87e659d 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/MasterServerPluginContainer.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/MasterServerPluginContainer.java
@@ -39,6 +39,7 @@ import org.rhq.core.domain.plugin.PluginKey;
import org.rhq.enterprise.server.plugin.pc.alert.AlertServerPluginContainer;
import org.rhq.enterprise.server.plugin.pc.bundle.BundleServerPluginContainer;
import org.rhq.enterprise.server.plugin.pc.content.ContentServerPluginContainer;
+import org.rhq.enterprise.server.plugin.pc.content.PackageTypeServerPluginContainer;
import org.rhq.enterprise.server.plugin.pc.entitlement.EntitlementServerPluginContainer;
import org.rhq.enterprise.server.plugin.pc.generic.GenericServerPluginContainer;
import org.rhq.enterprise.server.plugin.pc.perspective.PerspectiveServerPluginContainer;
@@ -463,6 +464,7 @@ public class MasterServerPluginContainer {
pcs.add(new AlertServerPluginContainer(this));
pcs.add(new EntitlementServerPluginContainer(this));
pcs.add(new BundleServerPluginContainer(this));
+ pcs.add(new PackageTypeServerPluginContainer(this));
return pcs;
}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/content/AbstractPackageTypeBehavior.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/content/AbstractPackageTypeBehavior.java
new file mode 100644
index 0000000..dfd0750
--- /dev/null
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/content/AbstractPackageTypeBehavior.java
@@ -0,0 +1,33 @@
+/*
+ * 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 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.server.plugin.pc.content;
+
+import org.rhq.enterprise.server.plugin.pc.ServerPluginComponent;
+
+/**
+ *
+ *
+ * @author Lukas Krejci
+ */
+public abstract class AbstractPackageTypeBehavior<T extends ServerPluginComponent> implements PackageTypeBehavior {
+
+ protected T pluginComponent;
+
+}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/content/PackageDetailsValidationException.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/content/PackageDetailsValidationException.java
new file mode 100644
index 0000000..026b343
--- /dev/null
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/content/PackageDetailsValidationException.java
@@ -0,0 +1,47 @@
+/*
+ * 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 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.server.plugin.pc.content;
+
+/**
+ * Thrown from {@link PackageTypeBehavior} when package details validation fails.
+ *
+ * @author Lukas Krejci
+ */
+public class PackageDetailsValidationException extends RuntimeException {
+
+ private static final long serialVersionUID = 1L;
+
+ public PackageDetailsValidationException() {
+ super();
+ }
+
+ public PackageDetailsValidationException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public PackageDetailsValidationException(String message) {
+ super(message);
+ }
+
+ public PackageDetailsValidationException(Throwable cause) {
+ super(cause);
+ }
+
+}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/content/PackageSource.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/content/PackageSource.java
index a5c7bae..dc51451 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/content/PackageSource.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/content/PackageSource.java
@@ -24,9 +24,6 @@ package org.rhq.enterprise.server.plugin.pc.content;
import java.io.InputStream;
import java.util.Collection;
-import java.util.Comparator;
-
-import org.rhq.core.domain.content.PackageVersion;
/**
* Indicates a content source has the capability to provide packages into the server. Package synchronization will
@@ -34,7 +31,6 @@ import org.rhq.core.domain.content.PackageVersion;
* passed into the plugin through {@link ContentProvider#initialize(org.rhq.core.domain.configuration.Configuration)}
*
* @author Jason Dobies
- * @author Lukas Krejci
*/
public interface PackageSource {
@@ -63,16 +59,4 @@ public interface PackageSource {
* @throws Exception if failed to obtain the stream to the remote package data
*/
InputStream getInputStream(String location) throws Exception;
-
- /**
- * This comparator will be used to determine the latest version of a package.
- * It should sort the package versions from the "oldest" to the "youngest", i.e. when comparing
- * <br/>
- * <code>comparator.compare(older, younger)</code>
- * <br/>
- * the comparator should return a value < 0.
- *
- * @return a comparator to use when sorting the package versions or null if {@link PackageVersion#DEFAULT_COMPARATOR} should be used.
- */
- Comparator<PackageVersion> getPackageVersionComparator();
}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/content/PackageTypeBehavior.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/content/PackageTypeBehavior.java
new file mode 100644
index 0000000..b11818f
--- /dev/null
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/content/PackageTypeBehavior.java
@@ -0,0 +1,67 @@
+/*
+ * 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 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.server.plugin.pc.content;
+
+import java.util.Comparator;
+
+import org.rhq.core.domain.auth.Subject;
+import org.rhq.core.domain.content.PackageVersion;
+import org.rhq.core.domain.content.PackageVersionFormatDescription;
+import org.rhq.core.domain.content.ValidatablePackageDetailsKey;
+
+/**
+ * The package types are either defined in the agent plugin descriptors or by the server-side
+ * package type plugins. The server-side plugins define a "behaviorClass" that implements
+ * this interface to provide additional runtime "hooks" controlling the package type
+ * behavior.
+ *
+ * @author Lukas Krejci
+ */
+public interface PackageTypeBehavior {
+
+ /**
+ * Validate the package before it gets stored.
+ *
+ * @param key the package details key
+ * @param origin who is uploading the package
+ * @throws PackageDetailsValidationException
+ */
+ void validateDetails(ValidatablePackageDetailsKey key, Subject origin) throws PackageDetailsValidationException;
+
+ /**
+ * This comparator will be used to determine the latest version of a package.
+ * It should sort the package versions from the "oldest" to the "youngest", i.e. when comparing
+ * <br/>
+ * <code>comparator.compare(older, younger)</code>
+ * <br/>
+ * the comparator should return a value < 0.
+ *
+ * @param packageTypeName the name of the package type
+ * @return a comparator to use when sorting the package versions or null if {@link PackageVersion#DEFAULT_COMPARATOR} should be used.
+ */
+ Comparator<PackageVersion> getPackageVersionComparator(String packageTypeName);
+
+ /**
+ * Description of the package version format mandated by the package type.
+ *
+ * @return the package version format description
+ */
+ PackageVersionFormatDescription getPackageVersionFormat(String packageTypeName);
+}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/content/PackageTypePluginManager.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/content/PackageTypePluginManager.java
new file mode 100644
index 0000000..f62b8e5
--- /dev/null
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/content/PackageTypePluginManager.java
@@ -0,0 +1,155 @@
+/*
+ * 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 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.server.plugin.pc.content;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.rhq.core.clientapi.agent.metadata.ConfigurationMetadataParser;
+import org.rhq.core.clientapi.agent.metadata.InvalidPluginDescriptorException;
+import org.rhq.core.domain.content.PackageType;
+import org.rhq.enterprise.server.auth.SubjectManagerLocal;
+import org.rhq.enterprise.server.content.ContentManagerLocal;
+import org.rhq.enterprise.server.plugin.pc.AbstractTypeServerPluginContainer;
+import org.rhq.enterprise.server.plugin.pc.ServerPluginComponent;
+import org.rhq.enterprise.server.plugin.pc.ServerPluginEnvironment;
+import org.rhq.enterprise.server.plugin.pc.ServerPluginManager;
+import org.rhq.enterprise.server.util.LookupUtil;
+import org.rhq.enterprise.server.xmlschema.generated.serverplugin.packagetype.PackageTypeDefinitionType;
+import org.rhq.enterprise.server.xmlschema.generated.serverplugin.packagetype.PackageTypePluginDescriptorType;
+
+/**
+ *
+ *
+ * @author Lukas Krejci
+ */
+public class PackageTypePluginManager extends ServerPluginManager {
+
+ private Map<PackageType, ServerPluginEnvironment> pluginsByPackageTypeId;
+
+ public PackageTypePluginManager(AbstractTypeServerPluginContainer pc) {
+ super(pc);
+ pluginsByPackageTypeId = new HashMap<PackageType, ServerPluginEnvironment>();
+ }
+
+ @Override
+ protected void loadPlugin(ServerPluginEnvironment env, boolean enabled) throws Exception {
+ super.loadPlugin(env, enabled);
+
+ PackageTypePluginDescriptorType descriptor = (PackageTypePluginDescriptorType) env.getPluginDescriptor();
+
+ try {
+ //check the behavior class exists
+ String behaviorClassName = descriptor.getBehaviorClass();
+
+ Class<?> behaviorClass = loadPluginClass(env, behaviorClassName, false);
+
+ if (!AbstractPackageTypeBehavior.class.isAssignableFrom(behaviorClass)) {
+ throw new Exception("The behavior class '" + behaviorClassName + "' of the plugin '"
+ + env.getPluginKey().getPluginName() + "' does not inherit from AbstractPackageTypeBehavior class.");
+ }
+
+ //check that all the package types defined by this plugin exist
+ for (PackageTypeDefinitionType def : descriptor.getPackageType()) {
+ PackageType pt = ensurePackageTypeExists(def);
+ pluginsByPackageTypeId.put(pt, env);
+ }
+ } catch (Exception e) {
+ // do not deploy this plugin - its stinky
+ try {
+ unloadPlugin(env.getPluginKey().getPluginName());
+ } catch (Exception ignore) {
+ }
+ throw e;
+ }
+ }
+
+ private PackageType ensurePackageTypeExists(PackageTypeDefinitionType def) throws InvalidPluginDescriptorException {
+ SubjectManagerLocal subjectManager = LookupUtil.getSubjectManager();
+ ContentManagerLocal cm = LookupUtil.getContentManager();
+
+ PackageType packageType = cm.findPackageType(subjectManager.getOverlord(), null, def.getName());
+
+ if (packageType == null) {
+ //TODO support tying the package type to the resource types?
+ packageType = new PackageType(def.getName(), null);
+ packageType.setDescription(def.getDescription());
+ packageType.setDisplayName(def.getDisplayName());
+ packageType.setSupportsArchitecture(def.isSupportsArchitecture());
+ packageType.setCreationData(false);
+ packageType.setDeploymentConfigurationDefinition(ConfigurationMetadataParser.parse(def.getName(),
+ def.getConfiguration()));
+ packageType.setDiscoveryInterval(-1);
+ packageType.setPackageExtraPropertiesDefinition(null);
+
+ packageType = cm.persistServersidePackageType(packageType);
+ }
+
+ return packageType;
+ }
+
+ public AbstractPackageTypeBehavior<? extends ServerPluginComponent> getBehavior(int packageTypeId) throws Exception {
+ return getBehavior(findByPackageTypeId(packageTypeId));
+ }
+
+ public AbstractPackageTypeBehavior<? extends ServerPluginComponent> getBehavior(String packageTypeName)
+ throws Exception {
+ return getBehavior(findByPackageTypeName(packageTypeName));
+ }
+
+ private AbstractPackageTypeBehavior<? extends ServerPluginComponent> getBehavior(ServerPluginEnvironment env)
+ throws Exception {
+ if (env == null) {
+ return null;
+ }
+
+ PackageTypePluginDescriptorType descriptor = (PackageTypePluginDescriptorType) env.getPluginDescriptor();
+
+ String behaviorClassName = descriptor.getBehaviorClass();
+
+ @SuppressWarnings("unchecked")
+ AbstractPackageTypeBehavior<ServerPluginComponent> ret = (AbstractPackageTypeBehavior<ServerPluginComponent>) instantiatePluginClass(
+ env, behaviorClassName);
+
+ ret.pluginComponent = getServerPluginComponent(env.getPluginKey().getPluginName());
+
+ return ret;
+ }
+
+ private ServerPluginEnvironment findByPackageTypeId(int id) {
+ for (Map.Entry<PackageType, ServerPluginEnvironment> entry : pluginsByPackageTypeId.entrySet()) {
+ if (entry.getKey().getId() == id) {
+ return entry.getValue();
+ }
+ }
+
+ return null;
+ }
+
+ private ServerPluginEnvironment findByPackageTypeName(String name) {
+ for (Map.Entry<PackageType, ServerPluginEnvironment> entry : pluginsByPackageTypeId.entrySet()) {
+ if (entry.getKey().getName().equals(name)) {
+ return entry.getValue();
+ }
+ }
+
+ return null;
+ }
+}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/content/PackageTypeServerPluginContainer.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/content/PackageTypeServerPluginContainer.java
new file mode 100644
index 0000000..df07119
--- /dev/null
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/content/PackageTypeServerPluginContainer.java
@@ -0,0 +1,56 @@
+/*
+ * 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 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.server.plugin.pc.content;
+
+import org.rhq.enterprise.server.plugin.pc.AbstractTypeServerPluginContainer;
+import org.rhq.enterprise.server.plugin.pc.MasterServerPluginContainer;
+import org.rhq.enterprise.server.plugin.pc.ServerPluginEnvironment;
+import org.rhq.enterprise.server.plugin.pc.ServerPluginManager;
+import org.rhq.enterprise.server.plugin.pc.ServerPluginType;
+import org.rhq.enterprise.server.xmlschema.generated.serverplugin.packagetype.PackageTypePluginDescriptorType;
+
+/**
+ *
+ *
+ * @author Lukas Krejci
+ */
+public class PackageTypeServerPluginContainer extends AbstractTypeServerPluginContainer {
+
+ /**
+ * @param master
+ */
+ public PackageTypeServerPluginContainer(MasterServerPluginContainer master) {
+ super(master);
+ }
+
+ public ServerPluginType getSupportedServerPluginType() {
+ return new ServerPluginType(PackageTypePluginDescriptorType.class);
+ }
+
+ @Override
+ public PackageTypePluginManager getPluginManager() {
+ return (PackageTypePluginManager) super.getPluginManager();
+ }
+
+ @Override
+ protected ServerPluginManager createPluginManager() {
+ return new PackageTypePluginManager(this);
+ }
+}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceFactoryManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceFactoryManagerBean.java
index 5a08508..8d5fad4 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceFactoryManagerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceFactoryManagerBean.java
@@ -463,8 +463,8 @@ public class ResourceFactoryManagerBean implements ResourceFactoryManagerLocal,
// Create/locate package and package version
PackageVersion packageVersion = null;
if (packageUploadDetails == null) {
- packageVersion = contentManager.createPackageVersion(packageName, newPackageType.getId(),
- packageVersionNumber, architectureId, packageBitStream);
+ packageVersion = contentManager.createPackageVersion(user, packageName,
+ newPackageType.getId(), packageVersionNumber, architectureId, packageBitStream);
} else {
packageVersion = contentManager.getUploadedPackageVersion(user, packageName,
newPackageType.getId(), packageVersionNumber, architectureId, packageBitStream, packageUploadDetails, newResourceTypeId, null);
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/webservices/WebservicesManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/webservices/WebservicesManagerBean.java
index 2ee417c..3a4910b 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/webservices/WebservicesManagerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/webservices/WebservicesManagerBean.java
@@ -68,6 +68,7 @@ import org.rhq.core.domain.content.PackageType;
import org.rhq.core.domain.content.PackageVersion;
import org.rhq.core.domain.content.Repo;
import org.rhq.core.domain.content.composite.PackageAndLatestVersionComposite;
+import org.rhq.core.domain.content.composite.PackageTypeAndVersionFormatComposite;
import org.rhq.core.domain.content.transfer.SubscribedRepo;
import org.rhq.core.domain.criteria.AlertCriteria;
import org.rhq.core.domain.criteria.AlertDefinitionCriteria;
@@ -517,6 +518,11 @@ public class WebservicesManagerBean implements WebservicesRemote {
return contentManager.findPackageType(subject, resourceTypeId, packageTypeName);
}
+ public PackageTypeAndVersionFormatComposite findPackageTypeWithVersionFormat(Subject subject,
+ Integer resourceTypeId, String packageTypeName) {
+ return contentManager.findPackageTypeWithVersionFormat(subject, resourceTypeId, packageTypeName);
+ }
+
public InstalledPackage getBackingPackageForResource(Subject subject, int resourceId) {
return contentManager.getBackingPackageForResource(subject, resourceId);
}
diff --git a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/plugin/pc/content/TestContentProvider.java b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/plugin/pc/content/TestContentProvider.java
index 0258f3a..749f73b 100644
--- a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/plugin/pc/content/TestContentProvider.java
+++ b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/plugin/pc/content/TestContentProvider.java
@@ -10,7 +10,9 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import org.rhq.core.domain.auth.Subject;
import org.rhq.core.domain.configuration.Configuration;
+import org.rhq.core.domain.content.PackageDetailsKey;
import org.rhq.core.domain.content.PackageVersion;
public class TestContentProvider implements ContentProvider, PackageSource, RepoSource, DistributionSource {
@@ -251,10 +253,6 @@ public class TestContentProvider implements ContentProvider, PackageSource, Repo
return bis;
}
- public Comparator<PackageVersion> getPackageVersionComparator() {
- return null;
- }
-
public void synchronizeDistribution(String repoName, DistributionSyncReport report,
Collection<DistributionDetails> existingDistros) throws SyncException, InterruptedException {
diff --git a/modules/enterprise/server/plugins/alert-cli/src/main/java/org/rhq/enterprise/server/plugins/alertCli/CliComponent.java b/modules/enterprise/server/plugins/alert-cli/src/main/java/org/rhq/enterprise/server/plugins/alertCli/CliComponent.java
index 2835ab9..d73b42e 100644
--- a/modules/enterprise/server/plugins/alert-cli/src/main/java/org/rhq/enterprise/server/plugins/alertCli/CliComponent.java
+++ b/modules/enterprise/server/plugins/alert-cli/src/main/java/org/rhq/enterprise/server/plugins/alertCli/CliComponent.java
@@ -35,7 +35,6 @@ import org.rhq.core.domain.configuration.Property;
import org.rhq.core.domain.configuration.PropertyList;
import org.rhq.core.domain.configuration.PropertyMap;
import org.rhq.core.domain.configuration.PropertySimple;
-import org.rhq.core.domain.content.PackageCategory;
import org.rhq.core.domain.content.PackageType;
import org.rhq.core.domain.content.PackageVersion;
import org.rhq.core.domain.criteria.AlertDefinitionCriteria;
@@ -50,7 +49,6 @@ import org.rhq.enterprise.server.alert.AlertDefinitionManagerLocal;
import org.rhq.enterprise.server.alert.AlertNotificationManagerLocal;
import org.rhq.enterprise.server.auth.SubjectManagerLocal;
import org.rhq.enterprise.server.content.ContentManagerLocal;
-import org.rhq.enterprise.server.content.RepoManagerLocal;
import org.rhq.enterprise.server.plugin.pc.ControlFacet;
import org.rhq.enterprise.server.plugin.pc.ControlResults;
import org.rhq.enterprise.server.plugin.pc.ServerPluginComponent;
@@ -67,14 +65,8 @@ import org.rhq.enterprise.server.xmlschema.generated.serverplugin.alert.AlertPlu
*/
public class CliComponent implements ServerPluginComponent, ControlFacet {
- //TODO the package type definition could be defined somewhere accessible
- //server-wide if we decide to use it in more places than just this alert sender
-
- public static final String PACKAGE_TYPE_NAME = "__SERVER_SIDE_CLI_SCRIPT";
- public static final String PACKAGE_TYPE_DESCRIPTION =
- "A CLI script running on the server-side.";
- public static final String PACKAGE_TYPE_DISPLAY_NAME = "Server-side CLI Script";
-
+ public static final String PACKAGE_TYPE_NAME = "org.rhq.enterprise.server.plugins.packagetypeCli.SERVER_SIDE_CLI_SCRIPT";
+
private static final String CONTROL_CHECK_ALERTS_VALIDITY = "checkAlertsValidity";
private static final String CONTROL_REASSIGN_ALERTS = "reassignAlerts";
@@ -93,36 +85,21 @@ public class CliComponent implements ServerPluginComponent, ControlFacet {
private PackageType packageType;
private int scriptTimeout;
- private SubjectManagerLocal subjectManager;
-
public void initialize(ServerPluginContext context) throws Exception {
pluginName = ((AlertPluginDescriptorType)context.getPluginEnvironment().getPluginDescriptor()).getShortName();
-
- subjectManager = LookupUtil.getSubjectManager();
- ContentManagerLocal cm = LookupUtil.getContentManager();
-
- packageType = cm.findPackageType(subjectManager.getOverlord(), null, PACKAGE_TYPE_NAME);
-
- if (packageType == null) {
- packageType = new PackageType(PACKAGE_TYPE_NAME, null);
- packageType.setCategory(PackageCategory.EXECUTABLE_SCRIPT);
- packageType.setDescription(PACKAGE_TYPE_DESCRIPTION);
- packageType.setDisplayName(PACKAGE_TYPE_DISPLAY_NAME);
- packageType.setSupportsArchitecture(false);
- packageType.setCreationData(false);
- packageType.setDeploymentConfigurationDefinition(null);
- packageType.setDiscoveryInterval(-1);
- packageType.setPackageExtraPropertiesDefinition(null);
-
- packageType = cm.persistServersidePackageType(packageType);
- }
-
+
String timeoutValue = context.getPluginConfiguration() == null ? "60" : context.getPluginConfiguration().getSimpleValue(PROP_SCRIPT_TIMEOUT, "60");
scriptTimeout = Integer.parseInt(timeoutValue);
}
public PackageType getScriptPackageType() {
+ if (packageType == null) {
+ SubjectManagerLocal subjectManager = LookupUtil.getSubjectManager();
+ ContentManagerLocal cm = LookupUtil.getContentManager();
+
+ packageType = cm.findPackageType(subjectManager.getOverlord(), null, PACKAGE_TYPE_NAME);
+ }
return packageType;
}
diff --git a/modules/enterprise/server/plugins/alert-cli/src/main/java/org/rhq/enterprise/server/plugins/alertCli/CliSender.java b/modules/enterprise/server/plugins/alert-cli/src/main/java/org/rhq/enterprise/server/plugins/alertCli/CliSender.java
index 3916c8a..61d5a3b 100644
--- a/modules/enterprise/server/plugins/alert-cli/src/main/java/org/rhq/enterprise/server/plugins/alertCli/CliSender.java
+++ b/modules/enterprise/server/plugins/alert-cli/src/main/java/org/rhq/enterprise/server/plugins/alertCli/CliSender.java
@@ -247,7 +247,7 @@ public class CliSender extends AlertSender<CliComponent> {
private static InputStream getPackageBits(int packageId, int repoId) throws IOException {
final ContentSourceManagerLocal csm = LookupUtil.getContentSourceManager();
RepoManagerLocal rm = LookupUtil.getRepoManagerLocal();
- final PackageVersion versionToUse = rm.getLatestPackageVersion(LookupUtil.getSubjectManager().getOverlord(), packageId, repoId, null);
+ final PackageVersion versionToUse = rm.getLatestPackageVersion(LookupUtil.getSubjectManager().getOverlord(), packageId, repoId);
if (versionToUse == null) {
throw new IllegalArgumentException("The package with id " + packageId + " either doesn't exist at all or doesn't have any version. Can't execute a CLI script without a script to run.");
diff --git a/modules/enterprise/server/plugins/disk/src/main/java/org/rhq/enterprise/server/plugins/disk/DiskSource.java b/modules/enterprise/server/plugins/disk/src/main/java/org/rhq/enterprise/server/plugins/disk/DiskSource.java
index 1c408ab..3155976 100644
--- a/modules/enterprise/server/plugins/disk/src/main/java/org/rhq/enterprise/server/plugins/disk/DiskSource.java
+++ b/modules/enterprise/server/plugins/disk/src/main/java/org/rhq/enterprise/server/plugins/disk/DiskSource.java
@@ -24,7 +24,6 @@ import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;
-import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -33,7 +32,6 @@ import org.rhq.core.domain.configuration.Configuration;
import org.rhq.core.domain.configuration.Property;
import org.rhq.core.domain.configuration.PropertyMap;
import org.rhq.core.domain.configuration.PropertySimple;
-import org.rhq.core.domain.content.PackageVersion;
import org.rhq.core.util.MessageDigestGenerator;
import org.rhq.core.util.file.ContentFileInfo;
import org.rhq.core.util.file.ContentFileInfoFactory;
@@ -166,20 +164,6 @@ public class DiskSource implements ContentProvider, PackageSource, RepoSource {
return new FileInputStream(new File(getRootDirectory(), location));
}
- /**
- * The disk source doesn't have a meaningful version strings, so this
- * implementation compares strictly by {@link PackageVersion#getFileCreatedDate() file creation date}.
- *
- * @return a comparator comparing two package versions coming from DiskSource by their file-created-date.
- */
- public Comparator<PackageVersion> getPackageVersionComparator() {
- return new Comparator<PackageVersion>() {
- public int compare(PackageVersion o1, PackageVersion o2) {
- return o1.getFileCreatedDate().compareTo(o2.getFileCreatedDate());
- }
- };
- }
-
protected File getRootDirectory() {
return this.rootDirectory;
}
@@ -332,7 +316,7 @@ public class DiskSource implements ContentProvider, PackageSource, RepoSource {
String resourceAndPlugin = configuration.getSimpleValue("resourceType", null);
- String resourceType = resourceAndPlugin.substring( (resourceAndPlugin.indexOf('-') + 1) );
+ String resourceType = resourceAndPlugin.substring((resourceAndPlugin.indexOf('-') + 1));
String pluginType = resourceAndPlugin.substring(0, resourceAndPlugin.indexOf('-'));
supportedPackageType.resourceTypeName = resourceType;
diff --git a/modules/enterprise/server/plugins/jboss-software/src/main/java/org/rhq/enterprise/server/plugins/jboss/software/JBossSoftwareContentSourceAdapter.java b/modules/enterprise/server/plugins/jboss-software/src/main/java/org/rhq/enterprise/server/plugins/jboss/software/JBossSoftwareContentSourceAdapter.java
index a40047a..2758e2b 100644
--- a/modules/enterprise/server/plugins/jboss-software/src/main/java/org/rhq/enterprise/server/plugins/jboss/software/JBossSoftwareContentSourceAdapter.java
+++ b/modules/enterprise/server/plugins/jboss-software/src/main/java/org/rhq/enterprise/server/plugins/jboss/software/JBossSoftwareContentSourceAdapter.java
@@ -22,7 +22,6 @@ import java.io.InputStream;
import java.net.URI;
import java.net.URL;
import java.util.Collection;
-import java.util.Comparator;
import churchillobjects.rss4j.RssDocument;
import churchillobjects.rss4j.parser.RssParser;
@@ -39,7 +38,6 @@ import org.apache.commons.logging.LogFactory;
import org.rhq.core.domain.configuration.Configuration;
import org.rhq.core.domain.configuration.PropertySimple;
-import org.rhq.core.domain.content.PackageVersion;
import org.rhq.enterprise.server.plugin.pc.content.ContentProvider;
import org.rhq.enterprise.server.plugin.pc.content.ContentProviderPackageDetails;
import org.rhq.enterprise.server.plugin.pc.content.PackageSource;
@@ -165,13 +163,6 @@ public class JBossSoftwareContentSourceAdapter implements ContentProvider, Packa
return stream;
}
- /**
- * @return null so that the {@link PackageVersion#DEFAULT_COMPARATOR} is used because it is well suited for the CSP packages.
- */
- public Comparator<PackageVersion> getPackageVersionComparator() {
- return null;
- }
-
public RepoImportReport importRepos() throws Exception {
RepoDetails repo = new RepoDetails("JBoss Patches");
diff --git a/modules/enterprise/server/plugins/packagetype-cli/pom.xml b/modules/enterprise/server/plugins/packagetype-cli/pom.xml
new file mode 100644
index 0000000..65c8e71
--- /dev/null
+++ b/modules/enterprise/server/plugins/packagetype-cli/pom.xml
@@ -0,0 +1,217 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <parent>
+ <artifactId>rhq-enterprise-server-plugins-parent</artifactId>
+ <groupId>org.rhq</groupId>
+ <version>4.0.0-SNAPSHOT</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.rhq</groupId>
+ <artifactId>packagetype-cli</artifactId>
+ <version>4.0.0-SNAPSHOT</version>
+
+ <name>RHQ Enterprise Server CLI Package Type Plugin</name>
+
+ <scm>
+ <connection>scm:git:ssh://git.fedorahosted.org/git/rhq.git/modules/enterprise/server/...
+ </connection>
+ <developerConnection>
+ scm:git:ssh://git.fedorahosted.org/git/rhq.git/modules/enterprise/server/...
+ </developerConnection>
+ </scm>
+
+ <properties>
+ <scm.module.path>modules/enterprise/server/plugins/packagetype-cli/</scm.module.path>
+ </properties>
+
+ <dependencies>
+
+ </dependencies>
+
+ <build>
+ <plugins>
+
+ <plugin>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <configuration>
+ <excludedGroups>${rhq.testng.excludedGroups}</excludedGroups>
+ <!--
+ <argLine>-Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,address=8787,server=y,suspend=y</argLine>
+ -->
+ </configuration>
+ </plugin>
+
+ </plugins>
+ </build>
+
+ <profiles>
+
+ <profile>
+ <id>dev</id>
+
+ <properties>
+ <rhq.rootDir>../../../../..</rhq.rootDir>
+ <rhq.containerDir>${rhq.rootDir}/${rhq.defaultDevContainerPath}</rhq.containerDir>
+ <rhq.deploymentDir>${rhq.containerDir}/jbossas/server/default/deploy/${rhq.earName}/rhq-serverplugins
+ </rhq.deploymentDir>
+ </properties>
+
+ <build>
+ <plugins>
+
+ <plugin>
+ <artifactId>maven-antrun-plugin</artifactId>
+ <version>1.1</version>
+ <executions>
+
+ <execution>
+ <id>deploy</id>
+ <phase>compile</phase>
+ <configuration>
+ <tasks>
+ <mkdir dir="${rhq.deploymentDir}" />
+ <property name="deployment.file" location="${rhq.deploymentDir}/${project.build.finalName}.jar" />
+ <echo>*** Updating ${deployment.file}...</echo>
+ <jar destfile="${deployment.file}" basedir="${project.build.outputDirectory}" />
+ </tasks>
+ </configuration>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ </execution>
+
+ <execution>
+ <id>undeploy</id>
+ <phase>clean</phase>
+ <configuration>
+ <tasks>
+ <property name="deployment.file" location="${rhq.deploymentDir}/${project.build.finalName}.jar" />
+ <echo>*** Deleting ${deployment.file}...</echo>
+ <delete file="${deployment.file}" />
+ </tasks>
+ </configuration>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ </execution>
+
+ <execution>
+ <id>deploy-jar-meta-inf</id>
+ <phase>package</phase>
+ <configuration>
+ <tasks>
+ <property name="deployment.file"
+ location="${rhq.deploymentDir}/${project.build.finalName}.jar" />
+ <echo>*** Updating META-INF dir
+ in ${deployment.file}...</echo>
+ <unjar
+ src="${project.build.directory}/${project.build.finalName}.jar"
+ dest="${project.build.outputDirectory}">
+ <patternset>
+ <include name="META-INF/**" />
+ </patternset>
+ </unjar>
+ <jar destfile="${deployment.file}"
+ manifest="${project.build.outputDirectory}/META-INF/MANIFEST.MF"
+ update="true">
+ </jar>
+ </tasks>
+ </configuration>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+
+ </plugins>
+ </build>
+ </profile>
+ <profile>
+ <id>cobertura-plugins</id>
+ <activation>
+ <activeByDefault>false</activeByDefault>
+ </activation>
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-antrun-plugin</artifactId>
+ <dependencies>
+ <dependency>
+ <groupId>net.sourceforge.cobertura</groupId>
+ <artifactId>cobertura</artifactId>
+ <version>${cobertura.version}</version>
+ </dependency>
+ </dependencies>
+ <executions>
+ <execution>
+ <id>cobertura-instrument</id>
+ <phase>pre-integration-test</phase>
+ <configuration>
+ <tasks>
+ <!-- prepare directory structure for cobertura-->
+ <mkdir dir="target/cobertura" />
+ <mkdir dir="target/cobertura/backup" />
+ <!-- backup all classes so that we can instrument the original classes-->
+ <copy toDir="target/cobertura/backup" verbose="true" overwrite="true">
+ <fileset dir="target/classes">
+ <include name="**/*.class" />
+ </fileset>
+ </copy>
+ <!-- create a properties file and save there location of cobertura data file-->
+ <touch file="target/classes/cobertura.properties" />
+ <echo file="target/classes/cobertura.properties">net.sourceforge.cobertura.datafile=${project.build.directory}/cobertura/cobertura.ser</echo>
+ <taskdef classpathref="maven.plugin.classpath" resource="tasks.properties" />
+ <!-- instrument all classes in target/classes directory -->
+ <cobertura-instrument datafile="${project.build.directory}/cobertura/cobertura.ser" todir="${project.build.directory}/classes">
+ <fileset dir="${project.build.directory}/classes">
+ <include name="**/*.class" />
+ </fileset>
+ </cobertura-instrument>
+ </tasks>
+ </configuration>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ </execution>
+ <execution>
+ <id>cobertura-report</id>
+ <phase>post-integration-test</phase>
+ <configuration>
+ <tasks>
+ <taskdef classpathref="maven.plugin.classpath" resource="tasks.properties" />
+ <!-- prepare directory structure for cobertura-->
+ <mkdir dir="target/cobertura" />
+ <mkdir dir="target/site/cobertura" />
+ <!-- restore classes from backup folder to classes folder -->
+ <copy toDir="target/classes" verbose="true" overwrite="true">
+ <fileset dir="target/cobertura/backup">
+ <include name="**/*.class" />
+ </fileset>
+ </copy>
+ <!-- delete backup folder-->
+ <delete dir="target/cobertura/backup" />
+ <!-- create a code coverage report -->
+ <cobertura-report format="html" datafile="${project.build.directory}/cobertura/cobertura.ser" destdir="${project.build.directory}/site/cobertura">
+ <fileset dir="${basedir}/src/main/java">
+ <include name="**/*.java" />
+ </fileset>
+ </cobertura-report>
+ <!-- delete cobertura.properties file -->
+ <delete file="target/classes/cobertura.properties" />
+ </tasks>
+ </configuration>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ </profiles>
+
+
+</project>
diff --git a/modules/enterprise/server/plugins/packagetype-cli/src/main/java/org/rhq/enterprise/server/plugins/packagetypeCli/CliPackageTypeBehavior.java b/modules/enterprise/server/plugins/packagetype-cli/src/main/java/org/rhq/enterprise/server/plugins/packagetypeCli/CliPackageTypeBehavior.java
new file mode 100644
index 0000000..ea9c376
--- /dev/null
+++ b/modules/enterprise/server/plugins/packagetype-cli/src/main/java/org/rhq/enterprise/server/plugins/packagetypeCli/CliPackageTypeBehavior.java
@@ -0,0 +1,132 @@
+/*
+ * 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 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.server.plugins.packagetypeCli;
+
+import java.util.Comparator;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.rhq.core.domain.auth.Subject;
+import org.rhq.core.domain.content.PackageVersion;
+import org.rhq.core.domain.content.PackageVersionFormatDescription;
+import org.rhq.core.domain.content.ValidatablePackageDetailsKey;
+import org.rhq.core.domain.util.OSGiVersion;
+import org.rhq.core.domain.util.OSGiVersionComparator;
+import org.rhq.enterprise.server.plugin.pc.ServerPluginComponent;
+import org.rhq.enterprise.server.plugin.pc.content.AbstractPackageTypeBehavior;
+import org.rhq.enterprise.server.plugin.pc.content.PackageDetailsValidationException;
+
+/**
+ * This plugin defines the version formatting of the server-side CLI package type.
+ *
+ * In order for the CLI packages to exist per user, the format of the version has to include
+ * the username.
+ *
+ * The format is therefore following:
+ *
+ * {username}:{osgi.version.string}
+ *
+ * @author Lukas Krejci
+ */
+public class CliPackageTypeBehavior extends AbstractPackageTypeBehavior<ServerPluginComponent> {
+
+ private static final Log LOG = LogFactory.getLog(CliPackageTypeBehavior.class);
+
+ private static final String FULL_VERSION_REGEX = "^([^:]+:)?\\d+(\\.\\d+(\\.\\d+(\\..*)?)?)?$";
+ private static final String OSGI_EXTRACT_REGEX = "^([^:]+:)?(\\d+(\\.\\d+(\\.\\d+(\\..*)?)?)?)$";
+ private static final int OSGI_EXTRACT_VERSION_GROUP = 2;
+
+ private static final String PACKAGETYPE_NAME = "__SERVER_SIDE_CLI_SCRIPT";
+
+ private static final Comparator<PackageVersion> VERSION_COMPARATOR = new Comparator<PackageVersion>() {
+ private final OSGiVersionComparator OSGI_COMPARATOR = new OSGiVersionComparator();
+ public int compare(PackageVersion o1, PackageVersion o2) {
+ String v1 = o1.getVersion();
+ String v2 = o2.getVersion();
+
+ if (v1 != null && v2 != null) {
+ String[] v1Parts = getVersionParts(v1);
+ String[] v2Parts = getVersionParts(v2);
+
+ if (v1Parts[1] != null && v2Parts[1] != null) {
+ try {
+ return OSGI_COMPARATOR.compare(v1Parts[1], v2Parts[1]);
+ } catch (IllegalArgumentException e) {
+ //well.. they don't look like OSGi versions
+ }
+ }
+ }
+
+ //as a fallback, compare by ID. But we're enforcing the format in the validate
+ //method so this shouldn't ever happen.
+
+ LOG.warn("Using a fallback version comparison on package versions " + o1 + " and " + o2 + ". This should not happen.");
+
+ return Integer.valueOf(o1.getId()).compareTo(o2.getId());
+ }
+ };
+
+ public Comparator<PackageVersion> getPackageVersionComparator(String packageTypeName) {
+ if (PACKAGETYPE_NAME.equals(packageTypeName)) {
+ return VERSION_COMPARATOR;
+ }
+ return null;
+ }
+
+ public void validateDetails(ValidatablePackageDetailsKey key, Subject origin)
+ throws PackageDetailsValidationException {
+
+ key.setVersion(reformatVersion(key.getVersion(), origin.getName()));
+ }
+
+ public PackageVersionFormatDescription getPackageVersionFormat(String packageTypeName) {
+ if (PACKAGETYPE_NAME.equals(packageTypeName)) {
+ return new PackageVersionFormatDescription(FULL_VERSION_REGEX, OSGI_EXTRACT_REGEX, OSGI_EXTRACT_VERSION_GROUP, null);
+ }
+ return null;
+ }
+
+ private static String reformatVersion(String version, String userName) throws PackageDetailsValidationException {
+ String[] parts = getVersionParts(version);
+
+ if (!OSGiVersion.isValid(parts[1])) {
+ //ok the user supplied something that isn't an OSGi version.
+ //We can't accept that.
+ throw new PackageDetailsValidationException("The version part of '" + version + "' isn't an OSGi version string.");
+ }
+
+ return userName + ":" + parts[1];
+ }
+
+ private static String[] getVersionParts(String version) {
+ String[] ret = new String[2];
+
+ int colonIdx = version.indexOf(':');
+ if (colonIdx >= 0 && colonIdx < version.length() - 1) {
+ ret[0] = version.substring(0, colonIdx);
+ ret[1] = version.substring(colonIdx + 1);
+ } else {
+ ret[1] = version;
+ }
+
+ return ret;
+ }
+}
diff --git a/modules/enterprise/server/plugins/packagetype-cli/src/main/resources/META-INF/rhq-serverplugin.xml b/modules/enterprise/server/plugins/packagetype-cli/src/main/resources/META-INF/rhq-serverplugin.xml
new file mode 100644
index 0000000..d57d82b
--- /dev/null
+++ b/modules/enterprise/server/plugins/packagetype-cli/src/main/resources/META-INF/rhq-serverplugin.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<packagetype-plugin name="packagetype-cli"
+ displayName="PackageType:CLI" xmlns="urn:xmlns:rhq-serverplugin.packagetype"
+ xmlns:c="urn:xmlns:rhq-configuration" xmlns:serverplugin="urn:xmlns:rhq-serverplugin"
+ package="org.rhq.enterprise.server.plugins.packagetypeCli"
+ description="A package type for CLI scripts.">
+
+ <serverplugin:help>
+ This plugin defines the "Server-side CLI Script"
+ package type used
+ by the Alert:CLI plugin to store the scripts in
+ the content subsystem.
+ </serverplugin:help>
+
+ <!-- How does this sender show up in drop downs etc -->
+ <behavior-class>CliPackageTypeBehavior</behavior-class>
+
+
+ <package-type
+ name="org.rhq.enterprise.server.plugins.packagetypeCli.SERVER_SIDE_CLI_SCRIPT"
+ displayName="Server-side CLI Script" description="A CLI script running on the server-side." />
+
+</packagetype-plugin>
diff --git a/modules/enterprise/server/plugins/pom.xml b/modules/enterprise/server/plugins/pom.xml
index 7da7c3b..2ebb23e 100644
--- a/modules/enterprise/server/plugins/pom.xml
+++ b/modules/enterprise/server/plugins/pom.xml
@@ -87,6 +87,7 @@
<module>ant-bundle</module>
<module>validate-all-serverplugins</module>
<module>groovy-script</module>
+ <module>packagetype-cli</module>
</modules>
</project>
diff --git a/modules/enterprise/server/plugins/rhnhosted/src/main/java/org/rhq/enterprise/server/plugins/rhnhosted/RHNProvider.java b/modules/enterprise/server/plugins/rhnhosted/src/main/java/org/rhq/enterprise/server/plugins/rhnhosted/RHNProvider.java
index f9710cf..03e7ba6 100644
--- a/modules/enterprise/server/plugins/rhnhosted/src/main/java/org/rhq/enterprise/server/plugins/rhnhosted/RHNProvider.java
+++ b/modules/enterprise/server/plugins/rhnhosted/src/main/java/org/rhq/enterprise/server/plugins/rhnhosted/RHNProvider.java
@@ -28,7 +28,6 @@ import java.net.URL;
import java.security.KeyException;
import java.util.ArrayList;
import java.util.Collection;
-import java.util.Comparator;
import java.util.List;
import org.apache.commons.io.FileUtils;
@@ -37,7 +36,6 @@ import org.apache.commons.logging.LogFactory;
import org.apache.xmlrpc.XmlRpcException;
import org.rhq.core.domain.configuration.Configuration;
-import org.rhq.core.domain.content.PackageVersion;
import org.rhq.enterprise.server.plugin.pc.content.AdvisoryDetails;
import org.rhq.enterprise.server.plugin.pc.content.AdvisorySource;
import org.rhq.enterprise.server.plugin.pc.content.AdvisorySyncReport;
@@ -227,13 +225,6 @@ public class RHNProvider implements ContentProvider, PackageSource, RepoSource,
}
/**
- * @return null so that the {@link PackageVersion#DEFAULT_COMPARATOR} is used because it is well suited for the RHN packages.
- */
- public Comparator<PackageVersion> getPackageVersionComparator() {
- return null;
- }
-
- /**
* @inheritDoc
*/
public void synchronizeAdvisory(String repoName, AdvisorySyncReport report,
diff --git a/modules/enterprise/server/plugins/url/src/main/java/org/rhq/enterprise/server/plugins/url/UrlProvider.java b/modules/enterprise/server/plugins/url/src/main/java/org/rhq/enterprise/server/plugins/url/UrlProvider.java
index 2f98600..c229a2b 100644
--- a/modules/enterprise/server/plugins/url/src/main/java/org/rhq/enterprise/server/plugins/url/UrlProvider.java
+++ b/modules/enterprise/server/plugins/url/src/main/java/org/rhq/enterprise/server/plugins/url/UrlProvider.java
@@ -25,7 +25,6 @@ import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.Collection;
-import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -34,7 +33,6 @@ import org.rhq.core.domain.configuration.Configuration;
import org.rhq.core.domain.configuration.Property;
import org.rhq.core.domain.configuration.PropertyList;
import org.rhq.core.domain.configuration.PropertyMap;
-import org.rhq.core.domain.content.PackageVersion;
import org.rhq.enterprise.server.plugin.pc.content.ContentProvider;
import org.rhq.enterprise.server.plugin.pc.content.ContentProviderPackageDetails;
import org.rhq.enterprise.server.plugin.pc.content.ContentProviderPackageDetailsKey;
@@ -211,14 +209,6 @@ public class UrlProvider implements ContentProvider, PackageSource {
return;
}
- /**
- * This uses the default comparator.
- * @return null so that the {@link PackageVersion#DEFAULT_COMPARATOR} is used.
- */
- public Comparator<PackageVersion> getPackageVersionComparator() {
- return null;
- }
-
public void testConnection() throws Exception {
// to test, just make sure we can read the index file;
// errors will caused exceptions to be thrown.
diff --git a/modules/enterprise/server/plugins/yum/src/main/java/org/rhq/enterprise/server/plugins/yum/RepoProvider.java b/modules/enterprise/server/plugins/yum/src/main/java/org/rhq/enterprise/server/plugins/yum/RepoProvider.java
index ffff370..f065ba7 100644
--- a/modules/enterprise/server/plugins/yum/src/main/java/org/rhq/enterprise/server/plugins/yum/RepoProvider.java
+++ b/modules/enterprise/server/plugins/yum/src/main/java/org/rhq/enterprise/server/plugins/yum/RepoProvider.java
@@ -21,14 +21,12 @@ package org.rhq.enterprise.server.plugins.yum;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;
-import java.util.Comparator;
import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.rhq.core.domain.configuration.Configuration;
-import org.rhq.core.domain.content.PackageVersion;
import org.rhq.enterprise.server.plugin.pc.content.ContentProvider;
import org.rhq.enterprise.server.plugin.pc.content.ContentProviderPackageDetails;
import org.rhq.enterprise.server.plugin.pc.content.PackageSource;
@@ -179,13 +177,6 @@ public class RepoProvider implements ContentProvider, PackageSource {
}
/**
- * @return null so that the {@link PackageVersion#DEFAULT_COMPARATOR} is used because it is well suited for YUM packages.
- */
- public Comparator<PackageVersion> getPackageVersionComparator() {
- return null;
- }
-
- /**
* Trim white space and trailing (/) characters.
*
* @param path A url/directory path string.
diff --git a/modules/enterprise/server/xml-schemas/src/main/java/org/rhq/enterprise/server/xmlschema/ServerPluginDescriptorUtil.java b/modules/enterprise/server/xml-schemas/src/main/java/org/rhq/enterprise/server/xmlschema/ServerPluginDescriptorUtil.java
index d427c05..00ba663 100644
--- a/modules/enterprise/server/xml-schemas/src/main/java/org/rhq/enterprise/server/xmlschema/ServerPluginDescriptorUtil.java
+++ b/modules/enterprise/server/xml-schemas/src/main/java/org/rhq/enterprise/server/xmlschema/ServerPluginDescriptorUtil.java
@@ -79,7 +79,8 @@ public abstract class ServerPluginDescriptorUtil {
PLUGIN_SCHEMA_PACKAGES.put(XmlSchemas.XSD_SERVERPLUGIN_ALERT, XmlSchemas.PKG_SERVERPLUGIN_ALERT);
PLUGIN_SCHEMA_PACKAGES.put(XmlSchemas.XSD_SERVERPLUGIN_ENTITLEMENT, XmlSchemas.PKG_SERVERPLUGIN_ENTITLEMENT);
PLUGIN_SCHEMA_PACKAGES.put(XmlSchemas.XSD_SERVERPLUGIN_BUNDLE, XmlSchemas.PKG_SERVERPLUGIN_BUNDLE);
-
+ PLUGIN_SCHEMA_PACKAGES.put(XmlSchemas.XSD_SERVERPLUGIN_PACKAGETYPE, XmlSchemas.PKG_SERVERPLUGIN_PACKAGETYPE);
+
// so we only have to do this once, build a ':' separated context path containing all schema package names
StringBuilder packages = new StringBuilder();
for (String packageName : PLUGIN_SCHEMA_PACKAGES.values()) {
diff --git a/modules/enterprise/server/xml-schemas/src/main/java/org/rhq/enterprise/server/xmlschema/XmlSchemas.java b/modules/enterprise/server/xml-schemas/src/main/java/org/rhq/enterprise/server/xmlschema/XmlSchemas.java
index 8d270e6..63050dd 100644
--- a/modules/enterprise/server/xml-schemas/src/main/java/org/rhq/enterprise/server/xmlschema/XmlSchemas.java
+++ b/modules/enterprise/server/xml-schemas/src/main/java/org/rhq/enterprise/server/xmlschema/XmlSchemas.java
@@ -62,6 +62,10 @@ public interface XmlSchemas {
public static final String XSD_SERVERPLUGIN_BUNDLE = "rhq-serverplugin-bundle.xsd";
public static final String PKG_SERVERPLUGIN_BUNDLE = "org.rhq.enterprise.server.xmlschema.generated.serverplugin.bundle";
+ // the server plugin descriptor for the package type plugin type
+ public static final String XSD_SERVERPLUGIN_PACKAGETYPE = "rhq-serverplugin-packagetype.xsd";
+ public static final String PKG_SERVERPLUGIN_PACKAGETYPE = "org.rhq.enterprise.server.xmlschema.generated.serverplugin.packagetype";
+
// the configuration schema that can be reused in any other server-side schema to define normal configuration properties
public static final String XSD_CONFIGURATION = "rhq-configuration.xsd";
public static final String PKG_CONFIGURATION = DescriptorPackages.CONFIGURATION;
diff --git a/modules/enterprise/server/xml-schemas/src/main/resources/rhq-serverplugin-packagetype.xsd b/modules/enterprise/server/xml-schemas/src/main/resources/rhq-serverplugin-packagetype.xsd
new file mode 100644
index 0000000..fff6046
--- /dev/null
+++ b/modules/enterprise/server/xml-schemas/src/main/resources/rhq-serverplugin-packagetype.xsd
@@ -0,0 +1,144 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
+ xmlns:serverplugin="urn:xmlns:rhq-serverplugin" xmlns:config="urn:xmlns:rhq-configuration"
+ xmlns:c="urn:xmlns:rhq-configuration" xmlns:packagetype="urn:xmlns:rhq-serverplugin.packagetype"
+ targetNamespace="urn:xmlns:rhq-serverplugin.packagetype"
+ elementFormDefault="qualified" jaxb:version="2.0"
+ xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" blockDefault="">
+
+ <xs:import namespace="urn:xmlns:rhq-serverplugin"
+ schemaLocation="rhq-serverplugin.xsd" />
+ <xs:import namespace="urn:xmlns:rhq-configuration"
+ schemaLocation="rhq-configuration.xsd" />
+
+ <xs:annotation>
+ <xs:documentation>
+ Schema for package type server-side plug-ins.
+ </xs:documentation>
+ <xs:appinfo>
+ <jaxb:schemaBindings>
+ <jaxb:package
+ name="org.rhq.enterprise.server.xmlschema.generated.serverplugin.packagetype" />
+ </jaxb:schemaBindings>
+ </xs:appinfo>
+ </xs:annotation>
+
+ <xs:element name="packagetype-plugin"
+ type="packagetype:PackageTypePluginDescriptorType"
+ substitutionGroup="serverplugin:server-plugin">
+ <xs:annotation>
+ <xs:documentation>
+ Defines a server-side package type
+ plug-in. This type of plug-in allows you to define your
+ own package types.
+ Users are then able to create packages
+ of those types and the data stored in the content
+ subsystem for such
+ packages can then be used in other
+ server-side plugins.
+ </xs:documentation>
+ <xs:appinfo>
+ <jaxb:class name="PackageTypePluginElement" />
+ </xs:appinfo>
+ </xs:annotation>
+ </xs:element>
+
+ <xs:complexType name="PackageTypePluginDescriptorType">
+ <xs:complexContent>
+ <xs:extension base="serverplugin:ServerPluginDescriptorType">
+ <xs:sequence>
+ <xs:element name="behavior-class" type="xs:string"
+ minOccurs="1" maxOccurs="1">
+ <xs:annotation>
+ <xs:documentation>
+ The name of the class
+ implementing the
+ PackageTypeBehavior
+ interface.
+ This class provides runtime
+ hooks for checking
+ the correctness of the
+ packages of different types.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:element>
+ <xs:element name="package-type"
+ type="packagetype:PackageTypeDefinitionType"
+ minOccurs="0" maxOccurs="unbounded">
+ <xs:annotation>
+ <xs:documentation>
+ The list of package types
+ this plugin defines.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:element>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="PackageTypeDefinitionType">
+ <xs:sequence>
+ <xs:element name="configuration" type="config:configuration"
+ minOccurs="0">
+ <xs:annotation>
+ <xs:documentation>
+ Describes properties that dictate
+ how the package was deployed or
+ installed. The
+ user will be
+ prompted for values for these
+ properties when deploying a new package of
+ this
+ type.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:element>
+ </xs:sequence>
+ <xs:attribute name="name" type="xs:string" use="required">
+ <xs:annotation>
+ <xs:documentation>
+ Name of this package type. This must
+ be unique across all other package
+ types defined for
+ this
+ resource type.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute name="displayName" type="xs:string"
+ use="optional">
+ <xs:annotation>
+ <xs:documentation>
+ The user friendly name of the package
+ type that will be displayed in
+ the UI.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute name="description" type="xs:string"
+ use="optional">
+ <xs:annotation>
+ <xs:documentation>
+ Description of the package type that
+ will be displayed in the UI.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute name="supportsArchitecture" type="xs:boolean"
+ use="optional" default="false">
+ <xs:annotation>
+ <xs:documentation>
+ Indicates packages of this type may be
+ of different architectures. If this
+ is set to false,
+ when
+ creating new packages of this type, the
+ architecture will be defaulted to
+ "noarch".
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ </xs:complexType>
+</xs:schema>
commit 28f92d3dfcd8ac86c89e241b52a1dee6084f9a3f
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Fri Feb 25 17:52:56 2011 +0100
Caching custom interfaces for resource proxies obtained from ProxyFactory.
This is especially important in the server environment so that we don't waste the permgen if we don't have to.
By relying on the resource type structure to determine equality of resource types, plugin updates are seemlessly supported.
diff --git a/modules/enterprise/binding/src/main/java/org/rhq/bindings/client/ResourceClientFactory.java b/modules/enterprise/binding/src/main/java/org/rhq/bindings/client/ResourceClientFactory.java
index 480a5dd..6f15e81 100644
--- a/modules/enterprise/binding/src/main/java/org/rhq/bindings/client/ResourceClientFactory.java
+++ b/modules/enterprise/binding/src/main/java/org/rhq/bindings/client/ResourceClientFactory.java
@@ -4,10 +4,10 @@ import java.io.PrintWriter;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Collections;
+import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Set;
-import java.util.concurrent.atomic.AtomicInteger;
import javax.jws.WebParam;
@@ -27,6 +27,7 @@ import javassist.util.proxy.MethodHandler;
import javassist.util.proxy.ProxyFactory;
import org.rhq.bindings.util.ConfigurationClassBuilder;
+import org.rhq.bindings.util.ResourceTypeFingerprint;
import org.rhq.core.domain.resource.ResourceCreationDataType;
/**
@@ -36,8 +37,16 @@ import org.rhq.core.domain.resource.ResourceCreationDataType;
*/
public class ResourceClientFactory {
+ private static class CacheRecord {
+ public ResourceTypeFingerprint fingerprint;
+ public Class<?> iface;
+ }
+
private static final Log LOG = LogFactory.getLog(ResourceClientFactory.class);
+ //keys are resource type ids
+ private static HashMap<Integer, CacheRecord> CUSTOM_CLASS_CACHE = new HashMap<Integer, CacheRecord>();
+
private RhqFacade rhqFacade;
private PrintWriter outputWriter;
@@ -46,8 +55,6 @@ public class ResourceClientFactory {
this.outputWriter = outputWriter;
}
- private static AtomicInteger classIndex = new AtomicInteger();
-
public RhqFacade getRemoteClient() {
return rhqFacade;
}
@@ -60,73 +67,22 @@ public class ResourceClientFactory {
ResourceClientProxy proxy = new ResourceClientProxy(this, resourceId);
Class<?> customInterface = null;
- try {
- // define the dynamic class
- ClassPool pool = ClassPool.getDefault();
- CtClass customClass = pool.makeInterface(ResourceClientProxy.class.getName() + "__Custom__"
- + classIndex.getAndIncrement());
-
- for (String key : proxy.allProperties.keySet()) {
- Object prop = proxy.allProperties.get(key);
-
- if (prop instanceof ResourceClientProxy.Measurement) {
- ResourceClientProxy.Measurement m = (ResourceClientProxy.Measurement) prop;
- String name = ResourceClientProxy.getterName(key);
-
- try {
- ResourceClientProxy.class.getMethod(name);
- } catch (NoSuchMethodException nsme) {
- CtMethod method = CtNewMethod.abstractMethod(pool.get(ResourceClientProxy.Measurement.class.getName()),
- ResourceClientProxy.getterName(key), new CtClass[0], new CtClass[0], customClass);
- customClass.addMethod(method);
- }
- } else if (prop instanceof ResourceClientProxy.Operation) {
- ResourceClientProxy.Operation o = (ResourceClientProxy.Operation) prop;
-
- LinkedHashMap<String, CtClass> types = ConfigurationClassBuilder.translateParameters(o
- .getDefinition().getParametersConfigurationDefinition());
-
- CtClass[] params = new CtClass[types.size()];
- int x = 0;
- for (String param : types.keySet()) {
- params[x++] = types.get(param);
- }
-
- CtMethod method = CtNewMethod.abstractMethod(ConfigurationClassBuilder.translateConfiguration(o
- .getDefinition().getResultsConfigurationDefinition()), ResourceClientProxy.simpleName(key), params,
- new javassist.CtClass[0], customClass);
-
- // Setup @WebParam annotations so the signatures have the config prop names
- Annotation[][] newAnnotations = new Annotation[params.length][1];
- int i = 0;
- for (String paramName : types.keySet()) {
- newAnnotations[i] = new Annotation[1];
-
- newAnnotations[i][0] = new Annotation(WebParam.class.getName(), method.getMethodInfo()
- .getConstPool());
- newAnnotations[i][0].addMemberValue("name", new StringMemberValue(paramName, method
- .getMethodInfo().getConstPool()));
- i++;
- }
-
- ParameterAnnotationsAttribute newAnnotationsAttribute = new ParameterAnnotationsAttribute(
- method.getMethodInfo().getConstPool(), ParameterAnnotationsAttribute.visibleTag);
- newAnnotationsAttribute.setAnnotations(newAnnotations);
- method.getMethodInfo().addAttribute(newAnnotationsAttribute);
-
- customClass.addMethod(method);
- }
+ synchronized (CUSTOM_CLASS_CACHE) {
+ Integer resourceTypeId = proxy.getResourceType().getId();
+ CacheRecord record = CUSTOM_CLASS_CACHE.get(resourceTypeId);
+
+ //if we don't have a cached custom interface for this resource type
+ //or if the resource type has changed, generate the custom iface for it.
+ if (record == null || !record.fingerprint.equals(proxy.fingerprint)) {
+ record = new CacheRecord();
+ record.fingerprint = proxy.fingerprint;
+ record.iface = defineCustomInterface(proxy);
+ CUSTOM_CLASS_CACHE.put(resourceTypeId, record);
}
-
- customInterface = customClass.toClass();
- } catch (NotFoundException e) {
- LOG.error("Could not create custom interface for resource with id " + resourceId, e);
- } catch (CannotCompileException e) {
- LOG.error("Could not create custom interface for resource with id " + resourceId, e);
- } catch (Exception e) {
- LOG.error("Could not create custom interface for resource with id " + resourceId, e);
+
+ customInterface = record.iface;
}
-
+
if (customInterface != null) {
List<Class<?>> interfaces = new ArrayList<Class<?>>();
@@ -185,4 +141,73 @@ public class ResourceClientFactory {
protected MethodHandler instantiateMethodHandler(ResourceClientProxy proxy, List<Class<?>> interfaces, RhqFacade remoteClient) {
return new ResourceClientProxy.ClientProxyMethodHandler(proxy, remoteClient);
}
+
+ private Class<?> defineCustomInterface(ResourceClientProxy proxy) {
+ try {
+ // define the dynamic class
+ ClassPool pool = ClassPool.getDefault();
+ CtClass customClass = pool.makeInterface(ResourceClientProxy.class.getName() + proxy.fingerprint);
+
+ for (String key : proxy.allProperties.keySet()) {
+ Object prop = proxy.allProperties.get(key);
+
+ if (prop instanceof ResourceClientProxy.Measurement) {
+ String name = ResourceClientProxy.getterName(key);
+
+ try {
+ ResourceClientProxy.class.getMethod(name);
+ } catch (NoSuchMethodException nsme) {
+ CtMethod method = CtNewMethod.abstractMethod(pool.get(ResourceClientProxy.Measurement.class.getName()),
+ ResourceClientProxy.getterName(key), new CtClass[0], new CtClass[0], customClass);
+ customClass.addMethod(method);
+ }
+ } else if (prop instanceof ResourceClientProxy.Operation) {
+ ResourceClientProxy.Operation o = (ResourceClientProxy.Operation) prop;
+
+ LinkedHashMap<String, CtClass> types = ConfigurationClassBuilder.translateParameters(o
+ .getDefinition().getParametersConfigurationDefinition());
+
+ CtClass[] params = new CtClass[types.size()];
+ int x = 0;
+ for (String param : types.keySet()) {
+ params[x++] = types.get(param);
+ }
+
+ CtMethod method = CtNewMethod.abstractMethod(ConfigurationClassBuilder.translateConfiguration(o
+ .getDefinition().getResultsConfigurationDefinition()), ResourceClientProxy.simpleName(key), params,
+ new javassist.CtClass[0], customClass);
+
+ // Setup @WebParam annotations so the signatures have the config prop names
+ Annotation[][] newAnnotations = new Annotation[params.length][1];
+ int i = 0;
+ for (String paramName : types.keySet()) {
+ newAnnotations[i] = new Annotation[1];
+
+ newAnnotations[i][0] = new Annotation(WebParam.class.getName(), method.getMethodInfo()
+ .getConstPool());
+ newAnnotations[i][0].addMemberValue("name", new StringMemberValue(paramName, method
+ .getMethodInfo().getConstPool()));
+ i++;
+ }
+
+ ParameterAnnotationsAttribute newAnnotationsAttribute = new ParameterAnnotationsAttribute(
+ method.getMethodInfo().getConstPool(), ParameterAnnotationsAttribute.visibleTag);
+ newAnnotationsAttribute.setAnnotations(newAnnotations);
+ method.getMethodInfo().addAttribute(newAnnotationsAttribute);
+
+ customClass.addMethod(method);
+ }
+ }
+
+ return customClass.toClass();
+ } catch (NotFoundException e) {
+ LOG.error("Could not create custom interface for resource with id " + proxy.getId(), e);
+ } catch (CannotCompileException e) {
+ LOG.error("Could not create custom interface for resource with id " + proxy.getId(), e);
+ } catch (Exception e) {
+ LOG.error("Could not create custom interface for resource with id " + proxy.getId(), e);
+ }
+
+ return null;
+ }
}
diff --git a/modules/enterprise/binding/src/main/java/org/rhq/bindings/client/ResourceClientProxy.java b/modules/enterprise/binding/src/main/java/org/rhq/bindings/client/ResourceClientProxy.java
index 5b49e18..b850605 100644
--- a/modules/enterprise/binding/src/main/java/org/rhq/bindings/client/ResourceClientProxy.java
+++ b/modules/enterprise/binding/src/main/java/org/rhq/bindings/client/ResourceClientProxy.java
@@ -29,10 +29,14 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
import javassist.util.proxy.MethodHandler;
import org.rhq.bindings.util.ConfigurationClassBuilder;
import org.rhq.bindings.util.LazyLoadScenario;
+import org.rhq.bindings.util.ResourceTypeFingerprint;
import org.rhq.bindings.util.ScriptUtil;
import org.rhq.bindings.util.ShortOutput;
import org.rhq.core.domain.configuration.Configuration;
@@ -74,6 +78,8 @@ import org.rhq.enterprise.server.resource.ResourceTypeNotFoundException;
*/
public class ResourceClientProxy {
+ private static final Log LOG = LogFactory.getLog(ResourceClientProxy.class);
+
private ResourceClientFactory proxyFactory;
private RhqFacade remoteClient;
private int resourceId;
@@ -81,6 +87,8 @@ public class ResourceClientProxy {
Map<String, Object> allProperties = new HashMap<String, Object>();
+ ResourceTypeFingerprint fingerprint;
+
// Metadata
private List<MeasurementDefinition> measurementDefinitions;
private Map<String, Measurement> measurementMap = new HashMap<String, Measurement>();
@@ -197,6 +205,14 @@ public class ResourceClientProxy {
initOperations();
initConfigDefs();
initContent();
+
+ List<PackageType> packageTypes = new ArrayList<PackageType>();
+ for(ContentType ct : contentTypes.values()) {
+ packageTypes.add(ct.getPackageType());
+ }
+
+ fingerprint = new ResourceTypeFingerprint(resource.getResourceType(), measurementDefinitions,
+ operationDefinitions, packageTypes, pluginConfigurationDefinition, resourceConfigurationDefinition);
}
private void initConfigDefs() {
@@ -267,7 +283,7 @@ public class ResourceClientProxy {
contentTypes.put(packageType.getName(), new ContentType(packageType));
}
} catch (ResourceTypeNotFoundException e) {
- e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
+ LOG.error("Could not find resource type while creating content mappings of the resource proxy for resource with id " + resourceId, e);
}
}
diff --git a/modules/enterprise/binding/src/main/java/org/rhq/bindings/util/ResourceTypeFingerprint.java b/modules/enterprise/binding/src/main/java/org/rhq/bindings/util/ResourceTypeFingerprint.java
new file mode 100644
index 0000000..fa20b86
--- /dev/null
+++ b/modules/enterprise/binding/src/main/java/org/rhq/bindings/util/ResourceTypeFingerprint.java
@@ -0,0 +1,182 @@
+/*
+ * 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 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.bindings.util;
+
+import java.util.Collection;
+import java.util.Map;
+
+import org.rhq.core.domain.configuration.definition.ConfigurationDefinition;
+import org.rhq.core.domain.configuration.definition.PropertyDefinition;
+import org.rhq.core.domain.configuration.definition.PropertyDefinitionList;
+import org.rhq.core.domain.configuration.definition.PropertyDefinitionMap;
+import org.rhq.core.domain.configuration.definition.PropertyDefinitionSimple;
+import org.rhq.core.domain.content.PackageType;
+import org.rhq.core.domain.measurement.MeasurementDefinition;
+import org.rhq.core.domain.operation.OperationDefinition;
+import org.rhq.core.domain.resource.ResourceType;
+import org.rhq.core.util.MessageDigestGenerator;
+
+/**
+ * This type is used as an identification of a resource type not based
+ * on its id but rather on its structure.
+ *
+ * @author Lukas Krejci
+ */
+public class ResourceTypeFingerprint {
+
+ private String digest;
+
+ public ResourceTypeFingerprint(ResourceType rt, Collection<MeasurementDefinition> measurements,
+ Collection<OperationDefinition> operations, Collection<PackageType> packageTypes,
+ ConfigurationDefinition pluginConfigurationDefinition, ConfigurationDefinition resourceConfigurationDefinition) {
+
+ digest = computeDigest(rt, measurements, operations, packageTypes, pluginConfigurationDefinition,
+ resourceConfigurationDefinition);
+ }
+
+ @Override
+ public int hashCode() {
+ return digest.hashCode();
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (this == other) {
+ return true;
+ }
+
+ if (!(other instanceof ResourceTypeFingerprint)) {
+ return false;
+ }
+
+ ResourceTypeFingerprint o = (ResourceTypeFingerprint) other;
+
+ return digest.equals(o.digest);
+ }
+
+ @Override
+ public String toString() {
+ return digest;
+ }
+
+ private static String computeDigest(ResourceType rt, Collection<MeasurementDefinition> measurements,
+ Collection<OperationDefinition> operations, Collection<PackageType> packageTypes,
+ ConfigurationDefinition pluginConfigurationDefinition, ConfigurationDefinition resourceConfigurationDefinition) {
+
+ StringBuilder representation = new StringBuilder();
+
+ addResourceTypeRepresentation(rt, representation);
+ addMeasurementDefinitionsRepresentations(measurements, representation);
+ addOperationDefinitionsRepresentations(operations, representation);
+ addPackageTypesRepresentations(packageTypes, representation);
+ addRepresentation(pluginConfigurationDefinition, representation);
+ addRepresentation(resourceConfigurationDefinition, representation);
+
+ return new MessageDigestGenerator(MessageDigestGenerator.SHA_256).calcDigestString(representation.toString());
+ }
+
+ private static void addResourceTypeRepresentation(ResourceType rt, StringBuilder bld) {
+ bld.append(rt.getName()).append(rt.getPlugin());
+ }
+
+ private static void addMeasurementDefinitionsRepresentations(Collection<MeasurementDefinition> defs,
+ StringBuilder bld) {
+ if (defs == null) {
+ bld.append("null");
+ } else {
+ for (MeasurementDefinition d : defs) {
+ addRepresentation(d, bld);
+ }
+ }
+ }
+
+ private static void addOperationDefinitionsRepresentations(Collection<OperationDefinition> defs, StringBuilder bld) {
+ if (defs == null) {
+ bld.append("null");
+ } else {
+ for (OperationDefinition d : defs) {
+ addRepresentation(d, bld);
+ }
+ }
+ }
+
+ private static void addPackageTypesRepresentations(Collection<PackageType> defs, StringBuilder bld) {
+ if (defs == null) {
+ bld.append("null");
+ } else {
+ for (PackageType d : defs) {
+ addRepresentation(d, bld);
+ }
+ }
+ }
+
+ private static void addRepresentation(MeasurementDefinition md, StringBuilder bld) {
+ bld.append(md.getName());
+ }
+
+ private static void addRepresentation(OperationDefinition od, StringBuilder bld) {
+ bld.append(od.getName());
+ addRepresentation(od.getResultsConfigurationDefinition(), bld);
+ addRepresentation(od.getParametersConfigurationDefinition(), bld);
+ }
+
+ private static void addRepresentation(PackageType pt, StringBuilder bld) {
+ bld.append(pt.getName());
+ }
+
+ private static void addRepresentation(ConfigurationDefinition cd, StringBuilder bld) {
+ if (cd == null) {
+ bld.append("null");
+ } else {
+ addRepresentation(cd.getPropertyDefinitions(), bld);
+ }
+ }
+
+ private static void addRepresentation(Map<String, PropertyDefinition> defs, StringBuilder bld) {
+ for (Map.Entry<String, PropertyDefinition> entry : defs.entrySet()) {
+ PropertyDefinition def = entry.getValue();
+ addRepresentation(def, bld);
+ }
+ }
+
+ private static void addRepresentation(PropertyDefinition def, StringBuilder bld) {
+ if (def instanceof PropertyDefinitionSimple) {
+ addRepresentation((PropertyDefinitionSimple) def, bld);
+ } else if (def instanceof PropertyDefinitionMap) {
+ addRepresentation((PropertyDefinitionMap) def, bld);
+ } else if (def instanceof PropertyDefinitionList) {
+ addRepresentation((PropertyDefinitionList) def, bld);
+ }
+ }
+
+ private static void addRepresentation(PropertyDefinitionSimple p, StringBuilder bld) {
+ bld.append(p.getName()).append(p.getType().name());
+ }
+
+ private static void addRepresentation(PropertyDefinitionMap pm, StringBuilder bld) {
+ bld.append(pm.getName());
+ addRepresentation(pm.getPropertyDefinitions(), bld);
+ }
+
+ private static void addRepresentation(PropertyDefinitionList pl, StringBuilder bld) {
+ bld.append(pl.getName());
+ addRepresentation(pl.getMemberDefinition(), bld);
+ }
+}
commit d64951a6f0b4478e85156cb08bd1e9ca772b97f1
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Fri Feb 25 15:31:10 2011 +0100
remove e.printStacktrace(), import classes instead of using full names.
diff --git a/modules/enterprise/binding/src/main/java/org/rhq/bindings/client/ResourceClientFactory.java b/modules/enterprise/binding/src/main/java/org/rhq/bindings/client/ResourceClientFactory.java
index 2112073..480a5dd 100644
--- a/modules/enterprise/binding/src/main/java/org/rhq/bindings/client/ResourceClientFactory.java
+++ b/modules/enterprise/binding/src/main/java/org/rhq/bindings/client/ResourceClientFactory.java
@@ -1,14 +1,30 @@
package org.rhq.bindings.client;
import java.io.PrintWriter;
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
import java.util.Collections;
+import java.util.LinkedHashMap;
import java.util.List;
import java.util.Set;
+import java.util.concurrent.atomic.AtomicInteger;
+import javax.jws.WebParam;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import javassist.CannotCompileException;
import javassist.ClassPool;
+import javassist.CtClass;
+import javassist.CtMethod;
import javassist.CtNewMethod;
+import javassist.NotFoundException;
import javassist.bytecode.ParameterAnnotationsAttribute;
+import javassist.bytecode.annotation.Annotation;
+import javassist.bytecode.annotation.StringMemberValue;
import javassist.util.proxy.MethodHandler;
+import javassist.util.proxy.ProxyFactory;
import org.rhq.bindings.util.ConfigurationClassBuilder;
import org.rhq.core.domain.resource.ResourceCreationDataType;
@@ -20,17 +36,19 @@ import org.rhq.core.domain.resource.ResourceCreationDataType;
*/
public class ResourceClientFactory {
- private org.rhq.bindings.client.RhqFacade rhqFacade;
+ private static final Log LOG = LogFactory.getLog(ResourceClientFactory.class);
+
+ private RhqFacade rhqFacade;
private PrintWriter outputWriter;
- public ResourceClientFactory(org.rhq.bindings.client.RhqFacade remoteClient, PrintWriter outputWriter) {
+ public ResourceClientFactory(RhqFacade remoteClient, PrintWriter outputWriter) {
this.rhqFacade = remoteClient;
this.outputWriter = outputWriter;
}
- private static java.util.concurrent.atomic.AtomicInteger classIndex = new java.util.concurrent.atomic.AtomicInteger();
+ private static AtomicInteger classIndex = new AtomicInteger();
- public org.rhq.bindings.client.RhqFacade getRemoteClient() {
+ public RhqFacade getRemoteClient() {
return rhqFacade;
}
@@ -38,60 +56,60 @@ public class ResourceClientFactory {
return outputWriter;
}
- public org.rhq.bindings.client.ResourceClientProxy getResource(int resourceId) {
+ public ResourceClientProxy getResource(int resourceId) {
- org.rhq.bindings.client.ResourceClientProxy proxy = new org.rhq.bindings.client.ResourceClientProxy(this, resourceId);
- java.lang.Class<?> customInterface = null;
+ ResourceClientProxy proxy = new ResourceClientProxy(this, resourceId);
+ Class<?> customInterface = null;
try {
// define the dynamic class
- javassist.ClassPool pool = ClassPool.getDefault();
- javassist.CtClass customClass = pool.makeInterface(org.rhq.bindings.client.ResourceClientProxy.class.getName() + "__Custom__"
+ ClassPool pool = ClassPool.getDefault();
+ CtClass customClass = pool.makeInterface(ResourceClientProxy.class.getName() + "__Custom__"
+ classIndex.getAndIncrement());
- for (java.lang.String key : proxy.allProperties.keySet()) {
- java.lang.Object prop = proxy.allProperties.get(key);
+ for (String key : proxy.allProperties.keySet()) {
+ Object prop = proxy.allProperties.get(key);
- if (prop instanceof org.rhq.bindings.client.ResourceClientProxy.Measurement) {
- org.rhq.bindings.client.ResourceClientProxy.Measurement m = (org.rhq.bindings.client.ResourceClientProxy.Measurement) prop;
- java.lang.String name = org.rhq.bindings.client.ResourceClientProxy.getterName(key);
+ if (prop instanceof ResourceClientProxy.Measurement) {
+ ResourceClientProxy.Measurement m = (ResourceClientProxy.Measurement) prop;
+ String name = ResourceClientProxy.getterName(key);
try {
- org.rhq.bindings.client.ResourceClientProxy.class.getMethod(name);
- } catch (java.lang.NoSuchMethodException nsme) {
- javassist.CtMethod method = CtNewMethod.abstractMethod(pool.get(org.rhq.bindings.client.ResourceClientProxy.Measurement.class.getName()),
- org.rhq.bindings.client.ResourceClientProxy.getterName(key), new javassist.CtClass[0], new javassist.CtClass[0], customClass);
+ ResourceClientProxy.class.getMethod(name);
+ } catch (NoSuchMethodException nsme) {
+ CtMethod method = CtNewMethod.abstractMethod(pool.get(ResourceClientProxy.Measurement.class.getName()),
+ ResourceClientProxy.getterName(key), new CtClass[0], new CtClass[0], customClass);
customClass.addMethod(method);
}
- } else if (prop instanceof org.rhq.bindings.client.ResourceClientProxy.Operation) {
- org.rhq.bindings.client.ResourceClientProxy.Operation o = (org.rhq.bindings.client.ResourceClientProxy.Operation) prop;
+ } else if (prop instanceof ResourceClientProxy.Operation) {
+ ResourceClientProxy.Operation o = (ResourceClientProxy.Operation) prop;
- java.util.LinkedHashMap<java.lang.String, javassist.CtClass> types = ConfigurationClassBuilder.translateParameters(o
+ LinkedHashMap<String, CtClass> types = ConfigurationClassBuilder.translateParameters(o
.getDefinition().getParametersConfigurationDefinition());
- javassist.CtClass[] params = new javassist.CtClass[types.size()];
+ CtClass[] params = new CtClass[types.size()];
int x = 0;
- for (java.lang.String param : types.keySet()) {
+ for (String param : types.keySet()) {
params[x++] = types.get(param);
}
- javassist.CtMethod method = CtNewMethod.abstractMethod(ConfigurationClassBuilder.translateConfiguration(o
- .getDefinition().getResultsConfigurationDefinition()), org.rhq.bindings.client.ResourceClientProxy.simpleName(key), params,
+ CtMethod method = CtNewMethod.abstractMethod(ConfigurationClassBuilder.translateConfiguration(o
+ .getDefinition().getResultsConfigurationDefinition()), ResourceClientProxy.simpleName(key), params,
new javassist.CtClass[0], customClass);
// Setup @WebParam annotations so the signatures have the config prop names
- javassist.bytecode.annotation.Annotation[][] newAnnotations = new javassist.bytecode.annotation.Annotation[params.length][1];
+ Annotation[][] newAnnotations = new Annotation[params.length][1];
int i = 0;
- for (java.lang.String paramName : types.keySet()) {
- newAnnotations[i] = new javassist.bytecode.annotation.Annotation[1];
+ for (String paramName : types.keySet()) {
+ newAnnotations[i] = new Annotation[1];
- newAnnotations[i][0] = new javassist.bytecode.annotation.Annotation(javax.jws.WebParam.class.getName(), method.getMethodInfo()
+ newAnnotations[i][0] = new Annotation(WebParam.class.getName(), method.getMethodInfo()
.getConstPool());
- newAnnotations[i][0].addMemberValue("name", new javassist.bytecode.annotation.StringMemberValue(paramName, method
+ newAnnotations[i][0].addMemberValue("name", new StringMemberValue(paramName, method
.getMethodInfo().getConstPool()));
i++;
}
- javassist.bytecode.ParameterAnnotationsAttribute newAnnotationsAttribute = new javassist.bytecode.ParameterAnnotationsAttribute(
+ ParameterAnnotationsAttribute newAnnotationsAttribute = new ParameterAnnotationsAttribute(
method.getMethodInfo().getConstPool(), ParameterAnnotationsAttribute.visibleTag);
newAnnotationsAttribute.setAnnotations(newAnnotations);
method.getMethodInfo().addAttribute(newAnnotationsAttribute);
@@ -101,17 +119,17 @@ public class ResourceClientFactory {
}
customInterface = customClass.toClass();
- } catch (javassist.NotFoundException e) {
- e.printStackTrace();
- } catch (javassist.CannotCompileException e) {
- e.printStackTrace();
- } catch (java.lang.Exception e) {
- e.printStackTrace();
+ } catch (NotFoundException e) {
+ LOG.error("Could not create custom interface for resource with id " + resourceId, e);
+ } catch (CannotCompileException e) {
+ LOG.error("Could not create custom interface for resource with id " + resourceId, e);
+ } catch (Exception e) {
+ LOG.error("Could not create custom interface for resource with id " + resourceId, e);
}
if (customInterface != null) {
- java.util.List<java.lang.Class<?>> interfaces = new java.util.ArrayList<java.lang.Class<?>>();
+ List<Class<?>> interfaces = new ArrayList<Class<?>>();
interfaces.add(customInterface);
if (proxy.resourceConfigurationDefinition != null) {
interfaces.add(getResourceConfigurableInterface());
@@ -126,21 +144,21 @@ public class ResourceClientFactory {
interfaces.addAll(getAdditionalInterfaces(proxy));
- javassist.util.proxy.ProxyFactory proxyFactory = new javassist.util.proxy.ProxyFactory();
- proxyFactory.setInterfaces(interfaces.toArray(new java.lang.Class[interfaces.size()]));
- proxyFactory.setSuperclass(org.rhq.bindings.client.ResourceClientProxy.class);
- org.rhq.bindings.client.ResourceClientProxy proxied = null;
+ ProxyFactory proxyFactory = new ProxyFactory();
+ proxyFactory.setInterfaces(interfaces.toArray(new Class[interfaces.size()]));
+ proxyFactory.setSuperclass(ResourceClientProxy.class);
+ ResourceClientProxy proxied = null;
try {
- proxied = (org.rhq.bindings.client.ResourceClientProxy) proxyFactory.create(new java.lang.Class[]{}, new java.lang.Object[]{},
+ proxied = (ResourceClientProxy) proxyFactory.create(new Class[]{}, new Object[]{},
instantiateMethodHandler(proxy, interfaces, rhqFacade));
- } catch (java.lang.InstantiationException e) {
- e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
- } catch (java.lang.IllegalAccessException e) {
- e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
- } catch (java.lang.NoSuchMethodException e) {
- e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
- } catch (java.lang.reflect.InvocationTargetException e) {
- e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
+ } catch (InstantiationException e) {
+ LOG.error("Could not instantiate a ResourceClientProxy, this is a bug.", e);
+ } catch (IllegalAccessException e) {
+ LOG.error("Could not instantiate a ResourceClientProxy, this is a bug.", e);
+ } catch (NoSuchMethodException e) {
+ LOG.error("Could not instantiate a ResourceClientProxy, this is a bug.", e);
+ } catch (InvocationTargetException e) {
+ LOG.error("Could not instantiate a ResourceClientProxy, this is a bug.", e);
}
return proxied;
}
@@ -149,22 +167,22 @@ public class ResourceClientFactory {
}
protected Class<?> getResourceConfigurableInterface() {
- return org.rhq.bindings.client.ResourceClientProxy.ResourceConfigurable.class;
+ return ResourceClientProxy.ResourceConfigurable.class;
}
protected Class<?> getPluginConfigurableInterface() {
- return org.rhq.bindings.client.ResourceClientProxy.PluginConfigurable.class;
+ return ResourceClientProxy.PluginConfigurable.class;
}
protected Class<?> getContentBackedInterface() {
- return org.rhq.bindings.client.ResourceClientProxy.ContentBackedResource.class;
+ return ResourceClientProxy.ContentBackedResource.class;
}
protected Set<Class<?>> getAdditionalInterfaces(ResourceClientProxy proxy) {
return Collections.emptySet();
}
- protected MethodHandler instantiateMethodHandler(ResourceClientProxy proxy, List<Class<?>> interfaces, org.rhq.bindings.client.RhqFacade remoteClient) {
- return new org.rhq.bindings.client.ResourceClientProxy.ClientProxyMethodHandler(proxy, remoteClient);
+ protected MethodHandler instantiateMethodHandler(ResourceClientProxy proxy, List<Class<?>> interfaces, RhqFacade remoteClient) {
+ return new ResourceClientProxy.ClientProxyMethodHandler(proxy, remoteClient);
}
}
commit 80edc2625c2e8348f52647cfb6910ea6cd4a3315
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Fri Feb 25 13:36:46 2011 +0100
Suggesting the package version in the upload form of the CLI notification editor.
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/util/OSGiVersion.java b/modules/core/domain/src/main/java/org/rhq/core/domain/util/OSGiVersion.java
new file mode 100644
index 0000000..0c9d664
--- /dev/null
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/util/OSGiVersion.java
@@ -0,0 +1,153 @@
+/*
+ * 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 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.core.domain.util;
+
+/**
+ * A simple representation of an OSGi formatted version string.
+ *
+ * All fields except the "major" part of the version can be undefined.
+ *
+ * @author Lukas Krejci
+ */
+public class OSGiVersion {
+ private int major;
+ private Integer minor;
+ private Integer micro;
+ private String qualifier;
+
+ public OSGiVersion() {
+
+ }
+
+ public OSGiVersion(String version) {
+ String[] parts = version.split("\\.");
+
+ try {
+ switch (parts.length) {
+ case 4: {
+ qualifier = parts[3];
+ }
+
+ case 3: {
+ micro = Integer.parseInt(parts[2]);
+ }
+
+ case 2: {
+ minor = Integer.parseInt(parts[1]);
+ }
+
+ case 1: {
+ major = Integer.parseInt(parts[0]);
+ break;
+ }
+
+ default: {
+ throw new IllegalArgumentException("Malformed version string [" + version + "]");
+ }
+ }
+ } catch (NumberFormatException e) {
+ throw new IllegalArgumentException("Malformed version string [" + version + "]");
+ }
+ }
+
+ /**
+ * @return the major
+ */
+ public int getMajor() {
+ return major;
+ }
+
+ /**
+ * @param major the major to set
+ */
+ public void setMajor(int major) {
+ this.major = major;
+ }
+
+ /**
+ * @return the minor
+ */
+ public Integer getMinorIfDefined() {
+ return minor;
+ }
+
+ public int getMinor() {
+ return minor == null ? 0 : minor;
+ }
+
+ /**
+ * @param minor the minor to set
+ */
+ public void setMinor(Integer minor) {
+ this.minor = minor;
+ }
+
+ /**
+ * @return the micro
+ */
+ public int getMicro() {
+ return micro == null ? 0 : micro;
+ }
+
+ public Integer getMicroIfDefined() {
+ return micro;
+ }
+
+ /**
+ * @param micro the micro to set
+ */
+ public void setMicro(Integer micro) {
+ this.micro = micro;
+ }
+
+ /**
+ * @return the qualifier
+ */
+ public String getQualifier() {
+ return qualifier;
+ }
+
+ /**
+ * @param qualifier the qualifier to set
+ */
+ public void setQualifier(String qualifier) {
+ this.qualifier = qualifier;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder bld = new StringBuilder();
+ bld.append(major);
+
+ if (minor != null) {
+ bld.append(".").append(minor);
+ }
+
+ if (micro != null) {
+ bld.append(".").append(micro);
+ }
+
+ if (qualifier != null) {
+ bld.append(".").append(qualifier);
+ }
+
+ return bld.toString();
+ }
+}
\ No newline at end of file
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/util/OSGiVersionComparator.java b/modules/core/domain/src/main/java/org/rhq/core/domain/util/OSGiVersionComparator.java
index 1f3936d..70cdc74 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/util/OSGiVersionComparator.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/util/OSGiVersionComparator.java
@@ -37,58 +37,32 @@ public class OSGiVersionComparator implements Comparator<String> {
}
public int compare(String string1, String string2) {
- Version ver1 = new Version(string1);
- Version ver2 = new Version(string2);
+ OSGiVersion ver1 = new OSGiVersion(string1);
+ OSGiVersion ver2 = new OSGiVersion(string2);
- int result = ver1.major - ver2.major;
+ int result = ver1.getMajor() - ver2.getMajor();
if (result == 0) {
- result = ver1.minor - ver2.minor;
+ result = ver1.getMinor() - ver2.getMinor();
if (result == 0) {
- result = ver1.micro - ver2.micro;
+ result = ver1.getMicro() - ver2.getMicro();
if (result == 0) {
- result = ver1.qualifier.compareTo(ver2.qualifier);
+ if (ver1.getQualifier() != null) {
+ if (ver2.getQualifier() == null) {
+ result = 1;
+ } else {
+ ver1.getQualifier().compareTo(ver2.getQualifier());
+ }
+ } else {
+ if (ver2.getQualifier() == null) {
+ result = 0;
+ } else {
+ result = -1;
+ }
+ }
}
}
}
return result;
}
-
- private class Version {
- int major;
- int minor;
- int micro;
- String qualifier = "";
-
- Version(String version) {
- String[] parts = version.split("\\.");
-
- try {
- switch (parts.length) {
- case 4: {
- qualifier = parts[3];
- }
-
- case 3: {
- micro = Integer.parseInt(parts[2]);
- }
-
- case 2: {
- minor = Integer.parseInt(parts[1]);
- }
-
- case 1: {
- major = Integer.parseInt(parts[0]);
- break;
- }
-
- default: {
- throw new IllegalArgumentException("Malformed version string [" + version + "]");
- }
- }
- } catch (NumberFormatException e) {
- throw new IllegalArgumentException("Malformed version string [" + version + "]");
- }
- }
- }
}
\ No newline at end of file
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/CliNotificationSenderForm.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/CliNotificationSenderForm.java
index 69a2a65..e8d1c1c 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/CliNotificationSenderForm.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/CliNotificationSenderForm.java
@@ -28,6 +28,10 @@ import com.smartgwt.client.types.TitleOrientation;
import com.smartgwt.client.widgets.form.DynamicForm;
import com.smartgwt.client.widgets.form.events.FormSubmitFailedEvent;
import com.smartgwt.client.widgets.form.events.FormSubmitFailedHandler;
+import com.smartgwt.client.widgets.form.events.ItemChangeEvent;
+import com.smartgwt.client.widgets.form.events.ItemChangeHandler;
+import com.smartgwt.client.widgets.form.events.ItemChangedEvent;
+import com.smartgwt.client.widgets.form.events.ItemChangedHandler;
import com.smartgwt.client.widgets.form.fields.ButtonItem;
import com.smartgwt.client.widgets.form.fields.FormItem;
import com.smartgwt.client.widgets.form.fields.FormItemIcon;
@@ -35,6 +39,7 @@ import com.smartgwt.client.widgets.form.fields.PasswordItem;
import com.smartgwt.client.widgets.form.fields.SectionItem;
import com.smartgwt.client.widgets.form.fields.SelectItem;
import com.smartgwt.client.widgets.form.fields.TextItem;
+import com.smartgwt.client.widgets.form.fields.UploadItem;
import com.smartgwt.client.widgets.form.fields.events.ChangedEvent;
import com.smartgwt.client.widgets.form.fields.events.ChangedHandler;
import com.smartgwt.client.widgets.form.fields.events.ClickEvent;
@@ -49,6 +54,7 @@ import org.rhq.core.domain.content.composite.PackageAndLatestVersionComposite;
import org.rhq.core.domain.criteria.PackageCriteria;
import org.rhq.core.domain.criteria.RepoCriteria;
import org.rhq.core.domain.criteria.SubjectCriteria;
+import org.rhq.core.domain.util.OSGiVersion;
import org.rhq.core.domain.util.PageList;
import org.rhq.enterprise.gui.coregui.client.CoreGUI;
import org.rhq.enterprise.gui.coregui.client.ImageManager;
@@ -570,6 +576,40 @@ public class CliNotificationSenderForm extends AbstractNotificationSenderForm {
};
uploadForm.addFormHandler(uploadSuccessHandler);
+ uploadForm.addItemChangeHandler(new ItemChangeHandler() {
+ public void onItemChange(ItemChangeEvent event) {
+ if (event.getItem() instanceof UploadItem) {
+ String fileName = event.getNewValue().toString();
+
+ if (config.allPackages != null) {
+ for(PackageAndLatestVersionComposite plv : config.allPackages) {
+ if (plv.getGeneralPackage().getName().equals(fileName)) {
+ try {
+ OSGiVersion v = new OSGiVersion(plv.getLatestPackageVersion().getVersion());
+ if (v.getMicroIfDefined() != null) {
+ v.setMicro(v.getMicro() + 1);
+ } else if (v.getMinorIfDefined() != null) {
+ v.setMinor(v.getMinor() + 1);
+ } else {
+ v.setMajor(v.getMajor() + 1);
+ }
+
+ uploadForm.getField("editableVersion").setValue(v.toString());
+ return;
+ } catch (IllegalArgumentException e) {
+ //ok, can't suggest anything
+ return;
+ }
+ }
+ }
+
+ //no existing package exists with the same name as the file being uploaded
+ uploadForm.getField("editableVersion").setValue("1.0");
+ }
+ }
+ }
+ });
+
return uploadForm;
}
commit efe26a4bc40b213c69507be5ad6679ab77c9893d
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Fri Feb 25 13:35:55 2011 +0100
small changes in the script engine factory, more useful configuration preview and error messages in the CliSender.
diff --git a/modules/enterprise/binding/src/main/java/org/rhq/bindings/ScriptEngineFactory.java b/modules/enterprise/binding/src/main/java/org/rhq/bindings/ScriptEngineFactory.java
index 7472953..345017f 100644
--- a/modules/enterprise/binding/src/main/java/org/rhq/bindings/ScriptEngineFactory.java
+++ b/modules/enterprise/binding/src/main/java/org/rhq/bindings/ScriptEngineFactory.java
@@ -80,15 +80,24 @@ public class ScriptEngineFactory {
ScriptEngine engine = initializer.instantiate(packageFinder.findPackages("org.rhq.core.domain"));
- injectStandardBindings(engine, bindings);
+ injectStandardBindings(engine, bindings, true);
return engine;
}
- public static void injectStandardBindings(ScriptEngine engine, StandardBindings bindings) {
+ /**
+ * Injects the values provided in the bindings into the {@link ScriptContext#ENGINE_SCOPE engine scope}
+ * of the provided script engine.
+ *
+ * @param engine the engine
+ * @param bindings the bindings
+ * @param deleteExistingBindings true if the existing bindings should be replaced by the provided ones, false
+ * if the provided bindings should be added to the existing ones (possibly overwriting bindings with the same name).
+ */
+ public static void injectStandardBindings(ScriptEngine engine, StandardBindings bindings, boolean deleteExistingBindings) {
bindings.preInject(engine);
- Bindings engineBindings = engine.getBindings(ScriptContext.ENGINE_SCOPE);
+ Bindings engineBindings = deleteExistingBindings ? engine.createBindings() : engine.getBindings(ScriptContext.ENGINE_SCOPE);
for(Map.Entry<String, Object> entry : bindings.entrySet()) {
engineBindings.put(entry.getKey(), entry.getValue());
diff --git a/modules/enterprise/binding/src/main/java/org/rhq/bindings/engine/JsEngineInitializer.java b/modules/enterprise/binding/src/main/java/org/rhq/bindings/engine/JsEngineInitializer.java
index eba36f3..3aa4616 100644
--- a/modules/enterprise/binding/src/main/java/org/rhq/bindings/engine/JsEngineInitializer.java
+++ b/modules/enterprise/binding/src/main/java/org/rhq/bindings/engine/JsEngineInitializer.java
@@ -20,7 +20,6 @@
package org.rhq.bindings.engine;
import java.lang.reflect.Method;
-import java.util.List;
import java.util.Set;
import javax.script.ScriptEngine;
@@ -34,13 +33,14 @@ import javax.script.ScriptException;
*/
public class JsEngineInitializer implements ScriptEngineInitializer {
+ private ScriptEngineManager engineManager = new ScriptEngineManager();
+
public boolean implementsLanguage(String language) {
return language != null && ("JavaScript".equals(language) || "ECMAScript".equals(language));
}
public ScriptEngine instantiate(Set<String> packages) throws ScriptException {
- ScriptEngineManager sem = new ScriptEngineManager();
- ScriptEngine eng = sem.getEngineByName("JavaScript");
+ ScriptEngine eng = engineManager.getEngineByName("JavaScript");
for(String pkg : packages) {
eng.eval("importPackage(" + pkg + ")");
diff --git a/modules/enterprise/remoting/cli/src/main/java/org/rhq/enterprise/client/commands/ScriptCommand.java b/modules/enterprise/remoting/cli/src/main/java/org/rhq/enterprise/client/commands/ScriptCommand.java
index dfc2b4c..8da9d9f 100644
--- a/modules/enterprise/remoting/cli/src/main/java/org/rhq/enterprise/client/commands/ScriptCommand.java
+++ b/modules/enterprise/remoting/cli/src/main/java/org/rhq/enterprise/client/commands/ScriptCommand.java
@@ -181,7 +181,7 @@ public class ScriptCommand implements ClientCommand {
bindings.put("configurationEditor", new ConfigurationEditor(client));
bindings.put("rhq", new Controller(client));
- ScriptEngineFactory.injectStandardBindings(jsEngine, bindings);
+ ScriptEngineFactory.injectStandardBindings(jsEngine, bindings, true);
ScriptEngineFactory.bindIndirectionMethods(jsEngine, "configurationEditor", bindings.get("configurationEditor"));
ScriptEngineFactory.bindIndirectionMethods(jsEngine, "rhq", bindings.get("rhq"));
diff --git a/modules/enterprise/server/plugins/alert-cli/src/main/java/org/rhq/enterprise/server/plugins/alertCli/CliSender.java b/modules/enterprise/server/plugins/alert-cli/src/main/java/org/rhq/enterprise/server/plugins/alertCli/CliSender.java
index a9ee867..3916c8a 100644
--- a/modules/enterprise/server/plugins/alert-cli/src/main/java/org/rhq/enterprise/server/plugins/alertCli/CliSender.java
+++ b/modules/enterprise/server/plugins/alert-cli/src/main/java/org/rhq/enterprise/server/plugins/alertCli/CliSender.java
@@ -25,19 +25,14 @@ import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
-import java.io.OutputStream;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
import java.io.PrintWriter;
import java.nio.charset.Charset;
import java.util.ArrayDeque;
import java.util.Collections;
-import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
-import java.util.concurrent.ArrayBlockingQueue;
-import java.util.concurrent.ConcurrentLinkedQueue;
-import java.util.concurrent.atomic.AtomicInteger;
import javax.script.ScriptEngine;
import javax.script.ScriptException;
@@ -54,7 +49,6 @@ import org.rhq.core.domain.alert.Alert;
import org.rhq.core.domain.alert.notification.SenderResult;
import org.rhq.core.domain.auth.Subject;
import org.rhq.core.domain.configuration.PropertySimple;
-import org.rhq.core.domain.content.PackageType;
import org.rhq.core.domain.content.PackageVersion;
import org.rhq.core.domain.content.Repo;
import org.rhq.core.domain.criteria.RepoCriteria;
@@ -64,7 +58,6 @@ import org.rhq.enterprise.server.auth.SessionManager;
import org.rhq.enterprise.server.auth.SubjectManagerLocal;
import org.rhq.enterprise.server.content.ContentSourceManagerLocal;
import org.rhq.enterprise.server.content.RepoManagerLocal;
-import org.rhq.enterprise.server.plugin.pc.ServerPluginComponent;
import org.rhq.enterprise.server.plugin.pc.alert.AlertSender;
import org.rhq.enterprise.server.plugin.pc.alert.AlertSenderValidationResults;
import org.rhq.enterprise.server.util.LookupUtil;
@@ -256,6 +249,10 @@ public class CliSender extends AlertSender<CliComponent> {
RepoManagerLocal rm = LookupUtil.getRepoManagerLocal();
final PackageVersion versionToUse = rm.getLatestPackageVersion(LookupUtil.getSubjectManager().getOverlord(), packageId, repoId, null);
+ if (versionToUse == null) {
+ throw new IllegalArgumentException("The package with id " + packageId + " either doesn't exist at all or doesn't have any version. Can't execute a CLI script without a script to run.");
+ }
+
PipedInputStream ret = new PipedInputStream();
final PipedOutputStream out = new PipedOutputStream(ret);
@@ -308,11 +305,16 @@ public class CliSender extends AlertSender<CliComponent> {
Subject overlord = LookupUtil.getSubjectManager().getOverlord();
RepoManagerLocal rm = LookupUtil.getRepoManagerLocal();
PackageVersion versionToUse = rm.getLatestPackageVersion(overlord, config.packageId, config.repoId);
-
- ret = ret.replace("$packageName", versionToUse.getDisplayName());
- ret = ret.replace("$packageVersion", versionToUse.getDisplayVersion() == null ? versionToUse.getVersion()
- : versionToUse.getDisplayVersion());
-
+
+ if (versionToUse != null) {
+ ret = ret.replace("$packageName", versionToUse.getDisplayName());
+ ret = ret.replace("$packageVersion", versionToUse.getDisplayVersion() == null ? versionToUse.getVersion()
+ : versionToUse.getDisplayVersion());
+ } else {
+ ret = ret.replace("$packageName", "unknown script with package id " + config.packageId);
+ ret = ret.replace("$packageVersion", "no version");
+ }
+
RepoCriteria criteria = new RepoCriteria();
criteria.addFilterId(config.repoId);
@@ -382,7 +384,7 @@ public class CliSender extends AlertSender<CliComponent> {
engine = ScriptEngineFactory.getScriptEngine("JavaScript",
new PackageFinder(Collections.<File> emptyList()), bindings);
} else {
- ScriptEngineFactory.injectStandardBindings(engine, bindings);
+ ScriptEngineFactory.injectStandardBindings(engine, bindings, true);
}
++ENGINES_IN_USE;
commit 9a16c738c5429d182ec5732013911574e8f3eeea
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Fri Feb 25 13:34:31 2011 +0100
remove unused import
diff --git a/modules/enterprise/binding/src/main/java/org/rhq/bindings/SandboxedScriptEngine.java b/modules/enterprise/binding/src/main/java/org/rhq/bindings/SandboxedScriptEngine.java
index faf3e15..ed3de18 100644
--- a/modules/enterprise/binding/src/main/java/org/rhq/bindings/SandboxedScriptEngine.java
+++ b/modules/enterprise/binding/src/main/java/org/rhq/bindings/SandboxedScriptEngine.java
@@ -26,7 +26,6 @@ import java.security.CodeSource;
import java.security.Permission;
import java.security.PermissionCollection;
import java.security.Permissions;
-import java.security.Principal;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.security.ProtectionDomain;
commit 45ceab2c82a6d2718295abeab0413f9ac8bc6064
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Fri Feb 25 13:34:11 2011 +0100
Make the CLI alert plugin controls for managing invalid alert definitions actually work and return more useful data.
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/AlertDefinitionCriteria.java b/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/AlertDefinitionCriteria.java
index e38a452..e8b6895 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/AlertDefinitionCriteria.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/AlertDefinitionCriteria.java
@@ -69,8 +69,10 @@ public class AlertDefinitionCriteria extends Criteria {
filterOverrides.put("alertTemplateResourceTypeId", "resourceType.id = ?");
filterOverrides.put("alertTemplateResourceTypeName", "resourceType.name like ?");
filterOverrides.put("resourceIds", "resource.id IN ( ? )");
- filterOverrides.put("resourceGroupIds", "resourceGroup.id IN ( ? )");
- filterOverrides.put("notificationSenderNames", "alertNotifications.senderName IN ( ? )");
+ filterOverrides.put("resourceGroupIds", "resourceGroup.id IN ( ? )");
+ filterOverrides.put("notificationSenderNames", "id IN (" +
+ "SELECT notif.alertDefinition.id FROM AlertNotification notif " +
+ "WHERE notif.senderName IN ( ? ))");
filterOverrides.put("filterIds", "id IN ( ? )");
}
diff --git a/modules/enterprise/server/plugins/alert-cli/src/main/java/org/rhq/enterprise/server/plugins/alertCli/CliComponent.java b/modules/enterprise/server/plugins/alert-cli/src/main/java/org/rhq/enterprise/server/plugins/alertCli/CliComponent.java
index 93c5fee..2835ab9 100644
--- a/modules/enterprise/server/plugins/alert-cli/src/main/java/org/rhq/enterprise/server/plugins/alertCli/CliComponent.java
+++ b/modules/enterprise/server/plugins/alert-cli/src/main/java/org/rhq/enterprise/server/plugins/alertCli/CliComponent.java
@@ -22,8 +22,10 @@ package org.rhq.enterprise.server.plugins.alertCli;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
+import java.util.HashSet;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import org.rhq.core.domain.alert.AlertDefinition;
import org.rhq.core.domain.alert.notification.AlertNotification;
@@ -35,15 +37,20 @@ import org.rhq.core.domain.configuration.PropertyMap;
import org.rhq.core.domain.configuration.PropertySimple;
import org.rhq.core.domain.content.PackageCategory;
import org.rhq.core.domain.content.PackageType;
+import org.rhq.core.domain.content.PackageVersion;
import org.rhq.core.domain.criteria.AlertDefinitionCriteria;
+import org.rhq.core.domain.criteria.Criteria.Restriction;
+import org.rhq.core.domain.criteria.PackageVersionCriteria;
import org.rhq.core.domain.resource.composite.DisambiguationReport;
import org.rhq.core.domain.util.DisambiguationReportRenderer;
import org.rhq.core.domain.util.PageControl;
+import org.rhq.core.domain.util.PageList;
import org.rhq.core.util.IntExtractor;
import org.rhq.enterprise.server.alert.AlertDefinitionManagerLocal;
import org.rhq.enterprise.server.alert.AlertNotificationManagerLocal;
import org.rhq.enterprise.server.auth.SubjectManagerLocal;
import org.rhq.enterprise.server.content.ContentManagerLocal;
+import org.rhq.enterprise.server.content.RepoManagerLocal;
import org.rhq.enterprise.server.plugin.pc.ControlFacet;
import org.rhq.enterprise.server.plugin.pc.ControlResults;
import org.rhq.enterprise.server.plugin.pc.ServerPluginComponent;
@@ -51,6 +58,7 @@ import org.rhq.enterprise.server.plugin.pc.ServerPluginContext;
import org.rhq.enterprise.server.resource.ResourceManagerLocal;
import org.rhq.enterprise.server.resource.disambiguation.DefaultDisambiguationUpdateStrategies;
import org.rhq.enterprise.server.util.LookupUtil;
+import org.rhq.enterprise.server.xmlschema.generated.serverplugin.alert.AlertPluginDescriptorType;
/**
* The plugin component for controlling the CLI alerts.
@@ -73,7 +81,8 @@ public class CliComponent implements ServerPluginComponent, ControlFacet {
private static final String PROP_ALERT_DEFINITION_NAME = "alertDefinitionName";
private static final String PROP_RESOURCE_PATH = "resourcePath";
private static final String PROP_RESOURCE_ID = "resourceId";
- private static final String PROP_MISCONFIGURED_ALERT_DEFS = "misconfiguredAlertDefs";
+ private static final String PROP_MISSING_USERS = "missingUsers";
+ private static final String PROP_MISSING_SCRIPTS = "missingScripts";
private static final String PROP_ALERT_DEFINITION = "alertDefinition";
private static final String PROP_ALERT_DEFINITION_ID = "alertDefinitionId";
private static final String PROP_USER_NAME = "userName";
@@ -87,7 +96,7 @@ public class CliComponent implements ServerPluginComponent, ControlFacet {
private SubjectManagerLocal subjectManager;
public void initialize(ServerPluginContext context) throws Exception {
- pluginName = context.getPluginEnvironment().getPluginDescriptor().getName();
+ pluginName = ((AlertPluginDescriptorType)context.getPluginEnvironment().getPluginDescriptor()).getShortName();
subjectManager = LookupUtil.getSubjectManager();
ContentManagerLocal cm = LookupUtil.getContentManager();
@@ -147,34 +156,33 @@ public class CliComponent implements ServerPluginComponent, ControlFacet {
}
private void checkAlertsValidity(ControlResults results, Configuration parameters) {
- List<AlertNotification> invalidNotifs = getAllCliNotificationsWithInvalidUser();
+ List<AlertNotification> allCliNotifications = getAllCliNotifications(null);
+
+ Configuration resConfig = results.getComplexResults();
- for(AlertNotification cliNotification : invalidNotifs) {
- AlertDefinition def = cliNotification.getAlertDefinition();
-
- Configuration resConfig = results.getComplexResults();
-
- PropertyList misconfigured = resConfig.getList(PROP_MISCONFIGURED_ALERT_DEFS);
- if (misconfigured == null) {
- misconfigured = new PropertyList(PROP_MISCONFIGURED_ALERT_DEFS);
- resConfig.put(misconfigured);
- }
-
- PropertyMap alertDefinitionMap = new PropertyMap(PROP_ALERT_DEFINITION);
-
- alertDefinitionMap.put(new PropertySimple(PROP_ALERT_DEFINITION_ID, def.getId()));
- alertDefinitionMap.put(new PropertySimple(PROP_ALERT_DEFINITION_NAME, def.getName()));
- alertDefinitionMap.put(new PropertySimple(PROP_RESOURCE_ID, def.getResource().getId()));
-
- misconfigured.add(alertDefinitionMap);
- }
+ PropertyList missingUsersList = new PropertyList(PROP_MISSING_USERS);
+ resConfig.put(missingUsersList);
+
+ List<AlertNotification> invalidNotifs = getCliNotificationsWithInvalidUser(allCliNotifications);
+ convertNotificationsToInvalidAlertDefResults(missingUsersList, invalidNotifs);
+
+ PropertyList missingScriptsList = new PropertyList(PROP_MISSING_SCRIPTS);
+ resConfig.put(missingScriptsList);
+
+ invalidNotifs = getCliNotificationsWithInvalidPackage(allCliNotifications);
+ convertNotificationsToInvalidAlertDefResults(missingScriptsList, invalidNotifs);
//ok, now we have to obtain the resource paths. doing it out of the above loop reduces the number
//of server roundtrips
- ResourceManagerLocal resourceManager = LookupUtil.getResourceManager();
- PropertyList misconfigured = results.getComplexResults().getList(PROP_MISCONFIGURED_ALERT_DEFS);
- if (misconfigured != null) {
- List<DisambiguationReport<Property>> disambiguated = resourceManager.disambiguate(misconfigured.getList(),
+
+ List<Property> allMissing = new ArrayList<Property>();
+ allMissing.addAll(missingUsersList.getList());
+ allMissing.addAll(missingScriptsList.getList());
+
+ if (allMissing.size() > 0) {
+ ResourceManagerLocal resourceManager = LookupUtil.getResourceManager();
+
+ List<DisambiguationReport<Property>> disambiguated = resourceManager.disambiguate(allMissing,
new IntExtractor<Property>() {
public int extract(Property object) {
PropertyMap map = (PropertyMap) object;
@@ -200,7 +208,7 @@ public class CliComponent implements ServerPluginComponent, ControlFacet {
PropertySimple userNameProp = parameters.getSimple(PROP_USER_NAME);
PropertySimple alertDefIdsProp = parameters.getSimple(PROP_ALERT_DEF_IDS);
- if (userNameProp == null) {
+ if (userNameProp == null || userNameProp.getStringValue() == null || userNameProp.getStringValue().trim().length() == 0) {
throw new IllegalArgumentException("User name not specified.");
}
@@ -214,16 +222,15 @@ public class CliComponent implements ServerPluginComponent, ControlFacet {
//now get the list of the alert notifications to update
List<AlertNotification> notifsToReAssign = null;
- if (alertDefIdsProp == null || alertDefIdsProp.getStringValue().trim().length() == 0) {
- notifsToReAssign = getAllCliNotificationsWithInvalidUser();
+ if (alertDefIdsProp == null || alertDefIdsProp.getStringValue() == null || alertDefIdsProp.getStringValue().trim().length() == 0) {
+ notifsToReAssign = getCliNotificationsWithInvalidUser(getAllCliNotifications(null));
} else {
List<Integer> alertDefIds = asIdList(alertDefIdsProp.getStringValue().split("\\s*,\\s*"));
List<AlertDefinition> defs = getAlertDefinitionsWithCliNotifications(alertDefIds);
notifsToReAssign = new ArrayList<AlertNotification>();
for(AlertDefinition def : defs) {
- AlertNotification cliNotif = getCliNotification(def.getAlertNotifications());
- if (cliNotif != null) {
+ for(AlertNotification cliNotif : getCliNotifications(def.getAlertNotifications())) {
notifsToReAssign.add(cliNotif);
}
}
@@ -236,17 +243,18 @@ public class CliComponent implements ServerPluginComponent, ControlFacet {
notificationManager.massReconfigure(notifIds, updates);
}
- private AlertNotification getCliNotification(List<AlertNotification> notifications) {
+ private List<AlertNotification> getCliNotifications(List<AlertNotification> notifications) {
+ ArrayList<AlertNotification> ret = new ArrayList<AlertNotification>();
for(AlertNotification n : notifications) {
if (pluginName.equals(n.getSenderName())) {
- return n;
+ ret.add(n);
}
}
- return null;
+ return ret;
}
- private List<AlertDefinition> getAlertDefinitionsWithCliNotifications(Collection<Integer> ids) {
+ private List<AlertDefinition> getAlertDefinitionsWithCliNotifications(Collection<Integer> alertDefIds) {
SubjectManagerLocal subjectManager = LookupUtil.getSubjectManager();
AlertDefinitionManagerLocal manager = LookupUtil.getAlertDefinitionManager();
@@ -256,29 +264,33 @@ public class CliComponent implements ServerPluginComponent, ControlFacet {
criteria.addFilterNotificationNames(pluginName);
criteria.setPageControl(PageControl.getUnlimitedInstance());
criteria.fetchAlertNotifications(true);
- if (ids != null) {
- criteria.addFilterIds(ids.toArray(new Integer[ids.size()]));
+ if (alertDefIds != null) {
+ criteria.addFilterIds(alertDefIds.toArray(new Integer[alertDefIds.size()]));
}
return manager.findAlertDefinitionsByCriteria(overlord, criteria);
}
- private List<AlertNotification> getAllCliNotificationsWithInvalidUser() {
+ private List<AlertNotification> getAllCliNotifications(Collection<Integer> alertDefIds) {
List<AlertNotification> ret = new ArrayList<AlertNotification>();
- SubjectManagerLocal subjectManager = LookupUtil.getSubjectManager();
-
- List<AlertDefinition> defs = getAlertDefinitionsWithCliNotifications(null);
+ List<AlertDefinition> defs = getAlertDefinitionsWithCliNotifications(alertDefIds);
for(AlertDefinition def : defs) {
List<AlertNotification> notifications = def.getAlertNotifications();
- AlertNotification cliNotification = getCliNotification(notifications);
-
- if (cliNotification == null) {
- //we always should find this but a little bit of paranoia never hurt anyone
- continue;
- }
+ ret.addAll(getCliNotifications(notifications));
+ }
+
+ return ret;
+ }
+
+ private List<AlertNotification> getCliNotificationsWithInvalidUser(List<AlertNotification> allNotifications) {
+ List<AlertNotification> ret = new ArrayList<AlertNotification>();
+
+ SubjectManagerLocal subjectManager = LookupUtil.getSubjectManager();
+
+ for(AlertNotification cliNotification : allNotifications) {
Subject checkSubject = null;
@@ -297,6 +309,59 @@ public class CliComponent implements ServerPluginComponent, ControlFacet {
return ret;
}
+ private List<AlertNotification> getCliNotificationsWithInvalidPackage(List<AlertNotification> allNotifications) {
+ List<AlertNotification> ret = new ArrayList<AlertNotification>();
+
+ ContentManagerLocal contentManager = LookupUtil.getContentManager();
+ SubjectManagerLocal subjectManager = LookupUtil.getSubjectManager();
+
+ Subject overlord = subjectManager.getOverlord();
+
+ PackageVersionCriteria crit = new PackageVersionCriteria();
+ crit.setRestriction(Restriction.COUNT_ONLY);
+
+ for(AlertNotification cliNotification : allNotifications) {
+
+ int count = 0;
+
+ String packageId = cliNotification.getConfiguration().getSimpleValue(CliSender.PROP_PACKAGE_ID, null);
+ if (packageId != null) {
+ crit.addFilterPackageId(Integer.valueOf(packageId));
+
+ PageList<PackageVersion> res = contentManager.findPackageVersionsByCriteria(overlord, crit);
+ count = res.getTotalSize();
+ }
+
+ if (count == 0) {
+ ret.add(cliNotification);
+ }
+ }
+
+ return ret;
+ }
+
+ private void convertNotificationsToInvalidAlertDefResults(PropertyList results, List<AlertNotification> invalidNotifications) {
+ Set<AlertDefinition> processedDefs = new HashSet<AlertDefinition>();
+
+ for(AlertNotification cliNotification : invalidNotifications) {
+ AlertDefinition def = cliNotification.getAlertDefinition();
+
+ if (!processedDefs.add(def)) {
+ //skip this definition - it has more than one incorrect notifs and we already
+ //included it in the output.
+ continue;
+ }
+
+ PropertyMap alertDefinitionMap = new PropertyMap(PROP_ALERT_DEFINITION);
+
+ alertDefinitionMap.put(new PropertySimple(PROP_ALERT_DEFINITION_ID, def.getId()));
+ alertDefinitionMap.put(new PropertySimple(PROP_ALERT_DEFINITION_NAME, def.getName()));
+ alertDefinitionMap.put(new PropertySimple(PROP_RESOURCE_ID, def.getResource().getId()));
+
+ results.add(alertDefinitionMap);
+ }
+ }
+
private List<Integer> asIdList(String... ids) {
List<Integer> ret = new ArrayList<Integer>();
for(String id : ids) {
diff --git a/modules/enterprise/server/plugins/alert-cli/src/main/resources/META-INF/rhq-serverplugin.xml b/modules/enterprise/server/plugins/alert-cli/src/main/resources/META-INF/rhq-serverplugin.xml
index 4f60e6f..c4dcdea 100644
--- a/modules/enterprise/server/plugins/alert-cli/src/main/resources/META-INF/rhq-serverplugin.xml
+++ b/modules/enterprise/server/plugins/alert-cli/src/main/resources/META-INF/rhq-serverplugin.xml
@@ -15,14 +15,18 @@
</serverplugin:help>
<serverplugin:plugin-component class="CliComponent">
- <serverplugin:control name="checkAlertsValidity">
+ <serverplugin:control name="checkAlertsValidity" description="Alert scripts run authenticated as a user specified in their definitions. If a user is deleted, the alert definition will contain invalid reference to that user and needs to be update manually. Also the script can be deleted from a repo, or the repo itself can be deleted, at which point there is not script to run. This operation returns a list of such misconfigured alert definitions.">
<serverplugin:results>
- <c:list-property name="misconfiguredAlertDefs" displayName="Misconfigured Alert Definitions">
- <c:description>
- Alert scripts run authenticated as a user specified in their definitions. If a user is deleted,
- the alert definition will contain invalid reference to that user and needs to be update manually.
- This operation returns a list of such misconfigured alert definitions.
- </c:description>
+ <c:list-property name="missingUsers" displayName="Alerts with notifications referencing non-existent user.">
+ <c:map-property name="alertDefinition">
+ <c:simple-property name="alertDefinitionId" />
+ <c:simple-property name="alertDefinitionName" />
+ <c:simple-property name="resourceId" />
+ <c:simple-property name="resourcePath" />
+ </c:map-property>
+ </c:list-property>
+
+ <c:list-property name="missingScripts" displayName="Alerts with notifications referencing non-existent scripts.">
<c:map-property name="alertDefinition">
<c:simple-property name="alertDefinitionId" />
<c:simple-property name="alertDefinitionName" />
commit 86c740a3822f79167facb90b64d85d5667cb52db
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Fri Feb 25 13:32:34 2011 +0100
Deleting a user will cause all the repos s/he owned to have no owner and thus become readonly to anyone except repository managers. Deleting a user will therefore not cause disappearance of any packages s/he previously created and that might be used throughout the inventory as backing content for resources or as CLI scripts.
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/content/Repo.java b/modules/core/domain/src/main/java/org/rhq/core/domain/content/Repo.java
index c1014e2..ecf97ce 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/content/Repo.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/content/Repo.java
@@ -126,7 +126,9 @@ import org.rhq.core.domain.resource.Resource;
@NamedQuery(name = Repo.QUERY_CHECK_REPO_OWNED_BY_SUBJECT_ID, query = "SELECT COUNT(r) FROM Repo r" //
+ " WHERE r.id = :repoId"
- + " AND r.owner.id = :subjectId")
+ + " AND r.owner.id = :subjectId"),
+ @NamedQuery(name = Repo.QUERY_UPDATE_REMOVE_OWNER_FROM_REPOS_OWNED_BY_SUBJECT, query = "" +
+ "UPDATE Repo r SET r.owner = null WHERE r.owner.id = :ownerId")
})
@SequenceGenerator(name = "SEQ", sequenceName = "RHQ_REPO_ID_SEQ")
@Table(name = "RHQ_REPO")
@@ -152,6 +154,7 @@ public class Repo implements Serializable {
public static final String QUERY_FIND_CANDIDATES_WITH_ONLY_CONTENT_SOURCE = "Repo.findCandidatesWithOnlyContentSource";
public static final String QUERY_CHECK_REPO_VISIBLE_BY_SUBJECT_ID = "Repo.findVisibleReposBySubjectId";
public static final String QUERY_CHECK_REPO_OWNED_BY_SUBJECT_ID = "Repo.isRepoOwnedBySubjectId";
+ public static final String QUERY_UPDATE_REMOVE_OWNER_FROM_REPOS_OWNED_BY_SUBJECT = "Repo.removeOwnerFromReposOwnerBySubject";
private static final long serialVersionUID = 1L;
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/auth/SubjectManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/auth/SubjectManagerBean.java
index b3a25c9..3c5cc9e 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/auth/SubjectManagerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/auth/SubjectManagerBean.java
@@ -61,6 +61,7 @@ import org.rhq.enterprise.server.authz.AuthorizationManagerLocal;
import org.rhq.enterprise.server.authz.PermissionException;
import org.rhq.enterprise.server.authz.RequiredPermission;
import org.rhq.enterprise.server.authz.RoleManagerLocal;
+import org.rhq.enterprise.server.content.RepoManagerLocal;
import org.rhq.enterprise.server.core.CustomJaasDeploymentServiceMBean;
import org.rhq.enterprise.server.exception.LoginException;
import org.rhq.enterprise.server.resource.group.LdapGroupManagerLocal;
@@ -103,6 +104,10 @@ public class SubjectManagerBean implements SubjectManagerLocal, SubjectManagerRe
@IgnoreDependency
private RoleManagerLocal roleManager;
+ @EJB
+ @IgnoreDependency
+ private RepoManagerLocal repoManager;
+
private SessionManager sessionManager = SessionManager.getInstance();
/**
@@ -754,6 +759,8 @@ public class SubjectManagerBean implements SubjectManagerLocal, SubjectManagerRe
}
alertNotificationManager.cleanseAlertNotificationBySubject(doomedSubject.getId());
+ repoManager.removeOwnershipOfSubject(doomedSubject.getId());
+
entityManager.remove(doomedSubject);
return;
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/RepoManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/RepoManagerBean.java
index 9dbf92b..6eadde8 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/RepoManagerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/RepoManagerBean.java
@@ -694,6 +694,13 @@ public class RepoManagerBean implements RepoManagerLocal, RepoManagerRemote {
}
}
+ public void removeOwnershipOfSubject(int subjectId) {
+ Query q = entityManager.createNamedQuery(Repo.QUERY_UPDATE_REMOVE_OWNER_FROM_REPOS_OWNED_BY_SUBJECT);
+ q.setParameter("ownerId", subjectId);
+
+ q.executeUpdate();
+ }
+
@RequiredPermission(Permission.MANAGE_REPOSITORIES)
public RepoGroup createRepoGroup(Subject subject, RepoGroup repoGroup) throws RepoException {
validateRepoGroup(repoGroup);
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/RepoManagerLocal.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/RepoManagerLocal.java
index 99ab618..bc22d81 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/RepoManagerLocal.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/RepoManagerLocal.java
@@ -210,6 +210,17 @@ public interface RepoManagerLocal {
*/
void importCandidateRepo(Subject subject, List<Integer> repoIds) throws RepoException;
+ /**
+ * When a user gets deleted, all of his/her repos remain intact but become
+ * unassigned to any user. This way no links to packages are broken upon user deletion
+ * and repository manager can then decide what to do with the leftover repos.
+ * <p>
+ * This method therefore sets the owner of all repos owned by provided subject to null.
+ *
+ * @param subjectId
+ */
+ void removeOwnershipOfSubject(int subjectId);
+
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
//
// The following are shared with the Remote Interface
commit 49d947b89a34847fa71b16124600ff0ddd511a64
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Tue Feb 22 23:46:40 2011 +0100
fail the validation if another user is entered with incorrect credentials.
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/CliNotificationSenderForm.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/CliNotificationSenderForm.java
index 61b3f3d..69a2a65 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/CliNotificationSenderForm.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/CliNotificationSenderForm.java
@@ -593,7 +593,11 @@ public class CliNotificationSenderForm extends AbstractNotificationSenderForm {
config.selectedSubject = result;
verifyUserButton.setIcons(result == null ? authFailureIcon : authSuccessIcon);
markForRedraw();
- action.onSuccess(null);
+ if (result == null) {
+ action.onFailure(null);
+ } else {
+ action.onSuccess(null);
+ }
}
});
}
commit f573b869314155dc482e7eb12d5cd5b689347dbd
Merge: d15f758... cd5f842...
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Tue Feb 22 23:36:00 2011 +0100
Merge remote branch 'origin/master' into cli-alert-notifs
commit d15f758d0a5a4d4f1543c09a4e53d1d127ec676e
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Tue Feb 22 23:35:25 2011 +0100
CLI alert sender fixes:
* fake login to actually be able to perform stuff as the associated user
* correctly capturing script output
* caching up to 10 script engines and reusing them to speed up the execution.
diff --git a/modules/enterprise/server/plugins/alert-cli/src/main/java/org/rhq/enterprise/server/plugins/alertCli/CliSender.java b/modules/enterprise/server/plugins/alert-cli/src/main/java/org/rhq/enterprise/server/plugins/alertCli/CliSender.java
index 1e78f8d..a9ee867 100644
--- a/modules/enterprise/server/plugins/alert-cli/src/main/java/org/rhq/enterprise/server/plugins/alertCli/CliSender.java
+++ b/modules/enterprise/server/plugins/alert-cli/src/main/java/org/rhq/enterprise/server/plugins/alertCli/CliSender.java
@@ -30,8 +30,14 @@ import java.io.PipedInputStream;
import java.io.PipedOutputStream;
import java.io.PrintWriter;
import java.nio.charset.Charset;
+import java.util.ArrayDeque;
import java.util.Collections;
+import java.util.LinkedList;
import java.util.List;
+import java.util.Queue;
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.concurrent.atomic.AtomicInteger;
import javax.script.ScriptEngine;
import javax.script.ScriptException;
@@ -54,6 +60,7 @@ import org.rhq.core.domain.content.Repo;
import org.rhq.core.domain.criteria.RepoCriteria;
import org.rhq.core.util.exception.ThrowableUtil;
import org.rhq.enterprise.client.LocalClient;
+import org.rhq.enterprise.server.auth.SessionManager;
import org.rhq.enterprise.server.auth.SubjectManagerLocal;
import org.rhq.enterprise.server.content.ContentSourceManagerLocal;
import org.rhq.enterprise.server.content.RepoManagerLocal;
@@ -82,6 +89,12 @@ public class CliSender extends AlertSender<CliComponent> {
private static final String VALIDATION_ERROR_MESSAGE = "The provided user failed to authenticate.";
+ //no more than 10 concurrently running CLI notifications..
+ //is that enough?
+ private static final int MAX_SCRIPT_ENGINES = 10;
+ private static Queue<ScriptEngine> SCRIPT_ENGINES = new ArrayDeque<ScriptEngine>(MAX_SCRIPT_ENGINES);
+ private static int ENGINES_IN_USE = 0;
+
/**
* Simple strongly typed representation of the alert configuration
*/
@@ -98,13 +111,16 @@ public class CliSender extends AlertSender<CliComponent> {
public SenderResult send(Alert alert) {
SenderResult result = new SenderResult();
BufferedReader reader = null;
+ ScriptEngine engine = null;
try {
- Config config = getConfig();
+ final Config config = getConfig();
+
result.setSummary(createSummary(config, SUMMARY_TEMPLATE));
ByteArrayOutputStream scriptOutputStream = new ByteArrayOutputStream();
+ PrintWriter scriptOut = new PrintWriter(scriptOutputStream);
- ScriptEngine engine = getScriptEngine(alert, scriptOutputStream, config);
+ engine = getScriptEngine(alert, scriptOut, config);
final SandboxedScriptEngine sandbox = new SandboxedScriptEngine(engine, new StandardScriptPermissions());
@@ -119,7 +135,10 @@ public class CliSender extends AlertSender<CliComponent> {
Thread scriptRunner = new Thread(new Runnable() {
public void run() {
try {
+ //fake the login
+ SessionManager.getInstance().put(config.subject, pluginComponent.getScriptTimeout() * 1000);
sandbox.eval(rdr);
+ SessionManager.getInstance().invalidate(config.subject.getSessionId());
} catch (ScriptException e) {
exceptionHolder.throwable = e;
}
@@ -140,6 +159,7 @@ public class CliSender extends AlertSender<CliComponent> {
throw new Exception("Script failed with an exception.", exceptionHolder.throwable);
}
+ scriptOut.flush();
String scriptOutput = scriptOutputStream.toString(Charset.defaultCharset().name());
if (scriptOutput.length() == 0) {
@@ -155,6 +175,10 @@ public class CliSender extends AlertSender<CliComponent> {
result.addFailureMessage(ThrowableUtil.getAllMessages(e));
return result;
} finally {
+ if (engine != null) {
+ returnEngine(engine);
+ }
+
if (reader != null) {
try {
reader.close();
@@ -213,18 +237,18 @@ public class CliSender extends AlertSender<CliComponent> {
return results;
}
- private static ScriptEngine getScriptEngine(Alert alert, OutputStream scriptOutput, Config config) throws ScriptException,
- IOException {
+ private static ScriptEngine getScriptEngine(Alert alert, PrintWriter output, Config config) throws ScriptException,
+ IOException, InterruptedException {
Subject user = config.subject;
LocalClient client = new LocalClient(user);
- PrintWriter output = new PrintWriter(scriptOutput);
StandardBindings bindings = new StandardBindings(output, client);
bindings.put("alert", alert);
- return ScriptEngineFactory.getScriptEngine("JavaScript", new PackageFinder(Collections.<File> emptyList()),
- bindings);
+ ScriptEngine engine = takeEngine(bindings);
+
+ return engine;
}
private static InputStream getPackageBits(int packageId, int repoId) throws IOException {
@@ -344,4 +368,34 @@ public class CliSender extends AlertSender<CliComponent> {
throw new IllegalArgumentException(convertErrorMessage + e.getMessage(), e);
}
}
+
+ private static ScriptEngine takeEngine(StandardBindings bindings) throws InterruptedException, ScriptException,
+ IOException {
+ synchronized (SCRIPT_ENGINES) {
+ if (ENGINES_IN_USE >= MAX_SCRIPT_ENGINES) {
+ SCRIPT_ENGINES.wait();
+ }
+
+ ScriptEngine engine = SCRIPT_ENGINES.poll();
+
+ if (engine == null) {
+ engine = ScriptEngineFactory.getScriptEngine("JavaScript",
+ new PackageFinder(Collections.<File> emptyList()), bindings);
+ } else {
+ ScriptEngineFactory.injectStandardBindings(engine, bindings);
+ }
+
+ ++ENGINES_IN_USE;
+
+ return engine;
+ }
+ }
+
+ private static void returnEngine(ScriptEngine engine) {
+ synchronized (SCRIPT_ENGINES) {
+ SCRIPT_ENGINES.offer(engine);
+ --ENGINES_IN_USE;
+ SCRIPT_ENGINES.notify();
+ }
+ }
}
commit 05e040a35e79c3334d5e8b444e319e06a38f2186
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Tue Feb 22 23:32:46 2011 +0100
Adding some more permissions to StandardScriptPermissions so that we block as little as possible while remaining reasonably safe.
diff --git a/modules/enterprise/binding/src/main/java/org/rhq/bindings/StandardScriptPermissions.java b/modules/enterprise/binding/src/main/java/org/rhq/bindings/StandardScriptPermissions.java
index 01f7222..894c953 100644
--- a/modules/enterprise/binding/src/main/java/org/rhq/bindings/StandardScriptPermissions.java
+++ b/modules/enterprise/binding/src/main/java/org/rhq/bindings/StandardScriptPermissions.java
@@ -28,6 +28,9 @@ import java.security.Permissions;
import java.util.Enumeration;
import java.util.PropertyPermission;
+import javax.management.MBeanPermission;
+import javax.management.ObjectName;
+
/**
* @author Lukas Krejci
*/
@@ -42,18 +45,27 @@ public class StandardScriptPermissions extends PermissionCollection {
* already added.
*/
public StandardScriptPermissions() {
- //the JBoss specific perms that must be set
+ //the JBoss specific perms that must be set
add(new RuntimePermission("org.jboss.security.SecurityAssociation.getPrincipalInfo"));
add(new RuntimePermission("org.jboss.security.SecurityAssociation.setPrincipalInfo "));
add(new RuntimePermission("org.jboss.security.SecurityAssociation.setServer"));
add(new RuntimePermission("org.jboss.security.SecurityAssociation.setRunAsRole"));
+ //MBean perms
+ add(new MBeanPermission("*", "*", ObjectName.WILDCARD, "*"));
+
//JVM defined runtime perms
+ add(new RuntimePermission("createClassLoader"));
+ add(new RuntimePermission("getClassLoader"));
+ add(new RuntimePermission("setContextClassLoader"));
add(new RuntimePermission("getenv.*"));
add(new RuntimePermission("getProtectionDomain"));
add(new RuntimePermission("getFileSystemAttributes"));
add(new RuntimePermission("readFileDescriptor"));
add(new RuntimePermission("writeFileDescriptor"));
+ add(new RuntimePermission("loadLibrary.*"));
+ add(new RuntimePermission("accessClassInPackage.*"));
+ add(new RuntimePermission("defineClassInPackage.*"));
add(new RuntimePermission("accessDeclaredMembers"));
add(new RuntimePermission("queuePrintJob"));
add(new RuntimePermission("getStackTrace"));
diff --git a/modules/enterprise/binding/src/main/java/org/rhq/bindings/engine/JsEngineInitializer.java b/modules/enterprise/binding/src/main/java/org/rhq/bindings/engine/JsEngineInitializer.java
index 30b79e1..eba36f3 100644
--- a/modules/enterprise/binding/src/main/java/org/rhq/bindings/engine/JsEngineInitializer.java
+++ b/modules/enterprise/binding/src/main/java/org/rhq/bindings/engine/JsEngineInitializer.java
@@ -21,6 +21,7 @@ package org.rhq.bindings.engine;
import java.lang.reflect.Method;
import java.util.List;
+import java.util.Set;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
@@ -37,7 +38,7 @@ public class JsEngineInitializer implements ScriptEngineInitializer {
return language != null && ("JavaScript".equals(language) || "ECMAScript".equals(language));
}
- public ScriptEngine instantiate(List<String> packages) throws ScriptException {
+ public ScriptEngine instantiate(Set<String> packages) throws ScriptException {
ScriptEngineManager sem = new ScriptEngineManager();
ScriptEngine eng = sem.getEngineByName("JavaScript");
diff --git a/modules/enterprise/binding/src/main/java/org/rhq/bindings/engine/ScriptEngineInitializer.java b/modules/enterprise/binding/src/main/java/org/rhq/bindings/engine/ScriptEngineInitializer.java
index d938589..fe99bf5 100644
--- a/modules/enterprise/binding/src/main/java/org/rhq/bindings/engine/ScriptEngineInitializer.java
+++ b/modules/enterprise/binding/src/main/java/org/rhq/bindings/engine/ScriptEngineInitializer.java
@@ -21,6 +21,7 @@ package org.rhq.bindings.engine;
import java.lang.reflect.Method;
import java.util.List;
+import java.util.Set;
import javax.script.ScriptEngine;
import javax.script.ScriptException;
@@ -35,7 +36,7 @@ public interface ScriptEngineInitializer {
boolean implementsLanguage(String language);
- ScriptEngine instantiate(List<String> packages) throws ScriptException;
+ ScriptEngine instantiate(Set<String> packages) throws ScriptException;
/**
* This function returns a definition string in the script engine's language
diff --git a/modules/enterprise/binding/src/main/java/org/rhq/bindings/util/PackageFinder.java b/modules/enterprise/binding/src/main/java/org/rhq/bindings/util/PackageFinder.java
index d1ba40c..bbc611a 100644
--- a/modules/enterprise/binding/src/main/java/org/rhq/bindings/util/PackageFinder.java
+++ b/modules/enterprise/binding/src/main/java/org/rhq/bindings/util/PackageFinder.java
@@ -43,8 +43,8 @@ public class PackageFinder {
this.jarLocations = new ArrayList<File>(jarLocations);
}
- public List<String> findPackages(String packageRoot) throws IOException {
- ArrayList<String> found = new ArrayList<String>();
+ public Set<String> findPackages(String packageRoot) throws IOException {
+ HashSet<String> found = new HashSet<String>();
List<File> jars = new ArrayList<File>();
@@ -58,16 +58,21 @@ public class PackageFinder {
}
}
- jars.addAll(loadJARsFromClassPath(packageRoot));
+ jars.addAll(loadResourcesFromClassPath(packageRoot, "jar:file:"));
for (File jar : jars) {
- findPackages(packageRoot, found, jar);
+ findPackagesInJar(packageRoot, found, jar);
}
+ List<File> dirs = loadResourcesFromClassPath(packageRoot, "file:");
+ for(File d : dirs) {
+ findPackagesInDirectory(packageRoot, found, d);
+ }
+
return found;
}
- private List<File> loadJARsFromClassPath(String pkgRoot) throws IOException {
+ private List<File> loadResourcesFromClassPath(String pkgRoot, String prefix) throws IOException {
List<File> jarFiles = new ArrayList<File>();
String pkgPath = pkgRoot.replaceAll("\\.", "/");
Enumeration<URL> resources = getClass().getClassLoader().getResources(pkgPath);
@@ -75,8 +80,8 @@ public class PackageFinder {
while (resources.hasMoreElements()) {
resource = resources.nextElement();
- if (resource.toString().startsWith("jar:file")) {
- String jarFilePath = getJARFilePath(resource);
+ if (resource.toString().startsWith(prefix)) {
+ String jarFilePath = getFilePath(resource, prefix);
jarFiles.add(new File(jarFilePath));
}
}
@@ -84,15 +89,17 @@ public class PackageFinder {
return jarFiles;
}
- private String getJARFilePath(URL resource) {
- int startIndex = "jar:file:".length();
+ private String getFilePath(URL resource, String prefix) {
+ int startIndex = prefix.length();
String string = resource.toString().substring(startIndex);
int endIndex = string.indexOf("!");
-
+ if (endIndex < 0) {
+ endIndex = string.length();
+ }
return string.substring(0, endIndex);
}
- private void findPackages(String packageRoot, List<String> list, File jar) throws IOException {
+ private void findPackagesInJar(String packageRoot, Set<String> list, File jar) throws IOException {
Set<String> paths = new HashSet<String>();
JarFile jf = null;
@@ -122,4 +129,16 @@ public class PackageFinder {
}
}
}
+
+ private void findPackagesInDirectory(String packageRoot, Set<String> list, File dir) throws IOException {
+ File[] subDirs = dir.listFiles();
+
+ for(File s : subDirs) {
+ if (s.isDirectory()) {
+ String packageName = packageRoot + "." + s.getName();
+ list.add(packageName);
+ findPackagesInDirectory(packageName, list, s);
+ }
+ }
+ }
}
commit 840778353bb55b722af9e03383490038edf784b3
Merge: 744faae... e800871...
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Tue Feb 22 14:51:54 2011 +0100
Merge remote branch 'origin/master' into cli-alert-notifs
diff --cc modules/enterprise/remoting/cli/pom.xml
index b9ebd59,f5d54f0..1c5207c
--- a/modules/enterprise/remoting/cli/pom.xml
+++ b/modules/enterprise/remoting/cli/pom.xml
@@@ -31,15 -31,9 +31,15 @@@
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>rhq-remoting-client-api</artifactId>
- <version>${project.version}</version>
+ <version>${project.version}</version>
</dependency>
-
+
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>rhq-script-bindings</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
<dependency>
<groupId>${groupId}</groupId>
<artifactId>rhq-core-domain</artifactId>
diff --cc modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertDefinitionManagerBean.java
index d410486,af9f18a..84e6b8a
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertDefinitionManagerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertDefinitionManagerBean.java
@@@ -596,8 -592,13 +597,13 @@@ public class AlertDefinitionManagerBea
}
}
- private void checkAlertDefinition(AlertDefinition alertDefinition, Integer resourceId)
+ private void checkAlertDefinition(Subject subject, AlertDefinition alertDefinition, Integer resourceId)
throws InvalidAlertDefinitionException {
+ // if someone enters a really long description, we need to truncate it - the column is only 250 chars
+ if (alertDefinition.getDescription().length() > 250) {
+ alertDefinition.setDescription(alertDefinition.getDescription().substring(0, 250));
+ }
+
for (AlertCondition alertCondition : alertDefinition.getConditions()) {
AlertConditionCategory alertConditionCategory = alertCondition.getCategory();
if (alertConditionCategory == AlertConditionCategory.ALERT) {
commit 744faaecff1b774afe1c223377909dbdb09953ed
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Tue Feb 22 13:06:24 2011 +0100
moving about some tests.
diff --git a/modules/enterprise/binding/src/test/java/org/rhq/bindings/ScriptEngineTest.java b/modules/enterprise/binding/src/test/java/org/rhq/bindings/ScriptEngineTest.java
index 8dd0844..69874e4 100644
--- a/modules/enterprise/binding/src/test/java/org/rhq/bindings/ScriptEngineTest.java
+++ b/modules/enterprise/binding/src/test/java/org/rhq/bindings/ScriptEngineTest.java
@@ -25,9 +25,9 @@ import static org.testng.Assert.assertTrue;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
-import java.lang.reflect.Array;
import java.util.Collections;
+import javax.script.ScriptContext;
import javax.script.ScriptEngine;
import javax.script.ScriptException;
@@ -76,6 +76,16 @@ public class ScriptEngineTest {
}
}
+ @Test
+ public void testStandardBindings() throws ScriptException, IOException {
+ ScriptEngine scriptEngine = getScriptEngine();
+
+ for(String var : EMPTY_BINDINGS.keySet()) {
+ boolean hasVar = scriptEngine.getBindings(ScriptContext.ENGINE_SCOPE).containsKey(var);
+ assertTrue(hasVar, "The variable '" + var + "' is not present in the script context but should be.");
+ }
+ }
+
private ScriptEngine getScriptEngine() throws ScriptException, IOException {
return ScriptEngineFactory.getScriptEngine("JavaScript", new PackageFinder(Collections.<File>emptyList()), EMPTY_BINDINGS);
}
diff --git a/modules/enterprise/binding/src/test/java/org/rhq/bindings/util/ScriptAssertTest.java b/modules/enterprise/binding/src/test/java/org/rhq/bindings/util/ScriptAssertTest.java
new file mode 100644
index 0000000..cfd06b5
--- /dev/null
+++ b/modules/enterprise/binding/src/test/java/org/rhq/bindings/util/ScriptAssertTest.java
@@ -0,0 +1,92 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2008 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.bindings.util;
+
+import static org.testng.Assert.*;
+
+import org.testng.annotations.Test;
+import org.testng.annotations.BeforeClass;
+
+import org.rhq.bindings.util.ScriptAssert;
+
+import javax.script.ScriptEngine;
+import javax.script.ScriptEngineManager;
+
+public class ScriptAssertTest {
+
+ @Test
+ public void dummyTest() {
+ // Dummy test while the other tests are disabled
+ }
+
+ // @BeforeClass
+ public void verifyScriptEngineIsAvailable() {
+ assertNotNull(createScriptEngine(), "ScriptEngine is not available. Are the required libraries on the classpath?");
+ }
+
+ // @Test
+ public void assertExistsShouldReturnTrueWhenVariableIsBound() {
+ ScriptEngine scriptEngine = createScriptEngine();
+ scriptEngine.put("foo", "bar");
+
+ ScriptAssert scriptAssert = new ScriptAssert(scriptEngine);
+
+ try {
+ scriptAssert.assertExists("foo");
+ assert true;
+ } catch (AssertionError ae) {
+ assert false : "Expected isDefined() to return true when the variable is bound.";
+ }
+ }
+
+ // @Test(expectedExceptions={ScriptAssertionException.class})
+ public void assertExistsShouldReturnFalseWhenVariableIsNotBound() {
+ ScriptEngine scriptEngine = createScriptEngine();
+
+ ScriptAssert scriptAssert = new ScriptAssert(scriptEngine);
+
+ scriptAssert.assertExists("foo");
+ }
+
+ // @Test
+ public void assertExistsShouldReturnTrueWhenFunctionIsBound() {
+ ScriptEngine scriptEngine = createScriptEngine();
+ scriptEngine.put("func", "function func() { return 123; }");
+
+ ScriptAssert scriptAssert = new ScriptAssert(scriptEngine);
+
+ try {
+ scriptAssert.assertExists("func");
+ assert true;
+ } catch (AssertionError ae) {
+ assert false : "Expected isDefined() to return true when function is bound.";
+ }
+ }
+
+ ScriptEngine createScriptEngine() {
+ ScriptEngineManager scriptEngineMgr = new ScriptEngineManager();
+ return scriptEngineMgr.getEngineByName("JavaScript");
+ }
+
+}
diff --git a/modules/enterprise/binding/src/test/java/org/rhq/bindings/util/ScriptUtilTest.java b/modules/enterprise/binding/src/test/java/org/rhq/bindings/util/ScriptUtilTest.java
new file mode 100644
index 0000000..a633148
--- /dev/null
+++ b/modules/enterprise/binding/src/test/java/org/rhq/bindings/util/ScriptUtilTest.java
@@ -0,0 +1,40 @@
+package org.rhq.bindings.util;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+import javax.script.ScriptEngine;
+import javax.script.ScriptEngineManager;
+
+import org.testng.annotations.Test;
+
+import org.rhq.bindings.util.ScriptUtil;
+
+public class ScriptUtilTest {
+
+ @Test
+ public void getFileBytes() {
+ ScriptUtil scriptUtil = new ScriptUtil(null);
+
+ try {
+ String fileContents = "the rain in spain falls mainly on the plain";
+ String tempDir = System.getProperty("java.io.tmpdir");
+ File testFile = new File(tempDir, "getFileBytesTest.txt");
+ byte[] contentBytes = fileContents.getBytes();
+ FileOutputStream writer = new FileOutputStream(testFile);
+ writer.write(contentBytes);
+ writer.close();
+ System.out.println("Test data written to " + testFile.getAbsolutePath());
+
+ byte[] fileBytes = scriptUtil.getFileBytes(testFile.getAbsolutePath());
+ String results = new String(fileBytes);
+
+ System.out.println("Wrote: \"" + fileContents + "\"\nRead: \"" + results + "\"");
+ assert fileContents.equals(results) : "Wrote: \"" + fileContents + "\"\nRead: \"" + results + "\"";
+ } catch (IOException ioe) {
+ assert false : "Failure testing getFileBytes: " + ioe.getMessage();
+ }
+ }
+
+}
diff --git a/modules/enterprise/binding/src/test/java/org/rhq/bindings/util/SummaryFilterTest.java b/modules/enterprise/binding/src/test/java/org/rhq/bindings/util/SummaryFilterTest.java
new file mode 100644
index 0000000..3d6af43
--- /dev/null
+++ b/modules/enterprise/binding/src/test/java/org/rhq/bindings/util/SummaryFilterTest.java
@@ -0,0 +1,103 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2008 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.bindings.util;
+
+import static org.testng.Assert.*;
+
+import org.testng.annotations.Test;
+
+import org.rhq.bindings.util.SummaryFilter;
+import org.rhq.core.domain.util.Summary;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import java.beans.PropertyDescriptor;
+import java.beans.BeanInfo;
+import java.beans.Introspector;
+
+public class SummaryFilterTest {
+
+ @Test
+ public void testFilterAndReturnOrder() throws Exception {
+ SummaryFilter filter = new SummaryFilter();
+ PropertyDescriptor[] properties = filter.getPropertyDescriptors(new TestEntity(),false);
+
+ assert (properties.length == 2);
+ assert (properties[0].getName().equals("id"));
+ assert (properties[1].getName().equals("summaryField"));
+
+
+ }
+
+ PropertyDescriptor getPropertyDescriptor(String name) throws Exception {
+ BeanInfo beanInfo = Introspector.getBeanInfo(TestEntity.class);
+ for (PropertyDescriptor descriptor : beanInfo.getPropertyDescriptors()) {
+ if (descriptor.getName().equals(name)) {
+ return descriptor;
+ }
+ }
+ return null;
+ }
+
+ @Entity
+ static class TestEntity {
+ @Id
+ @Summary(index=1)
+ private int id;
+
+ @Summary(index=2)
+ private String summaryField;
+
+ private String nonSummaryField;
+
+ public int getId() {
+ return id;
+ }
+
+ public void setId(int id) {
+ this.id = id;
+ }
+
+ public String getSummaryField() {
+ return summaryField;
+ }
+
+ public void setSummaryField(String summaryField) {
+ this.summaryField = summaryField;
+ }
+
+ public String getNonSummaryField() {
+ return nonSummaryField;
+ }
+
+ public void setNonSummaryField(String nonSummaryField) {
+ this.nonSummaryField = nonSummaryField;
+ }
+
+ public String getNonField() {
+ return null;
+ }
+ }
+
+}
diff --git a/modules/enterprise/remoting/cli/src/test/java/org/rhq/enterprise/client/SummaryFilterTest.java b/modules/enterprise/remoting/cli/src/test/java/org/rhq/enterprise/client/SummaryFilterTest.java
deleted file mode 100644
index a2abec5..0000000
--- a/modules/enterprise/remoting/cli/src/test/java/org/rhq/enterprise/client/SummaryFilterTest.java
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * RHQ Management Platform
- * Copyright (C) 2005-2008 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.client;
-
-import static org.testng.Assert.*;
-
-import org.testng.annotations.Test;
-
-import org.rhq.bindings.util.SummaryFilter;
-import org.rhq.core.domain.util.Summary;
-
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import java.beans.PropertyDescriptor;
-import java.beans.BeanInfo;
-import java.beans.Introspector;
-
-public class SummaryFilterTest {
-
- @Test
- public void testFilterAndReturnOrder() throws Exception {
- SummaryFilter filter = new SummaryFilter();
- PropertyDescriptor[] properties = filter.getPropertyDescriptors(new TestEntity(),false);
-
- assert (properties.length == 2);
- assert (properties[0].getName().equals("id"));
- assert (properties[1].getName().equals("summaryField"));
-
-
- }
-
- PropertyDescriptor getPropertyDescriptor(String name) throws Exception {
- BeanInfo beanInfo = Introspector.getBeanInfo(TestEntity.class);
- for (PropertyDescriptor descriptor : beanInfo.getPropertyDescriptors()) {
- if (descriptor.getName().equals(name)) {
- return descriptor;
- }
- }
- return null;
- }
-
- @Entity
- static class TestEntity {
- @Id
- @Summary(index=1)
- private int id;
-
- @Summary(index=2)
- private String summaryField;
-
- private String nonSummaryField;
-
- public int getId() {
- return id;
- }
-
- public void setId(int id) {
- this.id = id;
- }
-
- public String getSummaryField() {
- return summaryField;
- }
-
- public void setSummaryField(String summaryField) {
- this.summaryField = summaryField;
- }
-
- public String getNonSummaryField() {
- return nonSummaryField;
- }
-
- public void setNonSummaryField(String nonSummaryField) {
- this.nonSummaryField = nonSummaryField;
- }
-
- public String getNonField() {
- return null;
- }
- }
-
-}
diff --git a/modules/enterprise/remoting/cli/src/test/java/org/rhq/enterprise/client/commands/ScriptCommandTest.java b/modules/enterprise/remoting/cli/src/test/java/org/rhq/enterprise/client/commands/ScriptCommandTest.java
index b795848..815629d 100644
--- a/modules/enterprise/remoting/cli/src/test/java/org/rhq/enterprise/client/commands/ScriptCommandTest.java
+++ b/modules/enterprise/remoting/cli/src/test/java/org/rhq/enterprise/client/commands/ScriptCommandTest.java
@@ -12,6 +12,7 @@ import java.util.ArrayList;
import org.testng.annotations.Test;
import org.rhq.enterprise.client.ClientMain;
import org.rhq.enterprise.client.RemoteClient;
+import org.rhq.enterprise.client.commands.ScriptCommand;
import org.rhq.enterprise.server.alert.AlertManagerRemote;
import org.rhq.enterprise.server.alert.AlertDefinitionManagerRemote;
import org.rhq.enterprise.server.configuration.ConfigurationManagerRemote;
@@ -61,7 +62,7 @@ public class ScriptCommandTest {
void assertSubjectBoundToScript() {
ScriptEngine scriptEngine = cmd.getScriptEngine();
- Object subject = scriptEngine.getBindings(ScriptContext.GLOBAL_SCOPE).get("subject");
+ Object subject = scriptEngine.getBindings(ScriptContext.ENGINE_SCOPE).get("subject");
assertNotNull(subject, "Expected variable 'subject' to be bound to script in global scope");
assertTrue(
@@ -75,7 +76,7 @@ public class ScriptCommandTest {
List<String> mgrsNotBound = new ArrayList<String>();
for (RhqManagers mgr : RhqManagers.values()) {
- if (!scriptEngine.getBindings(ScriptContext.GLOBAL_SCOPE).containsKey(mgr.name())) {
+ if (!scriptEngine.getBindings(ScriptContext.ENGINE_SCOPE).containsKey(mgr.name())) {
mgrsNotBound.add(mgr.remoteName());
}
}
@@ -88,7 +89,7 @@ public class ScriptCommandTest {
void assertPrettyWriterBoundToScript() {
ScriptEngine scriptEngine = cmd.getScriptEngine();
- Object writer = scriptEngine.getBindings(ScriptContext.GLOBAL_SCOPE).get("pretty");
+ Object writer = scriptEngine.getBindings(ScriptContext.ENGINE_SCOPE).get("pretty");
assertNotNull(writer, "Expected variable 'pretty' to be bound to script in global scope");
assertTrue(
diff --git a/modules/enterprise/remoting/cli/src/test/java/org/rhq/enterprise/client/utility/ScriptAssertTest.java b/modules/enterprise/remoting/cli/src/test/java/org/rhq/enterprise/client/utility/ScriptAssertTest.java
deleted file mode 100644
index 10f8fa7..0000000
--- a/modules/enterprise/remoting/cli/src/test/java/org/rhq/enterprise/client/utility/ScriptAssertTest.java
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * RHQ Management Platform
- * Copyright (C) 2005-2008 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.client.utility;
-
-import static org.testng.Assert.*;
-
-import org.testng.annotations.Test;
-import org.testng.annotations.BeforeClass;
-
-import org.rhq.bindings.util.ScriptAssert;
-
-import javax.script.ScriptEngine;
-import javax.script.ScriptEngineManager;
-
-public class ScriptAssertTest {
-
- @Test
- public void dummyTest() {
- // Dummy test while the other tests are disabled
- }
-
- // @BeforeClass
- public void verifyScriptEngineIsAvailable() {
- assertNotNull(createScriptEngine(), "ScriptEngine is not available. Are the required libraries on the classpath?");
- }
-
- // @Test
- public void assertExistsShouldReturnTrueWhenVariableIsBound() {
- ScriptEngine scriptEngine = createScriptEngine();
- scriptEngine.put("foo", "bar");
-
- ScriptAssert scriptAssert = new ScriptAssert(scriptEngine);
-
- try {
- scriptAssert.assertExists("foo");
- assert true;
- } catch (AssertionError ae) {
- assert false : "Expected isDefined() to return true when the variable is bound.";
- }
- }
-
- // @Test(expectedExceptions={ScriptAssertionException.class})
- public void assertExistsShouldReturnFalseWhenVariableIsNotBound() {
- ScriptEngine scriptEngine = createScriptEngine();
-
- ScriptAssert scriptAssert = new ScriptAssert(scriptEngine);
-
- scriptAssert.assertExists("foo");
- }
-
- // @Test
- public void assertExistsShouldReturnTrueWhenFunctionIsBound() {
- ScriptEngine scriptEngine = createScriptEngine();
- scriptEngine.put("func", "function func() { return 123; }");
-
- ScriptAssert scriptAssert = new ScriptAssert(scriptEngine);
-
- try {
- scriptAssert.assertExists("func");
- assert true;
- } catch (AssertionError ae) {
- assert false : "Expected isDefined() to return true when function is bound.";
- }
- }
-
- ScriptEngine createScriptEngine() {
- ScriptEngineManager scriptEngineMgr = new ScriptEngineManager();
- return scriptEngineMgr.getEngineByName("JavaScript");
- }
-
-}
diff --git a/modules/enterprise/remoting/cli/src/test/java/org/rhq/enterprise/client/utility/ScriptUtilTest.java b/modules/enterprise/remoting/cli/src/test/java/org/rhq/enterprise/client/utility/ScriptUtilTest.java
deleted file mode 100644
index 7a88720..0000000
--- a/modules/enterprise/remoting/cli/src/test/java/org/rhq/enterprise/client/utility/ScriptUtilTest.java
+++ /dev/null
@@ -1,40 +0,0 @@
-package org.rhq.enterprise.client.utility;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-
-import javax.script.ScriptEngine;
-import javax.script.ScriptEngineManager;
-
-import org.testng.annotations.Test;
-
-import org.rhq.bindings.util.ScriptUtil;
-
-public class ScriptUtilTest {
-
- @Test
- public void getFileBytes() {
- ScriptUtil scriptUtil = new ScriptUtil(null);
-
- try {
- String fileContents = "the rain in spain falls mainly on the plain";
- String tempDir = System.getProperty("java.io.tmpdir");
- File testFile = new File(tempDir, "getFileBytesTest.txt");
- byte[] contentBytes = fileContents.getBytes();
- FileOutputStream writer = new FileOutputStream(testFile);
- writer.write(contentBytes);
- writer.close();
- System.out.println("Test data written to " + testFile.getAbsolutePath());
-
- byte[] fileBytes = scriptUtil.getFileBytes(testFile.getAbsolutePath());
- String results = new String(fileBytes);
-
- System.out.println("Wrote: \"" + fileContents + "\"\nRead: \"" + results + "\"");
- assert fileContents.equals(results) : "Wrote: \"" + fileContents + "\"\nRead: \"" + results + "\"";
- } catch (IOException ioe) {
- assert false : "Failure testing getFileBytes: " + ioe.getMessage();
- }
- }
-
-}
commit 8a6216dac3a9c432c3a2aab3d4f0c2f79a837943
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Tue Feb 22 13:06:06 2011 +0100
Final touches on the CLI alert sender UI.
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/CliNotificationSenderForm.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/CliNotificationSenderForm.java
index 1800f48..61b3f3d 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/CliNotificationSenderForm.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/CliNotificationSenderForm.java
@@ -20,12 +20,9 @@
package org.rhq.enterprise.gui.coregui.client.alert.definitions;
import java.util.Collections;
-import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
-import java.util.ListIterator;
-import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.smartgwt.client.types.TitleOrientation;
import com.smartgwt.client.widgets.form.DynamicForm;
@@ -42,12 +39,10 @@ import com.smartgwt.client.widgets.form.fields.events.ChangedEvent;
import com.smartgwt.client.widgets.form.fields.events.ChangedHandler;
import com.smartgwt.client.widgets.form.fields.events.ClickEvent;
import com.smartgwt.client.widgets.form.fields.events.ClickHandler;
-import com.smartgwt.client.widgets.form.validator.Validator;
import org.rhq.core.domain.alert.notification.AlertNotification;
import org.rhq.core.domain.auth.Subject;
import org.rhq.core.domain.configuration.PropertySimple;
-import org.rhq.core.domain.content.Package;
import org.rhq.core.domain.content.PackageType;
import org.rhq.core.domain.content.Repo;
import org.rhq.core.domain.content.composite.PackageAndLatestVersionComposite;
@@ -61,7 +56,6 @@ import org.rhq.enterprise.gui.coregui.client.UserSessionManager;
import org.rhq.enterprise.gui.coregui.client.components.form.RadioGroupWithComponentsItem;
import org.rhq.enterprise.gui.coregui.client.components.upload.DynamicFormHandler;
import org.rhq.enterprise.gui.coregui.client.components.upload.DynamicFormSubmitCompleteEvent;
-import org.rhq.enterprise.gui.coregui.client.components.upload.FileUploadForm;
import org.rhq.enterprise.gui.coregui.client.components.upload.PackageVersionFileUploadForm;
import org.rhq.enterprise.gui.coregui.client.gwt.GWTServiceLookup;
import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableDynamicForm;
@@ -127,7 +121,7 @@ public class CliNotificationSenderForm extends AbstractNotificationSenderForm {
}
private static class PackageVersionFileUploadFormWithVersion extends PackageVersionFileUploadForm {
-
+
/**
* @param locatorId
* @param packageTypeId
@@ -153,7 +147,30 @@ public class CliNotificationSenderForm extends AbstractNotificationSenderForm {
return items;
}
}
+
+ private static abstract class ForwardingDynamicFormHandler implements DynamicFormHandler {
+ private AsyncCallback<Void> callback;
+
+ public AsyncCallback<Void> getCallback() {
+ return callback;
+ }
+
+ public void setCallback(AsyncCallback<Void> callback) {
+ this.callback = callback;
+ }
+ };
+ private static abstract class ForwardingSubmitFailedHandler implements FormSubmitFailedHandler {
+ private AsyncCallback<Void> callback;
+
+ public AsyncCallback<Void> getCallback() {
+ return callback;
+ }
+
+ public void setCallback(AsyncCallback<Void> callback) {
+ this.callback = callback;
+ }
+ };
private boolean formBuilt;
@@ -168,8 +185,8 @@ public class CliNotificationSenderForm extends AbstractNotificationSenderForm {
private ButtonItem verifyUserButton;
private FormItemIcon authSuccessIcon;
private FormItemIcon authFailureIcon;
- private HandlerRegistration currentUploadFailureRegistration;
- private DynamicFormHandler currentUploadSuccessHandler;
+ private ForwardingSubmitFailedHandler uploadFailureHandler;
+ private ForwardingDynamicFormHandler uploadSuccessHandler;
private Config config;
@@ -224,8 +241,9 @@ public class CliNotificationSenderForm extends AbstractNotificationSenderForm {
createAnotherUserForm());
userSelector = new RadioGroupWithComponentsItem(
extendLocatorId("userSelector"),
- "", userSelectItems, form);
+ "", userSelectItems, form);
userSelector.setWidth("100%");
+ userSelector.setShowTitle(false);
repoSection.setItemIds(extendLocatorId("repoSelector"));
packageSection.setItemIds(extendLocatorId("packageSelector"));
@@ -380,32 +398,16 @@ public class CliNotificationSenderForm extends AbstractNotificationSenderForm {
getConfiguration().put(new PropertySimple(PROP_PACKAGE_ID, config.selectedPackage.getGeneralPackage().getId()));
callback.onSuccess(null);
} else {
- currentUploadFailureRegistration = uploadForm.addFormSubmitFailedHandler(new FormSubmitFailedHandler() {
- public void onFormSubmitFailed(FormSubmitFailedEvent event) {
- uploadForm.removeFormHandler(currentUploadSuccessHandler);
- currentUploadFailureRegistration.removeHandler();
+ uploadFailureHandler.setCallback(callback);
+ uploadSuccessHandler.setCallback(new AsyncCallback<Void>() {
+ public void onFailure(Throwable caught) {
callback.onFailure(null);
- }
- });
-
- currentUploadSuccessHandler = new DynamicFormHandler() {
- public void onSubmitComplete(DynamicFormSubmitCompleteEvent event) {
- if (uploadForm.getPackageId() == 0 || uploadForm.getPackageVersionId() == 0) {
- uploadForm.removeFormHandler(this);
- currentUploadFailureRegistration.removeHandler();
- callback.onFailure(null);
- return;
- }
-
+ };
+ public void onSuccess(Void result) {
getConfiguration().put(new PropertySimple(PROP_PACKAGE_ID, uploadForm.getPackageId()));
-
- uploadForm.removeFormHandler(this);
- currentUploadFailureRegistration.removeHandler();
callback.onSuccess(null);
- }
- };
- uploadForm.addFormHandler(currentUploadSuccessHandler);
-
+ };
+ });
uploadForm.submitForm();
}
}
@@ -543,6 +545,30 @@ public class CliNotificationSenderForm extends AbstractNotificationSenderForm {
uploadForm = new PackageVersionFileUploadFormWithVersion(extendLocatorId("uploadForm"), cliScriptPackageType.getId());
uploadForm.setTitleOrientation(TitleOrientation.TOP);
uploadForm.setPackageTypeId(cliScriptPackageType.getId());
+
+ uploadFailureHandler = (new ForwardingSubmitFailedHandler() {
+ public void onFormSubmitFailed(FormSubmitFailedEvent event) {
+ if (getCallback() != null) {
+ getCallback().onFailure(null);
+ }
+ }
+ });
+
+ uploadSuccessHandler = new ForwardingDynamicFormHandler() {
+ public void onSubmitComplete(DynamicFormSubmitCompleteEvent event) {
+ if (uploadForm.getPackageId() == 0 || uploadForm.getPackageVersionId() == 0) {
+ if (getCallback() != null) {
+ getCallback().onFailure(null);
+ }
+ return;
+ }
+
+ if (getCallback() != null) {
+ getCallback().onSuccess(null);
+ }
+ }
+ };
+ uploadForm.addFormHandler(uploadSuccessHandler);
return uploadForm;
}
@@ -565,7 +591,7 @@ public class CliNotificationSenderForm extends AbstractNotificationSenderForm {
public void onSuccess(Subject result) {
config.selectedSubject = result;
- verifyUserButton.setIcons(authSuccessIcon);
+ verifyUserButton.setIcons(result == null ? authFailureIcon : authSuccessIcon);
markForRedraw();
action.onSuccess(null);
}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/upload/FileUploadForm.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/upload/FileUploadForm.java
index 3e74575..4e12df5 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/upload/FileUploadForm.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/upload/FileUploadForm.java
@@ -113,9 +113,7 @@ public class FileUploadForm extends DynamicCallbackForm {
public void setName(String name) {
this.name = name;
- if (onDrawCalled()) {
- getItem("name").setValue(name);
- }
+ onDraw();
}
public String getVersion() {
@@ -124,9 +122,7 @@ public class FileUploadForm extends DynamicCallbackForm {
public void setVersion(String version) {
this.version = version;
- if (onDrawCalled()) {
- getItem("version").setValue(version);
- }
+ onDraw();
}
/**
@@ -315,10 +311,6 @@ public class FileUploadForm extends DynamicCallbackForm {
}
}
- protected boolean onDrawCalled() {
- return getItem("sessionid") != null;
- }
-
public List<String> getUploadedFilePaths() {
return uploadedFilePaths;
}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/upload/PackageVersionFileUploadForm.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/upload/PackageVersionFileUploadForm.java
index 4085a82..5e0848d 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/upload/PackageVersionFileUploadForm.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/upload/PackageVersionFileUploadForm.java
@@ -79,9 +79,7 @@ public class PackageVersionFileUploadForm extends FileUploadForm {
public void setPackageTypeId(int value) {
packageTypeId = value;
- if (onDrawCalled()) {
- getItem("packageTypeId").setValue(value);
- }
+ onDraw();
}
public Integer getArchitectureId() {
@@ -90,18 +88,7 @@ public class PackageVersionFileUploadForm extends FileUploadForm {
public void setArchitectureId(Integer value) {
archId = value;
- FormItem item = getItem("archId");
- if (item != null) {
- if (value == null) {
- removeField("archId");
- } else {
- item.setDefaultValue(value);
- }
- } else if (value != null && onDrawCalled()) {
- HiddenItem archIdField = new HiddenItem("archId");
- archIdField.setDefaultValue(value);
- addField(archIdField);
- }
+ onDraw();
}
public Integer getRepoId() {
@@ -110,18 +97,7 @@ public class PackageVersionFileUploadForm extends FileUploadForm {
public void setRepoId(Integer value) {
repoId = value;
- FormItem item = getItem("repoId");
- if (item != null) {
- if (value != null) {
- removeField("repoId");
- } else {
- item.setDefaultValue(value);
- }
- } else if (value != null && onDrawCalled()) {
- HiddenItem repoIdField = new HiddenItem("repoId");
- repoIdField.setDefaultValue(value);
- addField(repoIdField);
- }
+ onDraw();
}
@Override
@@ -212,30 +188,4 @@ public class PackageVersionFileUploadForm extends FileUploadForm {
super.submitForm();
}
-
- private void removeField(String fieldName) {
- FormItem[] items = getFields();
- FormItem[] newItems = new FormItem[items.length - 1];
- int idx = 0;
- for (FormItem i : items) {
- if (!fieldName.equals(i.getName())) {
- newItems[idx] = i;
- }
- ++idx;
- }
-
- setFields(newItems);
- markForRedraw();
- }
-
- private void addField(FormItem item) {
- FormItem[] items = getFields();
- FormItem[] newItems = new FormItem[items.length + 1];
-
- System.arraycopy(items, 0, newItems, 0, items.length);
- newItems[items.length] = item;
-
- setFields(newItems);
- markForRedraw();
- }
}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/PackageVersionFileUploadServlet.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/PackageVersionFileUploadServlet.java
index dc89a2c..02d69a4 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/PackageVersionFileUploadServlet.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/PackageVersionFileUploadServlet.java
@@ -83,15 +83,9 @@ public class PackageVersionFileUploadServlet extends FileUploadServlet {
//persisted.
Map<String, String> metaData = new HashMap<String, String>();
metaData.put(ContentManagerLocal.UPLOAD_FILE_INSTALL_DATE, Long.toString(file.lastModified()));
- metaData.put(ContentManagerLocal.UPLOAD_FILE_NAME, files.keySet().iterator().next());
- PackageVersion packageVersion = contentManager.getUploadedPackageVersion(packageName, packageTypeId,
- version, architectureId, fileStream, metaData, null);
-
- if (repoId != null) {
- //XXX create a new SLSB method that would combine this and the above call in one transaction?
- RepoManagerLocal repoManager = LookupUtil.getRepoManagerLocal();
- repoManager.addPackageVersionsToRepo(subject, repoId, new int[] { packageVersion.getId() });
- }
+ metaData.put(ContentManagerLocal.UPLOAD_FILE_NAME, packageName);
+ PackageVersion packageVersion = contentManager.getUploadedPackageVersion(subject, packageName,
+ packageTypeId, version, architectureId, fileStream, metaData, null, repoId);
successMsg = "success [packageVersionId=" + packageVersion.getId() + ",packageId=" + packageVersion.getGeneralPackage().getId() + "]";
} catch (Exception e) {
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/SubjectGWTServiceImpl.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/SubjectGWTServiceImpl.java
index 303c5c3..e690d84 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/SubjectGWTServiceImpl.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/SubjectGWTServiceImpl.java
@@ -136,7 +136,8 @@ public class SubjectGWTServiceImpl extends AbstractGWTServiceImpl implements Sub
public Subject checkAuthentication(String username, String password) {
try {
- return subjectManager.checkAuthentication(username, password);
+ return SerialUtility.prepare(subjectManager.checkAuthentication(username, password),
+ "SubjectManager.checkAuthentication");
} catch (Throwable t) {
throw new RuntimeException(ThrowableUtil.getAllMessages(t));
}
diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/content/CreateNewPackageUIBean.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/content/CreateNewPackageUIBean.java
index 4a90c20..7c1cf1d 100644
--- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/content/CreateNewPackageUIBean.java
+++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/content/CreateNewPackageUIBean.java
@@ -246,8 +246,9 @@ public class CreateNewPackageUIBean {
//TODO: need to get parent id instead right? ref to app server inst itself?
Integer newResourceTypeId = resource == null ? null : resource.getResourceType().getId();
- packageVersion = contentManager.getUploadedPackageVersion(packageName, packageTypeId, version,
- architectureId, packageStream, packageUploadDetails, newResourceTypeId);
+ Integer iRepoId = usingARepo ? Integer.parseInt(repoId) : null;
+ packageVersion = contentManager.getUploadedPackageVersion(subject, packageName, packageTypeId,
+ version, architectureId, packageStream, packageUploadDetails, newResourceTypeId, iRepoId);
} catch (NoResultException nre) {
//eat the exception. Some of the queries return no results if no package yet exists which is fine.
@@ -260,21 +261,6 @@ public class CreateNewPackageUIBean {
int[] packageVersionList = new int[] { packageVersion.getId() };
- // Add the package to the repo
- if (usingARepo) {
- try {
- int iRepoId = Integer.parseInt(repoId);
-
- RepoManagerLocal repoManager = LookupUtil.getRepoManagerLocal();
- repoManager.addPackageVersionsToRepo(subject, iRepoId, packageVersionList);
- } catch (Exception e) {
- String errorMessages = ThrowableUtil.getAllMessages(e);
- FacesContextUtility.addMessage(FacesMessage.SEVERITY_ERROR, "Failed to associate package ["
- + packageName + "] with repository ID [" + repoId + "]. Cause: " + errorMessages);
- return "failure";
- }
- }
-
// Put the package ID in the session so it can fit into the deploy existing package workflow
HttpSession session = request.getSession();
session.setAttribute("selectedPackages", packageVersionList);
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerBean.java
index 4735ed8..026ea38 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerBean.java
@@ -1571,9 +1571,9 @@ public class ContentManagerBean implements ContentManagerLocal, ContentManagerRe
* when file has been uploaded via the UI.
*/
@SuppressWarnings("unchecked")
- public PackageVersion getUploadedPackageVersion(String packageName, int packageTypeId, String version,
- int architectureId, InputStream packageBitStream, Map<String, String> packageUploadDetails,
- Integer newResourceTypeId) {
+ public PackageVersion getUploadedPackageVersion(Subject subject, String packageName, int packageTypeId,
+ String version, int architectureId, InputStream packageBitStream,
+ Map<String, String> packageUploadDetails, Integer newResourceTypeId, Integer repoId) {
PackageVersion packageVersion = null;
PackageType packageType = null;
@@ -1651,6 +1651,12 @@ public class ContentManagerBean implements ContentManagerLocal, ContentManagerRe
}
entityManager.merge(packageVersion);
+
+ if (repoId != null) {
+ int[] packageVersionIds = new int[] { packageVersion.getId() };
+ repoManager.addPackageVersionsToRepo(subject, repoId, packageVersionIds);
+ }
+
entityManager.flush();
return packageVersion;
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerLocal.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerLocal.java
index 5212a98..6ae321a 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerLocal.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerLocal.java
@@ -242,7 +242,7 @@ public interface ContentManagerLocal {
* This method is similar to the {@link #createPackageVersion(String, int, String, int, InputStream)} but fails if
* the package version with the provided details already exists which is a desired behaviour for the GUI originating
* requests.
- *
+ * @param subject the current user
* @param packageName the name of the package (the general package will be created if none exists)
* @param packageTypeId the id of the package type. This is ignored if the <code>newResourceTypeId</code> is not null
* @param version the version of the package version being created
@@ -251,11 +251,12 @@ public interface ContentManagerLocal {
* @param packageUploadDetails additional details about the package. See the constants defined in this interface
* @param newResourceTypeId the resource type id the package version should be bound to. This is to support the usecase
* where a package version is being created as the backing content of a resource.
+ * @param repoId an optional id of the repo to insert the package version in
*
* @return the newly create package version
*/
- PackageVersion getUploadedPackageVersion(String packageName, int packageTypeId, String version, int architectureId,
- InputStream packageBitStream, Map<String, String> packageUploadDetails, Integer newResourceTypeId);
+ PackageVersion getUploadedPackageVersion(Subject subject, String packageName, int packageTypeId, String version,
+ int architectureId, InputStream packageBitStream, Map<String, String> packageUploadDetails, Integer newResourceTypeId, Integer repoId);
/**
* Very simple method that persists the given package version within its own transaction.
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceFactoryManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceFactoryManagerBean.java
index a27ae5c..5a08508 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceFactoryManagerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceFactoryManagerBean.java
@@ -466,8 +466,8 @@ public class ResourceFactoryManagerBean implements ResourceFactoryManagerLocal,
packageVersion = contentManager.createPackageVersion(packageName, newPackageType.getId(),
packageVersionNumber, architectureId, packageBitStream);
} else {
- packageVersion = contentManager.getUploadedPackageVersion(packageName, newPackageType.getId(),
- packageVersionNumber, architectureId, packageBitStream, packageUploadDetails, newResourceTypeId);
+ packageVersion = contentManager.getUploadedPackageVersion(user, packageName,
+ newPackageType.getId(), packageVersionNumber, architectureId, packageBitStream, packageUploadDetails, newResourceTypeId, null);
}
return doCreatePackageBackedResource(user, parentResource, newResourceType, newResourceName,
commit 74b9e24183181b31a24eaa98dc11aad6fceebaa9
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Tue Feb 22 13:04:41 2011 +0100
Make sure to find the local method on the invocation handler even if it is defined in the super classes.
diff --git a/modules/enterprise/binding/src/main/java/org/rhq/bindings/client/ResourceClientProxy.java b/modules/enterprise/binding/src/main/java/org/rhq/bindings/client/ResourceClientProxy.java
index 13517df..5b49e18 100644
--- a/modules/enterprise/binding/src/main/java/org/rhq/bindings/client/ResourceClientProxy.java
+++ b/modules/enterprise/binding/src/main/java/org/rhq/bindings/client/ResourceClientProxy.java
@@ -565,7 +565,7 @@ public class ResourceClientProxy {
} else {
try {
- Method localMethod = getClass().getDeclaredMethod(method.getName(), method
+ Method localMethod = getClass().getMethod(method.getName(), method
.getParameterTypes());
return localMethod.invoke(this, args);
} catch (NoSuchMethodException nsme) {
commit 09d33b2249ba13444fb96b0c5579681ca6c19890
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Mon Feb 21 18:15:15 2011 +0100
A lot of improvements on the CLI notification editor.
The notification editor validation is now possibly asynchronous so that we can support uploading a file upon confirming the dialog
some new support methods in the business layers.
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/AbstractNotificationSenderForm.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/AbstractNotificationSenderForm.java
index 5b68ee4..0ada400 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/AbstractNotificationSenderForm.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/AbstractNotificationSenderForm.java
@@ -22,6 +22,8 @@
*/
package org.rhq.enterprise.gui.coregui.client.alert.definitions;
+import com.google.gwt.user.client.rpc.AsyncCallback;
+
import org.rhq.core.domain.alert.notification.AlertNotification;
import org.rhq.core.domain.configuration.Configuration;
import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableVLayout;
@@ -110,5 +112,15 @@ public abstract class AbstractNotificationSenderForm extends LocatableVLayout {
}
}
- public abstract boolean validate();
+ /**
+ * Kicks off the validation, possibly doing some asynchronous work.
+ * Upon successful validation the <code>callback</code>'s <code>onSuccess</code>
+ * method must be invoked, <code>onFailure</code> on validation failure.
+ * <p>
+ * Both <code>onSuccess</code> and <code>onFailure</code> can be passed <code>null</code>
+ * as their arguments.
+ *
+ * @param callback
+ */
+ public abstract void validate(AsyncCallback<Void> callback);
}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/CliNotificationSenderForm.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/CliNotificationSenderForm.java
index 5041dde..1800f48 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/CliNotificationSenderForm.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/CliNotificationSenderForm.java
@@ -25,17 +25,24 @@ import java.util.LinkedHashMap;
import java.util.List;
import java.util.ListIterator;
+import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.smartgwt.client.types.TitleOrientation;
import com.smartgwt.client.widgets.form.DynamicForm;
+import com.smartgwt.client.widgets.form.events.FormSubmitFailedEvent;
+import com.smartgwt.client.widgets.form.events.FormSubmitFailedHandler;
import com.smartgwt.client.widgets.form.fields.ButtonItem;
import com.smartgwt.client.widgets.form.fields.FormItem;
+import com.smartgwt.client.widgets.form.fields.FormItemIcon;
import com.smartgwt.client.widgets.form.fields.PasswordItem;
import com.smartgwt.client.widgets.form.fields.SectionItem;
import com.smartgwt.client.widgets.form.fields.SelectItem;
import com.smartgwt.client.widgets.form.fields.TextItem;
import com.smartgwt.client.widgets.form.fields.events.ChangedEvent;
import com.smartgwt.client.widgets.form.fields.events.ChangedHandler;
+import com.smartgwt.client.widgets.form.fields.events.ClickEvent;
+import com.smartgwt.client.widgets.form.fields.events.ClickHandler;
+import com.smartgwt.client.widgets.form.validator.Validator;
import org.rhq.core.domain.alert.notification.AlertNotification;
import org.rhq.core.domain.auth.Subject;
@@ -43,13 +50,17 @@ import org.rhq.core.domain.configuration.PropertySimple;
import org.rhq.core.domain.content.Package;
import org.rhq.core.domain.content.PackageType;
import org.rhq.core.domain.content.Repo;
+import org.rhq.core.domain.content.composite.PackageAndLatestVersionComposite;
import org.rhq.core.domain.criteria.PackageCriteria;
import org.rhq.core.domain.criteria.RepoCriteria;
import org.rhq.core.domain.criteria.SubjectCriteria;
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.RadioGroupWithComponentsItem;
+import org.rhq.enterprise.gui.coregui.client.components.upload.DynamicFormHandler;
+import org.rhq.enterprise.gui.coregui.client.components.upload.DynamicFormSubmitCompleteEvent;
import org.rhq.enterprise.gui.coregui.client.components.upload.FileUploadForm;
import org.rhq.enterprise.gui.coregui.client.components.upload.PackageVersionFileUploadForm;
import org.rhq.enterprise.gui.coregui.client.gwt.GWTServiceLookup;
@@ -65,14 +76,16 @@ public class CliNotificationSenderForm extends AbstractNotificationSenderForm {
private static final String PROP_PACKAGE_ID = "packageId";
private static final String PROP_REPO_ID = "repoId";
private static final String PROP_USER_ID = "userId";
+ private static final String PROP_USER_NAME = "userName";
+ private static final String PROP_USER_PASSWORD = "userPassword";
private static final String PACKAGE_TYPE_NAME = "__SERVER_SIDE_CLI_SCRIPT";
private static class Config {
List<Repo> allRepos;
Repo selectedRepo;
- List<Package> allPackages;
- Package selectedPackage;
+ List<PackageAndLatestVersionComposite> allPackages;
+ PackageAndLatestVersionComposite selectedPackage;
Subject selectedSubject;
@@ -103,8 +116,8 @@ public class CliNotificationSenderForm extends AbstractNotificationSenderForm {
public void setSelectedPackage(int packageId) {
if (allPackages != null) {
- for(Package p : allPackages) {
- if (p.getId() == packageId) {
+ for(PackageAndLatestVersionComposite p : allPackages) {
+ if (p.getGeneralPackage().getId() == packageId) {
selectedPackage = p;
break;
}
@@ -150,8 +163,16 @@ public class CliNotificationSenderForm extends AbstractNotificationSenderForm {
private RadioGroupWithComponentsItem userSelector;
private PackageVersionFileUploadFormWithVersion uploadForm;
private PackageType cliScriptPackageType;
+ private TextItem anotherUserName;
+ private TextItem anotherUserPassword;
+ private ButtonItem verifyUserButton;
+ private FormItemIcon authSuccessIcon;
+ private FormItemIcon authFailureIcon;
+ private HandlerRegistration currentUploadFailureRegistration;
+ private DynamicFormHandler currentUploadSuccessHandler;
+
private Config config;
-
+
public CliNotificationSenderForm(String locatorId, AlertNotification notif, String sender) {
super(locatorId, notif, sender);
}
@@ -249,13 +270,14 @@ public class CliNotificationSenderForm extends AbstractNotificationSenderForm {
private void setupPackageSelector() {
LinkedHashMap<String, String> map = new LinkedHashMap<String, String>();
- for(Package p : config.allPackages) {
- map.put(String.valueOf(p.getId()), p.getName());
+ for(PackageAndLatestVersionComposite p : config.allPackages) {
+ String label = p.getGeneralPackage().getName() + " (" + p.getLatestPackageVersion().getVersion() + ")";
+ map.put(String.valueOf(p.getGeneralPackage().getId()), label);
}
existingPackageSelector.setValueMap(map);
if (config.selectedPackage != null) {
- existingPackageSelector.setValue(config.selectedPackage.getId());
+ existingPackageSelector.setValue(config.selectedPackage.getGeneralPackage().getId());
packageSelector.setSelected(MSG.view_alert_definition_notification_cliScript_editor_existingScript());
} else {
packageSelector.setSelected(MSG.view_alert_definition_notification_cliScript_editor_uploadNewScript());
@@ -285,9 +307,11 @@ public class CliNotificationSenderForm extends AbstractNotificationSenderForm {
if (config.selectedRepo != null) {
repoSelector.setValue(config.selectedRepo.getId());
packageSelector.setDisabled(false);
+ uploadForm.setRepoId(config.selectedRepo.getId());
} else {
repoSelector.setValue("");
packageSelector.setDisabled(true);
+ uploadForm.setRepoId(null);
}
if (!formBuilt) {
@@ -304,8 +328,8 @@ public class CliNotificationSenderForm extends AbstractNotificationSenderForm {
existingPackageSelector.setDisabled(true);
existingPackageSelector.setValueMap(MSG.common_msg_loading());
- GWTServiceLookup.getContentService().findPackagesByCriteria(pc, new AsyncCallback<PageList<Package>>() {
- public void onSuccess(PageList<Package> result) {
+ GWTServiceLookup.getContentService().findPackagesWithLatestVersion(pc, new AsyncCallback<PageList<PackageAndLatestVersionComposite>>() {
+ public void onSuccess(PageList<PackageAndLatestVersionComposite> result) {
config.allPackages = result;
config.selectedPackage = result.isEmpty() ? null : result.get(0); //we're autoselecting the first item
setupPackageSelector();
@@ -327,36 +351,63 @@ public class CliNotificationSenderForm extends AbstractNotificationSenderForm {
markForRedraw();
}
- public boolean validate() {
- // TODO add validation messages to the individual fields
-
- if (userSelector.getSelectedIndex() != 0 && config.selectedSubject == null) {
- return false;
- }
-
- if (config.selectedRepo == null) {
- return false;
- }
-
- if (packageSelector.getSelectedIndex() == 0 && config.selectedPackage == null) {
- return false;
- }
-
+ @Override
+ public void validate(final AsyncCallback<Void> callback) {
if (userSelector.getSelectedIndex() == 0) {
getConfiguration().put(new PropertySimple(PROP_USER_ID, UserSessionManager.getSessionSubject().getId()));
+ validatePackage(callback);
} else {
- getConfiguration().put(new PropertySimple(PROP_USER_ID, config.selectedSubject.getId()));
- }
-
+ checkAuthenticationAndDo(new AsyncCallback<Void>() {
+ public void onFailure(Throwable caught) {
+ callback.onFailure(caught);
+ }
+
+ public void onSuccess(Void result) {
+ getConfiguration().put(new PropertySimple(PROP_USER_ID, config.selectedSubject.getId()));
+ getConfiguration().put(new PropertySimple(PROP_USER_NAME, anotherUserName.getEnteredValue()));
+ getConfiguration().put(new PropertySimple(PROP_USER_PASSWORD, anotherUserPassword.getEnteredValue()));
+
+ validatePackage(callback);
+ }
+ });
+ }
+ }
+
+ private void validatePackage(final AsyncCallback<Void> callback) {
getConfiguration().put(new PropertySimple(PROP_REPO_ID, config.selectedRepo.getId()));
-
+
if (packageSelector.getSelectedIndex() == 0) {
- getConfiguration().put(new PropertySimple(PROP_PACKAGE_ID, config.selectedPackage.getId()));
+ getConfiguration().put(new PropertySimple(PROP_PACKAGE_ID, config.selectedPackage.getGeneralPackage().getId()));
+ callback.onSuccess(null);
} else {
- //TODO do upload here and wait for the result before returning...
+ currentUploadFailureRegistration = uploadForm.addFormSubmitFailedHandler(new FormSubmitFailedHandler() {
+ public void onFormSubmitFailed(FormSubmitFailedEvent event) {
+ uploadForm.removeFormHandler(currentUploadSuccessHandler);
+ currentUploadFailureRegistration.removeHandler();
+ callback.onFailure(null);
+ }
+ });
+
+ currentUploadSuccessHandler = new DynamicFormHandler() {
+ public void onSubmitComplete(DynamicFormSubmitCompleteEvent event) {
+ if (uploadForm.getPackageId() == 0 || uploadForm.getPackageVersionId() == 0) {
+ uploadForm.removeFormHandler(this);
+ currentUploadFailureRegistration.removeHandler();
+ callback.onFailure(null);
+ return;
+ }
+
+ getConfiguration().put(new PropertySimple(PROP_PACKAGE_ID, uploadForm.getPackageId()));
+
+ uploadForm.removeFormHandler(this);
+ currentUploadFailureRegistration.removeHandler();
+ callback.onSuccess(null);
+ }
+ };
+ uploadForm.addFormHandler(currentUploadSuccessHandler);
+
+ uploadForm.submitForm();
}
-
- return true;
}
private void loadConfig(final AsyncCallback<Config> handler) {
@@ -391,9 +442,8 @@ public class CliNotificationSenderForm extends AbstractNotificationSenderForm {
PackageCriteria pc = new PackageCriteria();
pc.addFilterRepoId(Integer.parseInt(repoId));
pc.addFilterPackageTypeId(cliScriptPackageType.getId());
-
- GWTServiceLookup.getContentService().findPackagesByCriteria(pc, new AsyncCallback<PageList<Package>>() {
- public void onSuccess(PageList<Package> result) {
+ GWTServiceLookup.getContentService().findPackagesWithLatestVersion(pc, new AsyncCallback<PageList<PackageAndLatestVersionComposite>>() {
+ public void onSuccess(PageList<PackageAndLatestVersionComposite> result) {
config.allPackages = result;
if (packageId != null && packageId.trim().length() > 0) {
@@ -443,12 +493,34 @@ public class CliNotificationSenderForm extends AbstractNotificationSenderForm {
private DynamicForm createAnotherUserForm() {
LocatableDynamicForm form = new LocatableDynamicForm(extendLocatorId("anotherUserForm"));
form.setTitleOrientation(TitleOrientation.TOP);
- TextItem userNameItem = new TextItem("userName", MSG.dataSource_users_field_name());
- PasswordItem passwordItem = new PasswordItem("password", MSG.dataSource_users_field_password());
- ButtonItem verifyItem = new ButtonItem("verify", MSG.view_alert_definition_notification_cliScript_editor_verifyAuthentication());
- form.setFields(userNameItem, passwordItem, verifyItem);
+ anotherUserName = new TextItem("userName", MSG.dataSource_users_field_name());
+ anotherUserPassword = new PasswordItem("password", MSG.dataSource_users_field_password());
+ verifyUserButton = new ButtonItem("verify", MSG.view_alert_definition_notification_cliScript_editor_verifyAuthentication());
- //TODO add verification functionality
+ authSuccessIcon = new FormItemIcon();
+ authSuccessIcon.setSrc(ImageManager.getAvailabilityIcon(Boolean.TRUE));
+ authSuccessIcon.setWidth(16);
+ authSuccessIcon.setHeight(16);
+
+ authFailureIcon = new FormItemIcon();
+ authFailureIcon.setSrc(ImageManager.getAvailabilityIcon(Boolean.FALSE));
+ authFailureIcon.setWidth(16);
+ authFailureIcon.setHeight(16);
+
+ form.setFields(anotherUserName, anotherUserPassword, verifyUserButton);
+
+ verifyUserButton.addClickHandler(new ClickHandler() {
+ public void onClick(ClickEvent event) {
+ //just checking the auth is ok, no other action is needed.
+ checkAuthenticationAndDo(new AsyncCallback<Void>() {
+ public void onFailure(Throwable caught) {
+ }
+
+ public void onSuccess(Void result) {
+ }
+ });
+ }
+ });
return form;
}
@@ -459,7 +531,7 @@ public class CliNotificationSenderForm extends AbstractNotificationSenderForm {
existingPackageSelector.setDefaultToFirstOption(true);
existingPackageSelector.setWrapTitle(false);
existingPackageSelector.setRedrawOnChange(true);
- existingPackageSelector.setWidth("*");
+ existingPackageSelector.setWidth(300);
existingPackageSelector.setValueMap(MSG.common_msg_loading());
existingPackageSelector.setDisabled(true);
@@ -470,11 +542,33 @@ public class CliNotificationSenderForm extends AbstractNotificationSenderForm {
private DynamicForm createUploadNewScriptForm() {
uploadForm = new PackageVersionFileUploadFormWithVersion(extendLocatorId("uploadForm"), cliScriptPackageType.getId());
uploadForm.setTitleOrientation(TitleOrientation.TOP);
-
+ uploadForm.setPackageTypeId(cliScriptPackageType.getId());
+
return uploadForm;
}
private void loadPackageType(AsyncCallback<PackageType> handler) {
GWTServiceLookup.getContentService().findPackageType(null, PACKAGE_TYPE_NAME, handler);
}
+
+ private void checkAuthenticationAndDo(final AsyncCallback<Void> action) {
+ String username = anotherUserName.getEnteredValue();
+ String password = anotherUserPassword.getEnteredValue();
+
+ GWTServiceLookup.getSubjectService().checkAuthentication(username, password, new AsyncCallback<Subject>() {
+ public void onFailure(Throwable caught) {
+ config.selectedSubject = null;
+ verifyUserButton.setIcons(authFailureIcon);
+ markForRedraw();
+ action.onFailure(caught);
+ }
+
+ public void onSuccess(Subject result) {
+ config.selectedSubject = result;
+ verifyUserButton.setIcons(authSuccessIcon);
+ markForRedraw();
+ action.onSuccess(null);
+ }
+ });
+ }
}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/NewNotificationEditor.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/NewNotificationEditor.java
index e1c4b44..666ecfa 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/NewNotificationEditor.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/NewNotificationEditor.java
@@ -158,10 +158,18 @@ public class NewNotificationEditor extends LocatableDynamicForm {
if (validate(false)) {
AbstractNotificationSenderForm senderForm = (AbstractNotificationSenderForm) senderCanvasItem
.getCanvas();
- if (senderForm.validate()) {
- saveNewNotification();
- closeFunction.run();
- }
+ senderForm.validate(new AsyncCallback<Void>() {
+ public void onSuccess(Void o) {
+ saveNewNotification();
+ closeFunction.run();
+ }
+
+ public void onFailure(Throwable t) {
+ //do nothing
+ //the sender form is supposed to warn the user about what is wrong
+ //with the supplied values.
+ }
+ });
}
}
});
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/ResourceOperationNotificationSenderForm.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/ResourceOperationNotificationSenderForm.java
index cdec69f..4a565a2 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/ResourceOperationNotificationSenderForm.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/ResourceOperationNotificationSenderForm.java
@@ -554,7 +554,7 @@ public class ResourceOperationNotificationSenderForm extends AbstractNotificatio
}
@Override
- public boolean validate() {
+ public void validate(AsyncCallback<Void> callback) {
try {
if (dynamicForm.validate(false)) {
// let's make sure the args can be validated successfully.
@@ -562,7 +562,8 @@ public class ResourceOperationNotificationSenderForm extends AbstractNotificatio
ConfigurationEditor configEditor = getConfigurationEditor();
if (configEditor != null) {
if (!configEditor.validate()) {
- return false;
+ callback.onFailure(null);
+ return;
}
// nothing else to store - our config editor directly edited our extraConfig already
} else {
@@ -609,13 +610,13 @@ public class ResourceOperationNotificationSenderForm extends AbstractNotificatio
config.put(new PropertySimple(ResourceOperationNotificationInfo.Constants.OPERATION_ID
.getPropertyName(), operationId));
- return true;
+ callback.onSuccess(null);
} else {
- return false;
+ callback.onFailure(null);
}
} catch (Exception e) {
CoreGUI.getErrorHandler().handleError(MSG.view_alert_definition_notification_editor_saveFailed(), e);
- return false;
+ callback.onFailure(null);
}
}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/SimpleNotificationSenderForm.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/SimpleNotificationSenderForm.java
index 1095a28..2714134 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/SimpleNotificationSenderForm.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/SimpleNotificationSenderForm.java
@@ -76,11 +76,16 @@ public class SimpleNotificationSenderForm extends AbstractNotificationSenderForm
}
@Override
- public boolean validate() {
+ public void validate(AsyncCallback<Void> callback) {
if (configEditor != null) {
- return configEditor.validate();
+ if (configEditor.validate()) {
+ callback.onSuccess(null);
+ } else {
+ callback.onFailure(null);
+ }
+ } else {
+ callback.onSuccess(null);
}
- return true;
}
}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/SystemRolesNotificationSenderForm.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/SystemRolesNotificationSenderForm.java
index 606da75..faf8087 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/SystemRolesNotificationSenderForm.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/SystemRolesNotificationSenderForm.java
@@ -103,20 +103,21 @@ public class SystemRolesNotificationSenderForm extends AbstractNotificationSende
}
@Override
- public boolean validate() {
+ public void validate(AsyncCallback<Void> callback) {
if (selector != null) {
try {
Set<Integer> selectedIds = selector.getSelection();
String newPropValue = fence(selectedIds);
getConfiguration().put(new PropertySimple(PROPNAME, newPropValue));
- return true;
+ callback.onSuccess(null);
} catch (Exception e) {
CoreGUI.getErrorHandler().handleError(MSG.view_alert_definition_notification_role_editor_saveFailed(),
e);
- return false;
+ callback.onFailure(null);
}
+ } else {
+ callback.onSuccess(null);
}
- return true;
}
@SuppressWarnings("unchecked")
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/SystemUsersNotificationSenderForm.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/SystemUsersNotificationSenderForm.java
index 7e45d52..fd67e71 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/SystemUsersNotificationSenderForm.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/SystemUsersNotificationSenderForm.java
@@ -114,20 +114,21 @@ public class SystemUsersNotificationSenderForm extends AbstractNotificationSende
}
@Override
- public boolean validate() {
+ public void validate(AsyncCallback<Void> callback) {
if (selector != null) {
try {
Set<Integer> selectedIds = selector.getSelection();
String newPropValue = fence(selectedIds);
getConfiguration().put(new PropertySimple(PROPNAME, newPropValue));
- return true;
+ callback.onSuccess(null);
} catch (Exception e) {
CoreGUI.getErrorHandler().handleError(MSG.view_alert_definition_notification_user_editor_saveFailed(),
e);
- return false;
+ callback.onFailure(null);
}
+ } else {
+ callback.onSuccess(null);
}
- return true;
}
@SuppressWarnings("unchecked")
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/ContentGWTService.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/ContentGWTService.java
index cf80f48..27f6bad 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/ContentGWTService.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/ContentGWTService.java
@@ -31,12 +31,14 @@ import org.rhq.core.domain.content.InstalledPackageHistory;
import org.rhq.core.domain.content.Package;
import org.rhq.core.domain.content.PackageType;
import org.rhq.core.domain.content.PackageVersion;
+import org.rhq.core.domain.content.composite.PackageAndLatestVersionComposite;
import org.rhq.core.domain.criteria.PackageCriteria;
import org.rhq.core.domain.criteria.PackageVersionCriteria;
import org.rhq.core.domain.util.PageList;
/**
* @author Greg Hinkle
+ * @author Lukas Krejci
*/
public interface ContentGWTService extends RemoteService {
@@ -46,6 +48,8 @@ public interface ContentGWTService extends RemoteService {
PageList<Package> findPackagesByCriteria(PackageCriteria criteria);
+ PageList<PackageAndLatestVersionComposite> findPackagesWithLatestVersion(PackageCriteria criteria);
+
PageList<InstalledPackageHistory> getInstalledPackageHistoryForResource(int resourceId, int count);
List<Architecture> getArchitectures() throws RuntimeException;
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/SubjectGWTService.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/SubjectGWTService.java
index 379b403..3e5b360 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/SubjectGWTService.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/SubjectGWTService.java
@@ -138,4 +138,12 @@ public interface SubjectGWTService extends RemoteService {
* @return <code>true</code> if the user exists and has a {@link Principal}, <code>false</code> otherwise
*/
boolean isUserWithPrincipal(String username) throws RuntimeException;
+
+ /**
+ * Checks if the provided credentials are correct.
+ * @param username
+ * @param password
+ * @return
+ */
+ Subject checkAuthentication(String username, String password);
}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/ContentGWTServiceImpl.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/ContentGWTServiceImpl.java
index ed9baa3..6a0f3eb 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/ContentGWTServiceImpl.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/ContentGWTServiceImpl.java
@@ -29,6 +29,7 @@ import org.rhq.core.domain.content.InstalledPackageHistory;
import org.rhq.core.domain.content.Package;
import org.rhq.core.domain.content.PackageType;
import org.rhq.core.domain.content.PackageVersion;
+import org.rhq.core.domain.content.composite.PackageAndLatestVersionComposite;
import org.rhq.core.domain.criteria.PackageCriteria;
import org.rhq.core.domain.criteria.PackageVersionCriteria;
import org.rhq.core.domain.util.PageControl;
@@ -79,6 +80,15 @@ public class ContentGWTServiceImpl extends AbstractGWTServiceImpl implements Con
}
}
+ public PageList<PackageAndLatestVersionComposite> findPackagesWithLatestVersion(PackageCriteria criteria) {
+ try {
+ return SerialUtility.prepare(contentManager.findPackagesWithLatestVersion(getSessionSubject(), criteria),
+ "ContentService.findPackagesByCriteria");
+ } catch (Throwable t) {
+ throw new RuntimeException(ThrowableUtil.getAllMessages(t));
+ }
+ }
+
public PageList<InstalledPackageHistory> getInstalledPackageHistoryForResource(int resourceId, int count)
throws RuntimeException {
try {
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/SubjectGWTServiceImpl.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/SubjectGWTServiceImpl.java
index 2943b4a..303c5c3 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/SubjectGWTServiceImpl.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/SubjectGWTServiceImpl.java
@@ -134,4 +134,11 @@ public class SubjectGWTServiceImpl extends AbstractGWTServiceImpl implements Sub
}
}
+ public Subject checkAuthentication(String username, String password) {
+ try {
+ return subjectManager.checkAuthentication(username, password);
+ } catch (Throwable t) {
+ throw new RuntimeException(ThrowableUtil.getAllMessages(t));
+ }
+ }
}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/auth/SubjectManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/auth/SubjectManagerBean.java
index 8080247..b3a25c9 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/auth/SubjectManagerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/auth/SubjectManagerBean.java
@@ -181,7 +181,6 @@ public class SubjectManagerBean implements SubjectManagerLocal, SubjectManagerRe
return entityManager.merge(subjectToModify);
}
- @Override
public Subject createSubject(Subject whoami, Subject subjectToCreate, String password) throws SubjectException,
EntityExistsException {
if (getSubjectByName(subjectToCreate.getName()) != null) {
@@ -364,18 +363,8 @@ public class SubjectManagerBean implements SubjectManagerLocal, SubjectManagerRe
// get the configuration properties and use the JAAS modules to perform the login
Properties config = systemManager.getSystemConfiguration(getOverlord());
- try {
- UsernamePasswordHandler handler = new UsernamePasswordHandler(username, password.toCharArray());
- LoginContext loginContext;
- loginContext = new LoginContext(CustomJaasDeploymentServiceMBean.SECURITY_DOMAIN_NAME, handler);
-
- loginContext.login();
- loginContext.getSubject().getPrincipals().iterator().next();
- loginContext.logout();
- } catch (javax.security.auth.login.LoginException e) {
- throw new LoginException(e.getMessage());
- }
-
+ _checkAuthentication(username, password);
+
// User is authenticated!
Subject subject = getSubjectByName(username);
@@ -426,6 +415,29 @@ public class SubjectManagerBean implements SubjectManagerLocal, SubjectManagerRe
return subject;
}
+ public Subject checkAuthentication(String username, String password) {
+ try {
+ _checkAuthentication(username, password);
+ return getSubjectByName(username);
+ } catch (LoginException e) {
+ return null;
+ }
+ }
+
+ private void _checkAuthentication(String username, String password) throws LoginException {
+ try {
+ UsernamePasswordHandler handler = new UsernamePasswordHandler(username, password.toCharArray());
+ LoginContext loginContext;
+ loginContext = new LoginContext(CustomJaasDeploymentServiceMBean.SECURITY_DOMAIN_NAME, handler);
+
+ loginContext.login();
+ loginContext.getSubject().getPrincipals().iterator().next();
+ loginContext.logout();
+ } catch (javax.security.auth.login.LoginException e) {
+ throw new LoginException(e.getMessage());
+ }
+ }
+
/**This method is applied to Subject instances that may require LDAP auth/authz processing.
* Called from both SLSB and SubjectGWTServiceImpl and:
* -if Subject passed in has Principal(not LDAP account) then we immediately return Subject as no processing needed.
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/auth/SubjectManagerLocal.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/auth/SubjectManagerLocal.java
index 279d2fe..2859b48 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/auth/SubjectManagerLocal.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/auth/SubjectManagerLocal.java
@@ -188,6 +188,15 @@ public interface SubjectManagerLocal {
*/
Subject updateSubject(Subject subject, Subject subjectToModify, String newPassword);
+ /**
+ * Checks whether a user would successfully login with the provided credentials.
+ *
+ * @param username the username
+ * @param password the password
+ * @return the subject if the credentials are correct, null otherwise
+ */
+ Subject checkAuthentication(String username, String password);
+
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
//
// The following are shared with the Remote Interface
commit ebf52da3240170c8ba9cd34192a9225907cc3623
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Mon Feb 21 18:13:15 2011 +0100
throw an actual exception on notification validation failure.
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertDefinitionManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertDefinitionManagerBean.java
index ef3d733..d410486 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertDefinitionManagerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertDefinitionManagerBean.java
@@ -619,7 +619,9 @@ public class AlertDefinitionManagerBean implements AlertDefinitionManagerLocal,
}
}
- alertNotificationManager.finalizeNotifications(subject, alertDefinition.getAlertNotifications());
+ if (!alertNotificationManager.finalizeNotifications(subject, alertDefinition.getAlertNotifications())) {
+ throw new InvalidAlertDefinitionException("Some of the notifications failed to validate.");
+ }
}
private void notifyAlertConditionCacheManager(Subject subject, String methodName, AlertDefinition alertDefinition,
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertNotificationManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertNotificationManagerBean.java
index 91cfe5a..60d6b0f 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertNotificationManagerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertNotificationManagerBean.java
@@ -322,7 +322,7 @@ public class AlertNotificationManagerBean implements AlertNotificationManagerLoc
hasErrors(validation.getExtraParameters());
}
- return hasErrors;
+ return !hasErrors;
}
public int cleanseAlertNotificationBySubject(int subjectId) {
commit 3a134b1058cb1c8a5266323e3ac354d9959673a3
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Mon Feb 21 18:11:07 2011 +0100
updating the package upload mechanism to:
1) return the package id along with package version id
2) fail on uploading an existing package version
3) move constants out of *Bean so that web layer isn't tightly coupled to an SLSB impl.
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/upload/PackageVersionFileUploadForm.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/upload/PackageVersionFileUploadForm.java
index 802ffea..4085a82 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/upload/PackageVersionFileUploadForm.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/upload/PackageVersionFileUploadForm.java
@@ -38,7 +38,8 @@ public class PackageVersionFileUploadForm extends FileUploadForm {
private Integer archId;
private Integer repoId;
private int packageVersionId;
-
+ private int packageId;
+
public PackageVersionFileUploadForm(String locatorId, int packageTypeId, String packageName, String version,
Integer archId, Integer repoId, boolean showNameLabel, boolean showUploadButton, Boolean isAlreadyUploaded) {
@@ -61,6 +62,17 @@ public class PackageVersionFileUploadForm extends FileUploadForm {
return this.packageVersionId;
}
+ /**
+ * If this component successfully upload a package version file, this will return
+ * the id of the package the uploaded package version was associated with.
+ * Otherwise, 0 is returned.
+ *
+ * @return the package id of the new package version
+ */
+ public int getPackageId() {
+ return packageId;
+ }
+
public int getPackageTypeId() {
return packageTypeId;
}
@@ -117,7 +129,7 @@ public class PackageVersionFileUploadForm extends FileUploadForm {
List<FormItem> onDrawItems = super.getOnDrawItems();
HiddenItem packageTypeIdField = new HiddenItem("packageTypeId");
- packageTypeIdField.setValue(packageTypeId);
+ packageTypeIdField.setDefaultValue(packageTypeId);
onDrawItems.add(packageTypeIdField);
if (null != archId) {
@@ -136,29 +148,56 @@ public class PackageVersionFileUploadForm extends FileUploadForm {
}
protected boolean processSubmitCompleteResults(String submitCompleteEventResults) {
- packageVersionId = parseIdFromResponse(submitCompleteEventResults);
+ parseIdsFromResponse(submitCompleteEventResults);
return (packageVersionId > 0);
}
- private int parseIdFromResponse(String results) {
- String successMsgPrefix = "success ["; // the upload servlet will respond with "success [packageVersionId]" on success
+ private void parseIdsFromResponse(String results) {
+ packageVersionId = 0;
+ packageId = 0;
+
+ // the upload servlet will respond with "success [packageVersionId=x,packageId=y]" on success
+
+ String successMsgPrefix = "success [";
int startSuccessMsgPrefix = results.indexOf(successMsgPrefix);
if (startSuccessMsgPrefix < 0) {
- return 0; // must mean it wasn't a success - results is probably an error message
+ CoreGUI.getErrorHandler().handleError(MSG.view_upload_error_packageVersionFile());
+ return; // must mean it wasn't a success - results is probably an error message
}
int endSuccessMsgPrefix = startSuccessMsgPrefix + successMsgPrefix.length();
int startSuccessMsgPostfix = results.indexOf(']', endSuccessMsgPrefix);
if (startSuccessMsgPostfix < 0) {
- return 0; // this should never happen, if we have "success [" we should always have the ending "]" bracket
+ CoreGUI.getErrorHandler().handleError(MSG.view_upload_error_packageVersionFile());
+ return; // this should never happen, if we have "success [" we should always have the ending "]" bracket
}
- String packageVersionIdString = results.substring(endSuccessMsgPrefix, startSuccessMsgPostfix);
- int id = 0;
+
+ String[] ids = results.substring(endSuccessMsgPrefix, startSuccessMsgPostfix).split(",");
+ if (ids.length != 2) {
+ CoreGUI.getErrorHandler().handleError(MSG.view_upload_error_packageVersionFile());
+ return;
+ }
+
+ String packageVersionIdString = ids[0];
+ String packageIdString = ids[1];
+
try {
- id = Integer.parseInt(packageVersionIdString);
+ int equalsIdx = packageVersionIdString.indexOf('=');
+ if (equalsIdx < 0) {
+ CoreGUI.getErrorHandler().handleError(MSG.view_upload_error_packageVersionFile());
+ return;
+ }
+ packageVersionId = Integer.parseInt(packageVersionIdString.substring(equalsIdx + 1));
+
+ equalsIdx = packageIdString.indexOf('=');
+ if (equalsIdx < 0) {
+ packageVersionId = 0;
+ CoreGUI.getErrorHandler().handleError(MSG.view_upload_error_packageVersionFile());
+ return;
+ }
+ packageId = Integer.parseInt(packageIdString.substring(equalsIdx + 1));
} catch (Exception e) {
CoreGUI.getErrorHandler().handleError(MSG.view_upload_error_packageVersionFile(), e);
}
- return id;
}
@Override
@@ -186,6 +225,7 @@ public class PackageVersionFileUploadForm extends FileUploadForm {
}
setFields(newItems);
+ markForRedraw();
}
private void addField(FormItem item) {
@@ -194,5 +234,8 @@ public class PackageVersionFileUploadForm extends FileUploadForm {
System.arraycopy(items, 0, newItems, 0, items.length);
newItems[items.length] = item;
+
+ setFields(newItems);
+ markForRedraw();
}
}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/PackageVersionFileUploadServlet.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/PackageVersionFileUploadServlet.java
index c07d06e..dc89a2c 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/PackageVersionFileUploadServlet.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/PackageVersionFileUploadServlet.java
@@ -23,6 +23,7 @@ import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
+import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
@@ -43,6 +44,7 @@ import org.rhq.enterprise.server.util.LookupUtil;
*
* @author Jay Shaughnessy
* @author John Mazzitelli
+ * @author Lukas Krejci
*/
public class PackageVersionFileUploadServlet extends FileUploadServlet {
private static final long serialVersionUID = 1L;
@@ -74,15 +76,24 @@ public class PackageVersionFileUploadServlet extends FileUploadServlet {
InputStream fileStream = new FileInputStream(file);
- PackageVersion packageVersion = contentManager.createPackageVersion(packageName, packageTypeId, version,
- architectureId, fileStream);
+ //use getUploadedPackageVersion instead of createPackageVersion here
+ //because createPackageVersion successfully returns an already existing
+ //package version with the provided "location". This is not what we want
+ //here since we want to make sure that the uploaded file actually gets
+ //persisted.
+ Map<String, String> metaData = new HashMap<String, String>();
+ metaData.put(ContentManagerLocal.UPLOAD_FILE_INSTALL_DATE, Long.toString(file.lastModified()));
+ metaData.put(ContentManagerLocal.UPLOAD_FILE_NAME, files.keySet().iterator().next());
+ PackageVersion packageVersion = contentManager.getUploadedPackageVersion(packageName, packageTypeId,
+ version, architectureId, fileStream, metaData, null);
if (repoId != null) {
+ //XXX create a new SLSB method that would combine this and the above call in one transaction?
RepoManagerLocal repoManager = LookupUtil.getRepoManagerLocal();
repoManager.addPackageVersionsToRepo(subject, repoId, new int[] { packageVersion.getId() });
}
- successMsg = "success [" + packageVersion.getId() + "]";
+ successMsg = "success [packageVersionId=" + packageVersion.getId() + ",packageId=" + packageVersion.getGeneralPackage().getId() + "]";
} catch (Exception e) {
writeExceptionResponse(response, "Failed to upload file", e); // clients will look for this string!
return;
diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/content/CreateNewPackageUIBean.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/content/CreateNewPackageUIBean.java
index 35a70a7..4a90c20 100644
--- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/content/CreateNewPackageUIBean.java
+++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/content/CreateNewPackageUIBean.java
@@ -51,7 +51,6 @@ import org.rhq.core.util.MessageDigestGenerator;
import org.rhq.core.util.exception.ThrowableUtil;
import org.rhq.enterprise.gui.util.EnterpriseFacesContextUtility;
import org.rhq.enterprise.server.content.ContentException;
-import org.rhq.enterprise.server.content.ContentManagerBean;
import org.rhq.enterprise.server.content.ContentManagerLocal;
import org.rhq.enterprise.server.content.ContentUIManagerLocal;
import org.rhq.enterprise.server.content.RepoManagerLocal;
@@ -229,16 +228,16 @@ public class CreateNewPackageUIBean {
//store information about uploaded file for packageDetails as most of it is already available
Map<String, String> packageUploadDetails = new HashMap<String, String>();
- packageUploadDetails.put(ContentManagerBean.UPLOAD_FILE_SIZE, String.valueOf(fileItem.getFileSize()));
- packageUploadDetails.put(ContentManagerBean.UPLOAD_FILE_INSTALL_DATE, String.valueOf(System
+ packageUploadDetails.put(ContentManagerLocal.UPLOAD_FILE_SIZE, String.valueOf(fileItem.getFileSize()));
+ packageUploadDetails.put(ContentManagerLocal.UPLOAD_FILE_INSTALL_DATE, String.valueOf(System
.currentTimeMillis()));
- packageUploadDetails.put(ContentManagerBean.UPLOAD_OWNER, subject.getName());
- packageUploadDetails.put(ContentManagerBean.UPLOAD_FILE_NAME, fileItem.getFileName());
+ packageUploadDetails.put(ContentManagerLocal.UPLOAD_OWNER, subject.getName());
+ packageUploadDetails.put(ContentManagerLocal.UPLOAD_FILE_NAME, fileItem.getFileName());
try {//Easier to implement here than in server side bean. Shouldn't affect performance too much.
- packageUploadDetails.put(ContentManagerBean.UPLOAD_MD5, new MessageDigestGenerator(
+ packageUploadDetails.put(ContentManagerLocal.UPLOAD_MD5, new MessageDigestGenerator(
MessageDigestGenerator.MD5).calcDigestString(fileItem.getFile()));
- packageUploadDetails.put(ContentManagerBean.UPLOAD_SHA256, new MessageDigestGenerator(
+ packageUploadDetails.put(ContentManagerLocal.UPLOAD_SHA256, new MessageDigestGenerator(
MessageDigestGenerator.SHA_256).calcDigestString(fileItem.getFile()));
} catch (IOException e1) {
log.warn("Error calculating file digest(s) : " + e1.getMessage());
diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/inventory/resource/CreateNewPackageChildResourceUIBean.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/inventory/resource/CreateNewPackageChildResourceUIBean.java
index 645ebe7..904eb48 100644
--- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/inventory/resource/CreateNewPackageChildResourceUIBean.java
+++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/inventory/resource/CreateNewPackageChildResourceUIBean.java
@@ -54,7 +54,6 @@ import org.rhq.core.util.exception.ThrowableUtil;
import org.rhq.enterprise.gui.legacy.ParamConstants;
import org.rhq.enterprise.gui.util.EnterpriseFacesContextUtility;
import org.rhq.enterprise.server.configuration.ConfigurationManagerLocal;
-import org.rhq.enterprise.server.content.ContentManagerBean;
import org.rhq.enterprise.server.content.ContentManagerLocal;
import org.rhq.enterprise.server.content.ContentUIManagerLocal;
import org.rhq.enterprise.server.resource.ResourceFactoryManagerLocal;
@@ -120,16 +119,16 @@ public class CreateNewPackageChildResourceUIBean {
//store information about uploaded file for packageDetails as most of it is already available
Map<String, String> packageUploadDetails = new HashMap<String, String>();
- packageUploadDetails.put(ContentManagerBean.UPLOAD_FILE_SIZE, String.valueOf(fileItem.getFileSize()));
- packageUploadDetails.put(ContentManagerBean.UPLOAD_FILE_INSTALL_DATE, String
+ packageUploadDetails.put(ContentManagerLocal.UPLOAD_FILE_SIZE, String.valueOf(fileItem.getFileSize()));
+ packageUploadDetails.put(ContentManagerLocal.UPLOAD_FILE_INSTALL_DATE, String
.valueOf(System.currentTimeMillis()));
- packageUploadDetails.put(ContentManagerBean.UPLOAD_OWNER, user.getName());
- packageUploadDetails.put(ContentManagerBean.UPLOAD_FILE_NAME, fileItem.getFileName());
+ packageUploadDetails.put(ContentManagerLocal.UPLOAD_OWNER, user.getName());
+ packageUploadDetails.put(ContentManagerLocal.UPLOAD_FILE_NAME, fileItem.getFileName());
try {//Easier to implement here than in server side bean. Shouldn't affect performance too much.
- packageUploadDetails.put(ContentManagerBean.UPLOAD_MD5, new MessageDigestGenerator(
+ packageUploadDetails.put(ContentManagerLocal.UPLOAD_MD5, new MessageDigestGenerator(
MessageDigestGenerator.MD5).calcDigestString(fileItem.getFile()));
- packageUploadDetails.put(ContentManagerBean.UPLOAD_SHA256, new MessageDigestGenerator(
+ packageUploadDetails.put(ContentManagerLocal.UPLOAD_SHA256, new MessageDigestGenerator(
MessageDigestGenerator.SHA_256).calcDigestString(fileItem.getFile()));
} catch (IOException e1) {
log.warn("Error calculating file digest(s) : " + e1.getMessage());
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerBean.java
index 486e997..4735ed8 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerBean.java
@@ -122,15 +122,6 @@ public class ContentManagerBean implements ContentManagerLocal, ContentManagerRe
*/
private static final int REQUEST_TIMEOUT = 1000 * 60 * 60;
- public static final String UPLOAD_FILE_SIZE = "fileSize";
- public static final String UPLOAD_FILE_INSTALL_DATE = "fileInstallDate";
- public static final String UPLOAD_OWNER = "owner";
- public static final String UPLOAD_FILE_NAME = "fileName";
- public static final String UPLOAD_MD5 = "md5";
- public static final String UPLOAD_SHA256 = "sha256";
-
- // Attributes --------------------------------------------
-
private final Log log = LogFactory.getLog(this.getClass());
@PersistenceContext(unitName = RHQConstants.PERSISTENCE_UNIT_NAME)
@@ -1271,7 +1262,8 @@ public class ContentManagerBean implements ContentManagerLocal, ContentManagerRe
PackageVersion newPackageVersion = new PackageVersion(existingPackage, version, architecture);
newPackageVersion.setDisplayName(existingPackage.getName());
- entityManager.persist(newPackageVersion);
+
+ newPackageVersion = persistOrMergePackageVersionSafely(newPackageVersion);
Map<String, String> contentDetails = new HashMap<String, String>();
PackageBits bits = loadPackageBits(packageBitStream, newPackageVersion.getId(), packageName, version, null,
@@ -1280,8 +1272,7 @@ public class ContentManagerBean implements ContentManagerLocal, ContentManagerRe
newPackageVersion.setPackageBits(bits);
newPackageVersion.setFileSize(Long.valueOf(contentDetails.get(UPLOAD_FILE_SIZE)).longValue());
newPackageVersion.setSHA256(contentDetails.get(UPLOAD_SHA256));
- newPackageVersion = persistOrMergePackageVersionSafely(newPackageVersion);
-
+
existingPackage.addVersion(newPackageVersion);
return newPackageVersion;
@@ -1643,18 +1634,20 @@ public class ContentManagerBean implements ContentManagerLocal, ContentManagerRe
}
//get the data
- PackageBits bits = loadPackageBits(packageBitStream, packageVersion.getId(), packageName, version, null, null);
+ Map<String, String> contentDetails = new HashMap<String, String>();
+ PackageBits bits = loadPackageBits(packageBitStream, packageVersion.getId(), packageName, version, null, contentDetails);
packageVersion.setPackageBits(bits);
+ packageVersion.setFileSize(Long.valueOf(contentDetails.get(UPLOAD_FILE_SIZE)).longValue());
+ packageVersion.setSHA256(contentDetails.get(UPLOAD_SHA256));
+
//populate extra details, persist
if (packageUploadDetails != null) {
packageVersion.setFileCreatedDate(Long.valueOf(packageUploadDetails
- .get(ContentManagerBean.UPLOAD_FILE_INSTALL_DATE)));
- packageVersion.setFileName(packageUploadDetails.get(ContentManagerBean.UPLOAD_FILE_NAME));
- packageVersion.setFileSize(Long.valueOf(packageUploadDetails.get(ContentManagerBean.UPLOAD_FILE_SIZE)));
- packageVersion.setMD5(packageUploadDetails.get(ContentManagerBean.UPLOAD_MD5));
- packageVersion.setSHA256(packageUploadDetails.get(ContentManagerBean.UPLOAD_SHA256));
+ .get(ContentManagerLocal.UPLOAD_FILE_INSTALL_DATE)));
+ packageVersion.setFileName(packageUploadDetails.get(ContentManagerLocal.UPLOAD_FILE_NAME));
+ packageVersion.setMD5(packageUploadDetails.get(ContentManagerLocal.UPLOAD_MD5));
}
entityManager.merge(packageVersion);
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerLocal.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerLocal.java
index ce6540d..5212a98 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerLocal.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerLocal.java
@@ -37,6 +37,7 @@ import org.rhq.core.domain.content.PackageBits;
import org.rhq.core.domain.content.PackageDetailsKey;
import org.rhq.core.domain.content.PackageType;
import org.rhq.core.domain.content.PackageVersion;
+import org.rhq.core.domain.content.composite.PackageAndLatestVersionComposite;
import org.rhq.core.domain.content.transfer.DeployPackageStep;
import org.rhq.core.domain.content.transfer.DeployPackagesResponse;
import org.rhq.core.domain.content.transfer.RemovePackagesResponse;
@@ -58,6 +59,29 @@ public interface ContentManagerLocal {
// Use case logic --------------------------------------------
/**
+ * This is currently ignored as the file size is computed
+ * upon persist.
+ */
+ public static final String UPLOAD_FILE_SIZE = "fileSize";
+
+ public static final String UPLOAD_FILE_INSTALL_DATE = "fileInstallDate";
+
+ /**
+ * This doesn't seem to serve any purpose.
+ */
+ public static final String UPLOAD_OWNER = "owner";
+
+ public static final String UPLOAD_FILE_NAME = "fileName";
+
+ public static final String UPLOAD_MD5 = "md5";
+
+ /**
+ * This is currently ignored as the SHA is computed upon
+ * persist.
+ */
+ public static final String UPLOAD_SHA256 = "sha256";
+
+ /**
* Deploys a package on the specified resource. Each installed package entry should be populated with the <code>
* PackageVersion</code> being installed, along with the deployment configuration values if any. This method will
* take care of populating the rest of the values in each installed package object.
@@ -314,6 +338,7 @@ public interface ContentManagerLocal {
*/
PackageType getResourceCreationPackageType(int resourceTypeId);
+
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
//
// The following are shared with the Remote Interface
commit b9b30c2e13358c76b2df9912c655e3c0d6436865
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Mon Feb 21 18:06:07 2011 +0100
adding support for querying packages together with their latest versions.
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/content/composite/PackageAndLatestVersionComposite.java b/modules/core/domain/src/main/java/org/rhq/core/domain/content/composite/PackageAndLatestVersionComposite.java
new file mode 100644
index 0000000..5c7c88f
--- /dev/null
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/content/composite/PackageAndLatestVersionComposite.java
@@ -0,0 +1,81 @@
+/*
+ * 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 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.core.domain.content.composite;
+
+import java.io.Serializable;
+
+import org.rhq.core.domain.content.Package;
+import org.rhq.core.domain.content.PackageVersion;
+
+/**
+ * This composite holds a general package together with a package version that is found
+ * to be the "latest" using the version comparison.
+ *
+ * @author Lukas Krejci
+ */
+public class PackageAndLatestVersionComposite implements Serializable {
+
+
+ private static final long serialVersionUID = 1L;
+
+ private Package generalPackage;
+ private PackageVersion latestPackageVersion;
+
+ public PackageAndLatestVersionComposite() {
+
+ }
+
+ public PackageAndLatestVersionComposite(Package generalPackage) {
+ this.generalPackage = generalPackage;
+ }
+
+ public PackageAndLatestVersionComposite(Package generalPakcage, PackageVersion packageVersion) {
+ this.generalPackage = generalPakcage;
+ this.latestPackageVersion = packageVersion;
+ }
+
+ /**
+ * @return the generalPackage
+ */
+ public Package getGeneralPackage() {
+ return generalPackage;
+ }
+
+ /**
+ * @param generalPackage the generalPackage to set
+ */
+ public void setGeneralPackage(Package generalPackage) {
+ this.generalPackage = generalPackage;
+ }
+
+ /**
+ * @return the latestPackageVersion
+ */
+ public PackageVersion getLatestPackageVersion() {
+ return latestPackageVersion;
+ }
+
+ /**
+ * @param latestPackageVersion the latestPackageVersion to set
+ */
+ public void setLatestPackageVersion(PackageVersion latestPackageVersion) {
+ this.latestPackageVersion = latestPackageVersion;
+ }
+}
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/PackageCriteria.java b/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/PackageCriteria.java
index d358cb1..306ce0a 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/PackageCriteria.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/PackageCriteria.java
@@ -77,6 +77,10 @@ public class PackageCriteria extends Criteria {
this.filterRepoId = repoId;
}
+ public Integer getFilterRepoId() {
+ return filterRepoId;
+ }
+
public void fetchVersions(boolean fetchVersions) {
this.fetchVersions = fetchVersions;
}
@@ -85,8 +89,4 @@ public class PackageCriteria extends Criteria {
addSortField("name");
this.sortName = sort;
}
-
- public boolean isInventoryManagerRequired() {
- return fetchVersions;
- }
}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerBean.java
index a5209bc..486e997 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerBean.java
@@ -77,6 +77,7 @@ import org.rhq.core.domain.content.PackageDetailsKey;
import org.rhq.core.domain.content.PackageInstallationStep;
import org.rhq.core.domain.content.PackageType;
import org.rhq.core.domain.content.PackageVersion;
+import org.rhq.core.domain.content.composite.PackageAndLatestVersionComposite;
import org.rhq.core.domain.content.transfer.ContentResponseResult;
import org.rhq.core.domain.content.transfer.DeployIndividualPackageResponse;
import org.rhq.core.domain.content.transfer.DeployPackageStep;
@@ -149,6 +150,10 @@ public class ContentManagerBean implements ContentManagerLocal, ContentManagerRe
@EJB
private ResourceTypeManagerLocal resourceTypeManager;
+
+ @EJB
+ private RepoManagerLocal repoManager;
+
// ContentManagerLocal Implementation --------------------------------------------
@@ -1517,9 +1522,12 @@ public class ContentManagerBean implements ContentManagerLocal, ContentManagerRe
public PageList<Package> findPackagesByCriteria(Subject subject, PackageCriteria criteria) {
- if (criteria.isInventoryManagerRequired() && !authorizationManager.isInventoryManager(subject)) {
- throw new PermissionException("Subject [" + subject.getName()
- + "] is required to have InventoryManager permission for requested query criteria.");
+ if (criteria.getFilterRepoId() != null) {
+ if (!authorizationManager.canViewRepo(subject, criteria.getFilterRepoId())) {
+ throw new PermissionException("Subject [" + subject.getName() + "] cannot view the repo with id " + criteria.getFilterRepoId());
+ }
+ } else if (!authorizationManager.hasGlobalPermission(subject, Permission.MANAGE_REPOSITORIES)) {
+ throw new PermissionException("Only repository managers can search for packages across all repos.");
}
CriteriaQueryGenerator generator = new CriteriaQueryGenerator(subject, criteria);
@@ -1529,6 +1537,24 @@ public class ContentManagerBean implements ContentManagerLocal, ContentManagerRe
return runner.execute();
}
+ public PageList<PackageAndLatestVersionComposite> findPackagesWithLatestVersion(Subject subject, PackageCriteria criteria) {
+ if (criteria.getFilterRepoId() == null) {
+ throw new IllegalArgumentException("The criteria query has to have a filter for a specific repo.");
+ }
+
+ criteria.fetchVersions(true);
+ PageList<Package> packages = findPackagesByCriteria(subject, criteria);
+
+ PageList<PackageAndLatestVersionComposite> ret = new PageList<PackageAndLatestVersionComposite>(packages.getTotalSize(), packages.getPageControl());
+
+ for(Package p : packages) {
+ PackageVersion latest = repoManager.getLatestPackageVersion(subject, p.getId(), criteria.getFilterRepoId());
+ ret.add(new PackageAndLatestVersionComposite(p, latest));
+ }
+
+ return ret;
+ }
+
public InstalledPackage getBackingPackageForResource(Subject subject, int resourceId) {
InstalledPackage result = null;
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerLocal.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerLocal.java
index 1840fc6..ce6540d 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerLocal.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerLocal.java
@@ -214,6 +214,22 @@ public interface ContentManagerLocal {
PackageVersion createPackageVersion(String packageName, int packageTypeId, String version, int architectureId,
InputStream packageBitStream);
+ /**
+ * This method is similar to the {@link #createPackageVersion(String, int, String, int, InputStream)} but fails if
+ * the package version with the provided details already exists which is a desired behaviour for the GUI originating
+ * requests.
+ *
+ * @param packageName the name of the package (the general package will be created if none exists)
+ * @param packageTypeId the id of the package type. This is ignored if the <code>newResourceTypeId</code> is not null
+ * @param version the version of the package version being created
+ * @param architectureId the architecture of the package version
+ * @param packageBitStream the input stream with the package bits
+ * @param packageUploadDetails additional details about the package. See the constants defined in this interface
+ * @param newResourceTypeId the resource type id the package version should be bound to. This is to support the usecase
+ * where a package version is being created as the backing content of a resource.
+ *
+ * @return the newly create package version
+ */
PackageVersion getUploadedPackageVersion(String packageName, int packageTypeId, String version, int architectureId,
InputStream packageBitStream, Map<String, String> packageUploadDetails, Integer newResourceTypeId);
@@ -357,6 +373,11 @@ public interface ContentManagerLocal {
PageList<Package> findPackagesByCriteria(Subject subject, PackageCriteria criteria);
/**
+ * @see ContentManagerRemote#findPackagesWithLatestVersion(Subject, PackageCriteria)
+ */
+ PageList<PackageAndLatestVersionComposite> findPackagesWithLatestVersion(Subject subject, PackageCriteria criteria);
+
+ /**
* @see {@link ContentManagerRemote#getBackingPackageForResource(Subject, int)
*/
InstalledPackage getBackingPackageForResource(Subject subject, int resourceId);
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerRemote.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerRemote.java
index 0a5614a..261accf 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerRemote.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerRemote.java
@@ -32,6 +32,7 @@ import org.rhq.core.domain.content.InstalledPackage;
import org.rhq.core.domain.content.Package;
import org.rhq.core.domain.content.PackageType;
import org.rhq.core.domain.content.PackageVersion;
+import org.rhq.core.domain.content.composite.PackageAndLatestVersionComposite;
import org.rhq.core.domain.criteria.InstalledPackageCriteria;
import org.rhq.core.domain.criteria.PackageCriteria;
import org.rhq.core.domain.criteria.PackageVersionCriteria;
@@ -182,11 +183,9 @@ public interface ContentManagerRemote {
@WebParam(name = "criteria") PackageVersionCriteria criteria);
/**
- * This method requires InventoryManager permissions if the criteria is set up to fetch the package
- * versions via {@link PackageCriteria#fetchVersions(boolean)}. There are no privileges required
- * if only a list of packages without their associated package versions is requested.
- * <p>
- * TODO the privileges need to be worked out for this...
+ * If the criteria object filters on repo id, the subject needs to be able to
+ * access that repo. If there is no filter on repos, the subject needs to have
+ * MANAGE_REPOSITORIES permission.
*
* @param subject
* @param criteria
@@ -198,6 +197,22 @@ public interface ContentManagerRemote {
@WebParam(name = "criteria") PackageCriteria criteria);
/**
+ * Akin to {@link #findPackagesByCriteria(Subject, PackageCriteria)} but also
+ * determines the latest version of the returned packages.
+ * <p>
+ * The provided criteria has to be limited to a specific repo using {@link PackageCriteria#addFilterRepoId(Integer)}.
+ *
+ * @param subject
+ * @param criteria
+ * @return
+ * @throws IllegalArgumentException if the criteria doesn't define a repo filter
+ */
+ @WebMethod
+ PageList<PackageAndLatestVersionComposite> findPackagesWithLatestVersion(
+ @WebParam(name = "subject") Subject subject,
+ @WebParam(name = "criteria") PackageCriteria criteria);
+
+ /**
* For a resource that is content-backed (aka package-backed), this call will return InstalledPackage information
* for the backing content (package).
*
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/webservices/WebservicesManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/webservices/WebservicesManagerBean.java
index b1c3109..2ee417c 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/webservices/WebservicesManagerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/webservices/WebservicesManagerBean.java
@@ -67,6 +67,7 @@ import org.rhq.core.domain.content.Package;
import org.rhq.core.domain.content.PackageType;
import org.rhq.core.domain.content.PackageVersion;
import org.rhq.core.domain.content.Repo;
+import org.rhq.core.domain.content.composite.PackageAndLatestVersionComposite;
import org.rhq.core.domain.content.transfer.SubscribedRepo;
import org.rhq.core.domain.criteria.AlertCriteria;
import org.rhq.core.domain.criteria.AlertDefinitionCriteria;
@@ -528,6 +529,12 @@ public class WebservicesManagerBean implements WebservicesRemote {
checkParametersPassedIn(subject, criteria);
return contentManager.findPackagesByCriteria(subject, criteria);
}
+
+ public PageList<PackageAndLatestVersionComposite> findPackagesWithLatestVersion(Subject subject,
+ PackageCriteria criteria) {
+ checkParametersPassedIn(subject, criteria);
+ return contentManager.findPackagesWithLatestVersion(subject, criteria);
+ }
//CONTENTMANAGER: END ----------------------------------
commit 0416a770aa9dd008abc8536547304236f628b06a
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Mon Feb 21 18:00:40 2011 +0100
added configuration support for MANAGE_REPOSITORIES permission in the role editor.
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/roles/PermissionsEditor.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/roles/PermissionsEditor.java
index 9300960..70bf059 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/roles/PermissionsEditor.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/roles/PermissionsEditor.java
@@ -176,6 +176,11 @@ public class PermissionsEditor extends LocatableVStack {
MSG.view_adminRoles_permissions_permDesc_manageBundles());
records.add(record);
+ record = createGlobalPermissionRecord(MSG.view_adminRoles_permissions_perm_manageRepositories(),
+ "subsystems/content/Content", Permission.MANAGE_REPOSITORIES,
+ MSG.view_adminRoles_permissions_permDesc_manageRepositories());
+ records.add(record);
+
grid.setData(records.toArray(new ListGridRecord[records.size()]));
return grid;
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 02e613d..b30a0ca 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
@@ -578,6 +578,8 @@ view_adminRoles_permissions_perm_manageSettings = Manage Settings
view_adminRoles_permissions_permDesc_manageSettings = can modify the RHQ Server configuration and perform any Server-related functionality
view_adminRoles_permissions_perm_manageBundles = Manage Bundles
view_adminRoles_permissions_permDesc_manageBundles = can create, update, or delete provisioning bundles (viewing is implied for everyone)
+view_adminRoles_permissions_perm_manageRepositories = Manage Repositories
+view_adminRoles_permissions_permDesc_manageRepositories = can create, update, or delete repositories of any user (everyone can create their own repositories), can associate content sources to repositories.
view_adminRoles_permissions_perm_inventory = Inventory
view_adminRoles_permissions_permReadDesc_inventory = (IMPLIED) view Resource properties (name, description, version, etc.), connection settings, and connection settings history
view_adminRoles_permissions_permWriteDesc_inventory = update Resource name, version, description, and connection settings; delete connection settings history items
commit f312a2aec7a8353b42ba242a468d6c8bb6628563
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Mon Feb 21 17:58:53 2011 +0100
added validation support to the cli alert sender.
diff --git a/modules/enterprise/server/plugins/alert-cli/src/main/java/org/rhq/enterprise/server/plugins/alertCli/CliSender.java b/modules/enterprise/server/plugins/alert-cli/src/main/java/org/rhq/enterprise/server/plugins/alertCli/CliSender.java
index ce5579b..1e78f8d 100644
--- a/modules/enterprise/server/plugins/alert-cli/src/main/java/org/rhq/enterprise/server/plugins/alertCli/CliSender.java
+++ b/modules/enterprise/server/plugins/alert-cli/src/main/java/org/rhq/enterprise/server/plugins/alertCli/CliSender.java
@@ -54,6 +54,7 @@ import org.rhq.core.domain.content.Repo;
import org.rhq.core.domain.criteria.RepoCriteria;
import org.rhq.core.util.exception.ThrowableUtil;
import org.rhq.enterprise.client.LocalClient;
+import org.rhq.enterprise.server.auth.SubjectManagerLocal;
import org.rhq.enterprise.server.content.ContentSourceManagerLocal;
import org.rhq.enterprise.server.content.RepoManagerLocal;
import org.rhq.enterprise.server.plugin.pc.ServerPluginComponent;
@@ -71,12 +72,16 @@ public class CliSender extends AlertSender<CliComponent> {
public static final String PROP_PACKAGE_ID = "packageId";
public static final String PROP_REPO_ID = "repoId";
public static final String PROP_USER_ID = "userId";
+ public static final String PROP_USER_NAME = "userName";
+ public static final String PROP_USER_PASSWORD = "userPassword";
private static final Log LOG = LogFactory.getLog(CliSender.class);
private static final String SUMMARY_TEMPLATE = "Ran script $packageName in version $packageVersion from repo $repoName as user $userName.";
private static final String PREVIEW_TEMPLATE = "Run script $packageName from repo $repoName as user $userName.";
+ private static final String VALIDATION_ERROR_MESSAGE = "The provided user failed to authenticate.";
+
/**
* Simple strongly typed representation of the alert configuration
*/
@@ -173,8 +178,39 @@ public class CliSender extends AlertSender<CliComponent> {
@Override
public AlertSenderValidationResults validateAndFinalizeConfiguration(Subject subject) {
- // TODO Auto-generated method stub
- return super.validateAndFinalizeConfiguration(subject);
+ AlertSenderValidationResults results = new AlertSenderValidationResults(alertParameters, extraParameters);
+
+ String userIdString = alertParameters.getSimpleValue(PROP_USER_ID, null);
+ String userName = alertParameters.getSimpleValue(PROP_USER_NAME, null);
+ String userPassword = alertParameters.getSimpleValue(PROP_USER_PASSWORD, null);
+
+ Integer userId = userIdString == null ? null : Integer.valueOf(userIdString);
+
+ if (userId == null || userId != subject.getId()) {
+ SubjectManagerLocal subjectManager = LookupUtil.getSubjectManager();
+
+ Subject authSubject = subjectManager.checkAuthentication(userName, userPassword);
+
+ if (authSubject == null) {
+ PropertySimple userNameProp = new PropertySimple(PROP_USER_NAME, userName);
+ userNameProp.setErrorMessage(VALIDATION_ERROR_MESSAGE);
+ alertParameters.put(userNameProp);
+ alertParameters.put(new PropertySimple(PROP_USER_ID, null));
+ } else {
+ //make sure we store the id of the user that actually authenticated to prevent
+ //security breaches.
+ alertParameters.put(new PropertySimple(PROP_USER_ID, authSubject.getId()));
+ }
+ } else {
+ //make sure to store the username of the user... not that it is functionally
+ //required but prevent confusions in case of debugging some errorneous situation
+ alertParameters.put(new PropertySimple(PROP_USER_NAME, subject.getName()));
+ }
+
+ //do not store the password in the database ever
+ alertParameters.put(new PropertySimple(PROP_USER_PASSWORD, null));
+
+ return results;
}
private static ScriptEngine getScriptEngine(Alert alert, OutputStream scriptOutput, Config config) throws ScriptException,
@@ -250,7 +286,7 @@ public class CliSender extends AlertSender<CliComponent> {
PackageVersion versionToUse = rm.getLatestPackageVersion(overlord, config.packageId, config.repoId);
ret = ret.replace("$packageName", versionToUse.getDisplayName());
- ret = ret.replace("$pacakgeVersion", versionToUse.getDisplayVersion() == null ? versionToUse.getVersion()
+ ret = ret.replace("$packageVersion", versionToUse.getDisplayVersion() == null ? versionToUse.getVersion()
: versionToUse.getDisplayVersion());
RepoCriteria criteria = new RepoCriteria();
commit 1f55fa60dee096cce8d910fc6b79c110f2fb8844
Merge: 8f2270e... 3c32f34...
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Fri Feb 18 13:26:25 2011 +0100
Merge branch 'master' into cli-alert-notifs
diff --cc modules/core/domain/src/main/java/org/rhq/core/domain/resource/composite/DisambiguationReport.java
index dd8e6ad,f1cb2e8..66d744c
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/resource/composite/DisambiguationReport.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/resource/composite/DisambiguationReport.java
@@@ -171,17 -161,21 +171,28 @@@ public class DisambiguationReport<T> im
/**
*
* @return the Resource name
+ *
+ * @deprecated use {@link #getResource()}.{@link Resource#getName() getName()}
*/
+ @Deprecated
public String getName() {
- return name;
+ return resource.getName();
}
+ /**
+ *
+ * @return the Resource id
++ *
++ * @deprecated use {@link #getResource()}.{@link Resource#getId() getId()}
+ */
++ @Deprecated
+ public int getId() {
- return id;
++ return resource.getId();
+ }
+
public String toString() {
- return "DisambiguationReport(type=" + resourceType + ", parents=" + parents + ", original=" + original
- + ", name=" + name + ", id=" + id + ")";
+ return "DisambiguationReport(resource=" + resource + ", parents=" + parents + ", original=" + original
+ + ")";
}
+
}
diff --cc modules/enterprise/remoting/cli/src/main/java/org/rhq/enterprise/client/commands/LoginCommand.java
index 95b1a8f,d8344ff..f4c3ebb
--- a/modules/enterprise/remoting/cli/src/main/java/org/rhq/enterprise/client/commands/LoginCommand.java
+++ b/modules/enterprise/remoting/cli/src/main/java/org/rhq/enterprise/client/commands/LoginCommand.java
@@@ -25,9 -25,8 +25,11 @@@ import org.apache.commons.logging.Log
import org.apache.commons.logging.LogFactory;
import org.rhq.core.domain.auth.Subject;
++import org.rhq.core.domain.common.ProductInfo;
++import org.rhq.core.domain.common.ServerDetails;
import org.rhq.enterprise.client.ClientMain;
import org.rhq.enterprise.client.RemoteClient;
+import org.rhq.enterprise.server.system.ServerVersion;
/**
* @author Greg Hinkle
@@@ -104,8 -103,6 +106,11 @@@ public class LoginCommand implements Cl
client.setPass(password);
Subject subject = remoteClient.login(username, password);
- ServerVersion version = remoteClient.getSystemManager().getServerVersion(subject);
++
++ ProductInfo info = remoteClient.getSystemManager().getServerDetails(subject).getProductInfo();
++ String version = info.getVersion()
++ + " (" + info.getBuildNumber() + ")";
+ client.getPrintWriter().println("Remote server version is: " + version);
client.setRemoteClient(remoteClient);
client.setSubject(subject);
diff --cc modules/enterprise/remoting/client-api/src/main/java/org/rhq/enterprise/client/RemoteClient.java
index ddd8f94,bef4bd5..b15c9f1
--- a/modules/enterprise/remoting/client-api/src/main/java/org/rhq/enterprise/client/RemoteClient.java
+++ b/modules/enterprise/remoting/client-api/src/main/java/org/rhq/enterprise/client/RemoteClient.java
@@@ -30,9 -27,8 +30,10 @@@ import org.jboss.remoting.InvokerLocato
import org.jboss.remoting.security.SSLSocketBuilder;
import org.jboss.remoting.transport.http.ssl.HTTPSClientInvoker;
+import org.rhq.bindings.client.RhqFacade;
+import org.rhq.bindings.client.RhqManagers;
import org.rhq.core.domain.auth.Subject;
+ import org.rhq.core.domain.common.ServerDetails;
import org.rhq.enterprise.communications.util.SecurityUtil;
import org.rhq.enterprise.server.alert.AlertDefinitionManagerRemote;
import org.rhq.enterprise.server.alert.AlertManagerRemote;
@@@ -139,11 -184,14 +139,9 @@@ public class RemoteClient implements Rh
logout();
doConnect();
- this.subject = getSubjectManagerRemote().login(user, password);
+ this.subject = getSubjectManager().login(user, password);
this.loggedIn = true;
- ServerVersion version = getSystemManager().getServerVersion(this.subject);
-
- ServerDetails details = getSystemManagerRemote().getServerDetails(this.subject);
- // TODO: what to do with this?
- System.out.println("Remote server version is: " + details.getProductInfo().getVersion() + " ("
- + details.getProductInfo().getBuildNumber() + ")");
-
return this.subject;
}
diff --cc modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/webservices/WebservicesManagerBean.java
index 60fb16c,1169bd1..b1c3109
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/webservices/WebservicesManagerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/webservices/WebservicesManagerBean.java
@@@ -25,9 -25,9 +25,10 @@@ package org.rhq.enterprise.server.webse
import java.io.File;
import java.io.InputStream;
import java.net.URL;
+import java.util.Comparator;
import java.util.List;
import java.util.Map;
+ import java.util.Properties;
import java.util.Set;
import javax.ejb.Stateless;
commit 8f2270e9bcd8087e0b7ed59db8485dbca77ba58a
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Fri Feb 18 10:44:21 2011 +0100
beefing up the exporter a bit so that it can be used from within the scripts more comfortably (the API hasn't changed).
diff --git a/modules/enterprise/binding/src/main/java/org/rhq/bindings/export/Exporter.java b/modules/enterprise/binding/src/main/java/org/rhq/bindings/export/Exporter.java
index 0e39b54..f37d924 100644
--- a/modules/enterprise/binding/src/main/java/org/rhq/bindings/export/Exporter.java
+++ b/modules/enterprise/binding/src/main/java/org/rhq/bindings/export/Exporter.java
@@ -31,49 +31,52 @@ import java.io.PrintWriter;
public class Exporter {
- private String format;
+ private String format = "raw";
private String file;
+ private int pageWidth = 160;
+
private TabularWriter tabularWriter;
- private FileWriter fileWriter;
+ private PrintWriter fileWriter;
+
+ private boolean newWriterNeeded;
public void setTarget(String format, String file) {
- try {
- this.format = format;
- this.file = file;
- fileWriter = new FileWriter(this.file);
- tabularWriter = new TabularWriter(new PrintWriter(fileWriter), format);
- tabularWriter.setExportMode(true);
- } catch (IOException e) {
- throw new ExportException(e);
- }
+ setFormat(format);
+ setFile(file);
+ initWriter();
}
public int getPageWidth() {
- return tabularWriter.getWidth();
+ return pageWidth;
}
public void setPageWidth(int width) {
- tabularWriter.setWidth(width);
+ pageWidth = width;
}
public void write(Object object) {
- try {
- tabularWriter.print(object);
- fileWriter.flush();
- } catch (IOException e) {
- throw new ExportException(e);
- }
+ initWriter();
+ tabularWriter.print(object);
+ fileWriter.flush();
}
+ public void close() {
+ if (fileWriter != null) {
+ fileWriter.close();
+ newWriterNeeded = true;
+ }
+ }
+
public String getFormat() {
return format;
}
public void setFormat(String format) {
this.format = format;
+ newWriterNeeded = true;
}
public String getFile() {
@@ -82,5 +85,37 @@ public class Exporter {
public void setFile(String file) {
this.file = file;
+ newWriterNeeded = true;
+ }
+
+ private void initWriter() {
+ if (newWriterNeeded || tabularWriter == null) {
+ if (fileWriter != null) {
+ fileWriter.close();
+ }
+
+ if (format == null) {
+ throw new IllegalStateException("No format is set. Please set it to 'raw' or 'csv'.");
+ }
+
+ if (file == null) {
+ throw new IllegalStateException("No file is set. Please specify the file to outut the data to.");
+ }
+
+ newWriterNeeded = false;
+
+ try {
+ fileWriter = new PrintWriter(new FileWriter(this.file));
+ tabularWriter = new TabularWriter(fileWriter, format);
+ tabularWriter.setExportMode(true);
+ } catch (IOException e) {
+ if (fileWriter != null) {
+ fileWriter.close();
+ }
+
+ throw new ExportException("Failed to initialize the exporter.", e);
+ }
+ }
+ tabularWriter.setWidth(pageWidth);
}
}
commit 24f73a93acb34778ce5188af0d7179c82c719132
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Thu Feb 17 17:22:53 2011 +0100
lowering the logging level when outputting the package version bits so that the logs don't get spammed during correct behavior.
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentSourceManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentSourceManagerBean.java
index 7aa3419..764f542 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentSourceManagerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentSourceManagerBean.java
@@ -2019,7 +2019,7 @@ public class ContentSourceManagerBean implements ContentSourceManagerLocal {
int resourceId = 0; //set to dummy value
- log.info("Calling outputPackageVersionBitsRangeHelper() with package details: " + packageDetailsKey);
+ log.debug("Calling outputPackageVersionBitsRangeHelper() with package details: " + packageDetailsKey);
return outputPackageVersionBitsRangeHelper(resourceId, packageDetailsKey, outputStream, 0, -1, packageVersion
.getId());
}
@@ -2036,7 +2036,7 @@ public class ContentSourceManagerBean implements ContentSourceManagerLocal {
int resourceId = 0; //set to dummy value
- log.info("Calling outputPackageVersionBitsRangeHelper() with package details: " + packageDetailsKey);
+ log.debug("Calling outputPackageVersionBitsRangeHelper() with package details: " + packageDetailsKey);
return outputPackageVersionBitsRangeHelper(resourceId, packageDetailsKey, outputStream, startByte, endByte,
packageVersion.getId());
}
commit 657e1c082bc88d5c9f8e61b867738a8262cec992
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Thu Feb 17 17:17:47 2011 +0100
Simplify the interfaces in the LocalClient in the same way we do it in the RemoteClient so that serverside and remote CLI scripts have the same APIs bound.
diff --git a/modules/enterprise/server/client-api/src/main/java/org/rhq/enterprise/client/LocalClient.java b/modules/enterprise/server/client-api/src/main/java/org/rhq/enterprise/client/LocalClient.java
index 0462638..5751b30 100644
--- a/modules/enterprise/server/client-api/src/main/java/org/rhq/enterprise/client/LocalClient.java
+++ b/modules/enterprise/server/client-api/src/main/java/org/rhq/enterprise/client/LocalClient.java
@@ -20,6 +20,7 @@
package org.rhq.enterprise.client;
import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
import java.util.HashMap;
import java.util.Map;
@@ -28,6 +29,7 @@ import org.apache.commons.logging.LogFactory;
import org.rhq.bindings.client.RhqFacade;
import org.rhq.bindings.client.RhqManagers;
+import org.rhq.bindings.util.InterfaceSimplifier;
import org.rhq.core.domain.auth.Subject;
import org.rhq.enterprise.server.alert.AlertDefinitionManagerRemote;
import org.rhq.enterprise.server.alert.AlertManagerRemote;
@@ -218,6 +220,10 @@ public class LocalClient implements RhqFacade {
private <T> T getProxy(Object slsb, Class<T> iface) {
RhqManagers manager = RhqManagers.forInterface(iface);
- return iface.cast(new LocalClientProxy(slsb, this, manager));
+ Class<?> simplified = InterfaceSimplifier.simplify(iface);
+
+ Object proxy = Proxy.newProxyInstance(iface.getClassLoader(), new Class<?>[] { simplified }, new LocalClientProxy(slsb, this, manager));
+
+ return iface.cast(proxy);
}
}
commit bcf4275ba28720f13d756c692c6f2a6d845625b7
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Thu Feb 17 17:16:12 2011 +0100
plain views for JSF content UI.
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/AdministrationView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/AdministrationView.java
index 2136724..7ba619b 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/AdministrationView.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/AdministrationView.java
@@ -218,7 +218,7 @@ public class AdministrationView extends AbstractSectionedLeftNavigationView {
"subsystems/content/Content_16.png", new ViewFactory() {
public Canvas createView() {
return new FullHTMLPane(extendLocatorId(PAGE_CONTENT_SOURCES_VIEW_ID.getName()),
- "/rhq/content/listContentProviders.xhtml?nomenu=true");
+ "/rhq/content/listContentProviders-plain.xhtml");
}
}, getGlobalPermissions().contains(Permission.MANAGE_REPOSITORIES));
@@ -226,7 +226,7 @@ public class AdministrationView extends AbstractSectionedLeftNavigationView {
new ViewFactory() {
public Canvas createView() {
return new FullHTMLPane(extendLocatorId(PAGE_REPOS_VIEW_ID.getName()),
- "/rhq/content/listRepos.xhtml?nomenu=true");
+ "/rhq/content/listRepos-plain.xhtml");
}
});
diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/content/CreateContentSourceUIBean.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/content/CreateContentSourceUIBean.java
index 4180b13..38c995d 100644
--- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/content/CreateContentSourceUIBean.java
+++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/content/CreateContentSourceUIBean.java
@@ -208,7 +208,7 @@ public class CreateContentSourceUIBean extends PagedDataTableUIBean {
String link = perspectiveManager.getPageLink(subject, "createContentProvider", typeName, null);
if (null == link) {
- link = "/rhq/content/createContentProvider.xhtml?mode=new&typeName=" + typeName;
+ link = "/rhq/content/createContentProvider-plain.xhtml?mode=new&typeName=" + typeName;
} else {
link += "&mode=new&typeName=" + typeName;
}
diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/content/advisoryInfo-plain.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/content/advisoryInfo-plain.xhtml
new file mode 100644
index 0000000..c672d16
--- /dev/null
+++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/content/advisoryInfo-plain.xhtml
@@ -0,0 +1,137 @@
+<?xml version="1.0"?>
+
+<!DOCTYPE html
+ PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml"
+ xmlns:h="http://java.sun.com/jsf/html"
+ xmlns:f="http://java.sun.com/jsf/core"
+ xmlns:ui="http://java.sun.com/jsf/facelets"
+ xmlns:c="http://java.sun.com/jstl/core"
+ xmlns:onc="http://jboss.org/on/component"
+ xmlns:onf="http://jboss.org/on/function"
+ xmlns:rich="http://richfaces.ajax4jsf.org/rich">
+
+<ui:composition template="/rhq/resource/layout/main-plain.xhtml">
+
+ <ui:param name="pageTitle" value="Advisory '#{AdvisoryDetailsUIBean.advisoryDetailsComposite.advisory}'"/>
+ <ui:param name="item" value="#{AdvisoryDetailsUIBean.advisoryDetailsComposite}" />
+ <ui:param name="id" value="${param.id}" />
+ <ui:param name="content_source_id" value="${param.content_source_id}" />
+ <ui:param name="content_source_name" value="${param.content_source_name}" />
+
+ <ui:define name="breadcrumbs">
+ <h:outputLink value="listContentProviders-plain.xhtml">
+ ${msg["contentprovider.list.breadcrumb"]}
+ </h:outputLink>
+ >
+ <h:outputLink value="repo-plain.xhtml">
+ ${msg["repo.list.breadcrumb"]}
+ </h:outputLink>
+ >
+ <h:outputLink value="advisoryInfo-plain.xhtml">
+ #{item.advisory.advisory}
+ <f:param name="id" value="#{item.advisory.id}" />
+ <f:param name="content_source_id" value="#{content_source_id}"/>
+ <f:param name="content_source_name" value="#{content_source_name}"/>
+ </h:outputLink>
+ </ui:define>
+
+ <ui:define name="content">
+
+ <h:form id="repoDetailsForm">
+ <input type="hidden" name="id" value="${param.id}"/>
+
+ <rich:panel>
+ <f:facet name="header">Advisory Details</f:facet>
+
+ <table cellspacing="0" cellpadding="4" width="100%">
+ <tr class="advisory-details-even-row">
+ <td class="advisory-details-key-column"><b>Advisory:</b></td>
+ <td class="advisory-details-value-column">
+ <h:outputText value="#{item.advisory.advisory}" rendered="#{!empty item.advisory.advisory}"/>
+ <h:outputText value="#{item.advisory}" rendered="#{empty item.advisory.advisory}"/>
+ </td>
+ </tr>
+ <tr class="advisory-details-odd-row">
+ <td class="advisory-details-key-column"><b>Type:</b></td>
+ <td class="advisory-details-value-column">
+ <h:outputText value="#{item.advisory.advisoryType}"
+ rendered="#{!empty item.advisory.advisoryType}"/>
+ <h:outputText value="#{item.advisory.advisoryType}"
+ rendered="#{empty item.advisory.advisoryType}"/>
+ </td>
+ </tr>
+ <tr class="advisory-details-even-row">
+ <td class="advisory-details-key-column"><b>Issue Date:</b></td>
+ <td class="advisory-details-value-column">
+ <h:outputText value="#{AdvisoryDetailsUIBean.advisoryDetailsComposite.issueDate}" />
+ </td>
+ </tr>
+ <tr class="advisory-details-odd-row">
+ <td class="advisory-details-key-column"><b>Update Date:</b></td>
+ <td class="advisory-details-value-column">
+ <h:outputText value="#{AdvisoryDetailsUIBean.advisoryDetailsComposite.updateDate}" />
+ </td>
+ </tr>
+ <tr class="advisory-details-even-row">
+ <td class="advisory-details-key-column"><b>Synopsis:</b></td>
+ <td class="advisory-details-value-column">
+ <h:outputText value="#{item.advisory.synopsis}" />
+ </td>
+ </tr>
+ <tr class="advisory-details-odd-row">
+ <td class="advisory-details-key-column"><b>Topic:</b></td>
+ <td class="advisory-details-value-column">
+ <h:outputText value="#{item.advisory.topic}" escape="false" styleClass="advisory-whitespace"/>
+ </td>
+ </tr>
+ <tr class="advisory-details-even-row">
+ <td class="advisory-details-key-column"><b>Description:</b></td>
+ <td class="advisory-details-value-column">
+ <h:outputText value="#{item.advisory.description}" escape="true" styleClass="advisory-whitespace"/>
+ </td>
+ </tr>
+ <tr class="advisory-details-odd-row">
+ <td class="advisory-details-key-column"><b>Solution:</b></td>
+ <td class="advisory-details-value-column">
+ <h:outputText value="#{item.advisory.solution}" escape="false" styleClass="advisory-whitespace"/>
+ </td>
+ </tr>
+ <tr class="advisory-details-even-row">
+ <td class="advisory-details-key-column"><b>CVE:</b></td>
+ <td class="advisory-details-value-column">
+ <h:outputText value="#{AdvisoryDetailsUIBean.advisoryDetailsComposite.cve}" escape="false"/>
+ </td>
+ </tr>
+ <tr class="advisory-details-odd-row">
+ <td class="advisory-details-key-column"><b>Affected Packages:</b></td>
+ <td class="advisory-details-value-column">
+ <rich:dataTable value="#{AdvisoryDetailsUIBean.advisoryDetailsComposite.pkgs}" var="prop">
+ <rich:column>
+ <h:outputLink value="packageVersion-plain.xhtml">
+ <f:param name="id" value="#{prop.id}"/>
+ <h:outputText value="#{prop.fileName}" />
+ </h:outputLink>
+ </rich:column>
+ </rich:dataTable>
+ </td>
+ </tr>
+ <tr class="advisory-details-even-row">
+ <td class="advisory-details-key-column"><b>Relevant Bugs:</b></td>
+ <td class="advisory-details-value-column">
+ <h:outputText value="#{AdvisoryDetailsUIBean.advisoryDetailsComposite.bugid}" escape="false"/>
+ </td>
+ </tr>
+ </table>
+
+ </rich:panel>
+
+ </h:form>
+
+ </ui:define>
+</ui:composition>
+
+</html>
+
diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/content/contentProvider-add-map-plain.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/content/contentProvider-add-map-plain.xhtml
new file mode 100644
index 0000000..e08bc56
--- /dev/null
+++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/content/contentProvider-add-map-plain.xhtml
@@ -0,0 +1,58 @@
+<?xml version="1.0"?>
+
+<!DOCTYPE html
+ PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml"
+ xmlns:h="http://java.sun.com/jsf/html"
+ xmlns:f="http://java.sun.com/jsf/core"
+ xmlns:ui="http://java.sun.com/jsf/facelets"
+ xmlns:c="http://java.sun.com/jstl/core"
+ xmlns:onc="http://jboss.org/on/component">
+
+THIS TEXT WILL BE REMOVED.
+
+<ui:composition template="/rhq/resource/layout/main-plain.xhtml">
+
+ THIS TEXT WILL BE REMOVED AS WELL.
+
+ <ui:param name="pageTitle" value="Content Source '#{ContentProviderDetailsUIBean.contentSource.name}' - Add Map To List '#{param.listName}'"/>
+
+ <ui:define name="breadcrumbs">
+ <h:outputLink value="listContentProviders-plain.xhtml">
+ ${msg["contentprovider.list.breadcrumb"]}
+ </h:outputLink>
+ >
+ <h:outputLink value="createContentProvider-plain.xhtml">
+ ${msg["contentprovider.new.breadcrumb"]}
+ </h:outputLink>
+ </ui:define>
+
+ <ui:define name="content">
+
+ <h:form id="editContentProviderConfigurationForm" onsubmit="prepareInputsForSubmission(this)">
+
+ <input type="hidden" name="mode" value="edit"/>
+ <input type="hidden" name="id" value="#{ContentProviderDetailsUIBean.contentSource.id}"/>
+
+ <onc:config configurationDefinition="#{ContentProviderDetailsUIBean.contentSourceTypeConfigurationDefinition}"
+ configuration="#{ContentProviderDetailsUIBean.contentSource.configuration}"
+ listName="#{param.listName}"/>
+
+ <h:panelGrid columns="2" styleClass="buttons-table" columnClasses="button-cell">
+ <h:commandButton value="OK" type="submit" action="#{ContentProviderDetailsUIBean.finishAddMap}"
+ alt="Click to Add Map" styleClass="buttonmed"/>
+ <h:commandButton value="RESET" type="reset" immediate="true"
+ alt="Click to Reset Fields" styleClass="buttonmed"/>
+ </h:panelGrid>
+
+ </h:form>
+
+ </ui:define>
+
+</ui:composition>
+
+THIS TEXT WILL BE REMOVED AS WELL.
+
+</html>
diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/content/contentProvider-edit-map-plain.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/content/contentProvider-edit-map-plain.xhtml
new file mode 100644
index 0000000..c8965ba
--- /dev/null
+++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/content/contentProvider-edit-map-plain.xhtml
@@ -0,0 +1,59 @@
+<?xml version="1.0"?>
+
+<!DOCTYPE html
+ PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml"
+ xmlns:h="http://java.sun.com/jsf/html"
+ xmlns:f="http://java.sun.com/jsf/core"
+ xmlns:ui="http://java.sun.com/jsf/facelets"
+ xmlns:c="http://java.sun.com/jstl/core"
+ xmlns:onc="http://jboss.org/on/component">
+
+THIS TEXT WILL BE REMOVED.
+
+<ui:composition template="/rhq/resource/layout/main-plain.xhtml">
+
+ THIS TEXT WILL BE REMOVED AS WELL.
+
+ <ui:param name="pageTitle" value="Content Source '#{ContentProviderDetailsUIBean.contentSource.name}' - Edit Map Entry '#{param.listName}'"/>
+
+ <ui:define name="breadcrumbs">
+ <h:outputLink value="listContentProviders-plain.xhtml">
+ ${msg["contentprovider.list.breadcrumb"]}
+ </h:outputLink>
+ >
+ <h:outputLink value="createContentProvider-plain.xhtml">
+ ${msg["contentprovider.new.breadcrumb"]}
+ </h:outputLink>
+ </ui:define>
+
+ <ui:define name="content">
+
+ <h:form id="editContentProviderConfigurationForm" onsubmit="prepareInputsForSubmission(this)">
+
+ <input type="hidden" name="mode" value="edit"/>
+ <input type="hidden" name="id" value="#{ContentProviderDetailsUIBean.contentSource.id}"/>
+
+ <onc:config configurationDefinition="#{ContentProviderDetailsUIBean.contentSourceTypeConfigurationDefinition}"
+ configuration="#{ContentProviderDetailsUIBean.contentSource.configuration}"
+ listName="#{param.listName}"
+ listIndex="#{param.listIndex}"/>
+
+ <h:panelGrid columns="2" styleClass="buttons-table" columnClasses="button-cell">
+ <h:commandButton value="OK" type="submit" action="#{ContentProviderDetailsUIBean.finishEditMap}"
+ alt="Click to Add Map" styleClass="buttonmed"/>
+ <h:commandButton value="RESET" type="reset" immediate="true"
+ alt="Click to Reset Fields" styleClass="buttonmed"/>
+ </h:panelGrid>
+
+ </h:form>
+
+ </ui:define>
+
+</ui:composition>
+
+THIS TEXT WILL BE REMOVED AS WELL.
+
+</html>
diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/content/contentProvider-plain.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/content/contentProvider-plain.xhtml
new file mode 100644
index 0000000..d13933b
--- /dev/null
+++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/content/contentProvider-plain.xhtml
@@ -0,0 +1,512 @@
+<?xml version="1.0"?>
+
+<!DOCTYPE html
+ PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml"
+ xmlns:h="http://java.sun.com/jsf/html"
+ xmlns:f="http://java.sun.com/jsf/core"
+ xmlns:ui="http://java.sun.com/jsf/facelets"
+ xmlns:c="http://java.sun.com/jstl/core"
+ xmlns:onc="http://jboss.org/on/component"
+ xmlns:onf="http://jboss.org/on/function"
+ xmlns:a4j="http://richfaces.org/a4j"
+ xmlns:rich="http://richfaces.org/rich">
+
+<ui:composition template="/rhq/resource/layout/main-plain.xhtml">
+
+ <ui:param name="id" value="#{param.id}" />
+ <ui:param name="mode" value="#{param.mode}" />
+ <ui:param name="pageTitle" value="Content Source '#{ContentProviderDetailsUIBean.contentSource.name}'"/>
+ <ui:param name="item" value="#{ContentProviderDetailsUIBean.contentSource}" />
+
+ <ui:define name="breadcrumbs">
+ <h:outputLink value="listContentProviders-plain.xhtml">
+ ${msg["contentprovider.list.breadcrumb"]}
+ </h:outputLink>
+ >
+ <h:outputLink value="contentProvider-plain.xhtml">
+ #{item.name}
+ <f:param name="mode" value="view" />
+ <f:param name="id" value="#{item.id}" />
+ </h:outputLink>
+ </ui:define>
+
+ <ui:define name="content">
+
+ <a4j:region>
+ <h:form id="pollerForm">
+ <input type="hidden" name="id" value="#{param.id}"/>
+ <input type="hidden" name="mode" value="#{param.mode}"/>
+
+ <!-- TODO: Only update if a sync is in progress. -->
+ <!-- BZ-589199 modified a4j:poll to rerender all other regions of contentSourceSyncResultsListForm but the modalPanel -->
+ <a4j:poll id="poller" interval="7000" enabled="true"
+ reRender="poller,table-check-boxes,table-start,table-end,table-id,table-status"/>
+ </h:form>
+ </a4j:region>
+
+ <h:form id="contentProviderDetailsForm">
+ <input type="hidden" name="id" value="${param.id}"/>
+ <input type="hidden" name="mode" value="${param.mode}"/>
+
+ <rich:panel>
+ <f:facet name="header">Basic Details</f:facet>
+ <table>
+ <tr>
+ <td align="right"><b>Type:</b></td>
+ <td align="left">
+ <h:outputText value="#{ContentProviderDetailsUIBean.contentSource.contentSourceType.name}" />
+ </td>
+ </tr>
+ <tr>
+ <td align="right"><b>Name:</b></td>
+ <td align="left">
+ <h:inputText rendered="${mode eq 'edit'}" value="#{ContentProviderDetailsUIBean.contentSource.name}" />
+ <h:outputText rendered="${mode ne 'edit'}" value="#{ContentProviderDetailsUIBean.contentSource.name}" />
+ </td>
+ </tr>
+ <tr>
+ <td align="right"><b>Description:</b></td>
+ <td align="left">
+ <h:inputTextarea rendered="${mode eq 'edit'}" rows="3" cols="20" value="#{ContentProviderDetailsUIBean.contentSource.description}"/>
+ <h:outputText rendered="${mode ne 'edit'}" value="#{ContentProviderDetailsUIBean.contentSource.description}"/>
+ </td>
+ </tr>
+ <tr>
+ <td align="right"><b>Synchronization Schedule:</b></td>
+ <td align="left">
+ <h:inputText rendered="${mode eq 'edit'}" value="#{ContentProviderDetailsUIBean.contentSource.syncSchedule}" />
+ <h:outputText rendered="${mode ne 'edit'}" value="#{ContentProviderDetailsUIBean.contentSource.syncSchedule}" />
+ </td>
+ </tr>
+ <tr>
+ <td align="right"><b>Lazy Load:</b></td>
+ <td align="left">
+ <h:selectBooleanCheckbox rendered="${mode eq 'edit'}" value="#{ContentProviderDetailsUIBean.contentSource.lazyLoad}" />
+ <h:outputText rendered="${mode ne 'edit'}" value="#{ContentProviderDetailsUIBean.contentSource.lazyLoad}" />
+ </td>
+ </tr>
+ <tr>
+ <td align="right"><b>Download Mode:</b></td>
+ <td align="left">
+ <h:selectOneMenu rendered="${mode eq 'edit'}"
+ value="#{ContentProviderDetailsUIBean.selectedDownloadMode}">
+ <f:selectItems value="#{ContentProviderDetailsUIBean.downloadModes}" />
+ </h:selectOneMenu>
+ <h:outputText rendered="${mode ne 'edit'}" value="#{ContentProviderDetailsUIBean.contentSource.downloadMode}" />
+ </td>
+ </tr>
+ <tr>
+ <td align="right"><b>Creation Date:</b></td>
+ <td align="left">
+ <h:outputText value="#{ContentProviderDetailsUIBean.contentSource.creationDate}">
+ <f:convertDateTime pattern="M/d/yy, h:mm:ss aa, zzz" timeZone="#{ServerInfoUIBean.timeZone}"/>
+ </h:outputText>
+ </td>
+ </tr>
+ <tr>
+ <td align="right"><b>Last Modified Date:</b></td>
+ <td align="left">
+ <h:outputText value="#{ContentProviderDetailsUIBean.contentSource.lastModifiedDate}">
+ <f:convertDateTime pattern="M/d/yy, h:mm:ss aa, zzz" timeZone="#{ServerInfoUIBean.timeZone}"/>
+ </h:outputText>
+ </td>
+ </tr>
+ <tr>
+ <td align="right"><b>Last Download Error:</b></td>
+ <td align="left">
+ <h:outputLink rendered="#{ContentProviderDetailsUIBean.contentSource.loadErrorMessage ne null}"
+ value="#" id="lastDownloadErrorLink">
+ <h:outputText value="Click here to view..."/>
+ <rich:componentControl for="lastDownloadErrorModalPanel" attachTo="lastDownloadErrorLink" operation="show" event="onclick"/>
+ </h:outputLink>
+ <h:outputText rendered="#{ContentProviderDetailsUIBean.contentSource.loadErrorMessage eq null}" value="None"/>
+ <rich:modalPanel id="lastDownloadErrorModalPanel" width="350" height="300"
+ style="overflow: auto;">
+ <f:facet name="header">
+ <h:panelGroup>
+ <h:outputText value="Last Download Error" />
+ </h:panelGroup>
+ </f:facet>
+ <f:facet name="controls">
+ <h:panelGroup>
+ <h:graphicImage value="/images/close.png" style="cursor:pointer" id="lastDownloadErrorModalPanelHideLink"/>
+ <rich:componentControl for="lastDownloadErrorModalPanel" attachTo="lastDownloadErrorModalPanelHideLink" operation="hide" event="onclick"/>
+ </h:panelGroup>
+ </f:facet>
+ <div class="ErrorModalBody">
+ <h:outputText value="#{ContentProviderDetailsUIBean.contentSource.loadErrorMessage}" />
+ </div>
+ </rich:modalPanel>
+ </td>
+ </tr>
+ </table>
+ </rich:panel>
+
+ <rich:panel>
+ <onc:config configurationDefinition="#{ContentProviderDetailsUIBean.contentSourceTypeConfigurationDefinition}"
+ configuration="#{ContentProviderDetailsUIBean.contentSource.configuration}"
+ readOnly="#{mode ne 'edit'}"
+ nullConfigurationDefinitionMessage="This content source type does not require a configuration."
+ nullConfigurationMessage="Configuration is empty."
+ nullConfigurationStyle="InfoBlock"/>
+ </rich:panel>
+
+ <h:panelGrid columns="3" styleClass="buttons-table" columnClasses="button-cell">
+ <ui:remove><!-- view mode buttons --></ui:remove>
+ <h:commandButton rendered="${mode ne 'edit'}"
+ value="EDIT" action="#{ContentProviderDetailsUIBean.edit}"
+ alt="Edit" styleClass="buttonmed" id="editButton"/>
+ <h:commandButton rendered="${mode ne 'edit'}"
+ value="TEST CONNECTION" action="#{ContentProviderDetailsUIBean.test}"
+ alt="Test Connection" styleClass="buttonmed" id="testButton"/>
+ <h:commandButton rendered="${mode ne 'edit'}"
+ value="SYNCHRONIZE" action="#{ContentProviderDetailsUIBean.sync}"
+ alt="Synchronize" styleClass="buttonmed" id="syncButton"/>
+
+ <ui:remove><!-- edit mode buttons --></ui:remove>
+ <h:commandButton rendered="${mode eq 'edit'}"
+ value="SAVE" action="#{ContentProviderDetailsUIBean.save}"
+ alt="Save" styleClass="buttonmed" id="saveButton"/>
+ <h:commandButton rendered="${mode eq 'edit'}"
+ value="CANCEL" action="#{ContentProviderDetailsUIBean.cancel}"
+ alt="Cancel" styleClass="buttonmed" id="cancelButton"/>
+ </h:panelGrid>
+
+ </h:form>
+
+
+
+ <!-- IMPORTED (NOT CANDIDATE) REPOS LIST -->
+
+ <h:form id="contentProviderReposListForm">
+ <input type="hidden" name="id" value="${param.id}"/>
+ <input type="hidden" name="mode" value="${param.mode}"/>
+
+ <rich:panel>
+ <f:facet name="header">
+ <h:outputText value="Repositories"/>
+ </f:facet>
+
+ <h:panelGrid columns="1" width="100%">
+
+ <ui:param name="contentProviderReposDataModel" value="#{ContentSourceReposUIBean.dataModel}"/>
+ <rich:dataTable id="contentProviderReposDataTable"
+ rows="#{PageControl.ContentSourceReposList.pageSize}"
+ value="#{contentProviderReposDataModel}"
+ var="repo"
+ width="100%"
+ columnsWidth="1%, 20%, 20%, 20%"
+ headerClass="tableRowHeader"
+ footerClass="on-pager-footer"
+ onRowMouseOver="this.style.backgroundColor='#E7E7E7'"
+ onRowMouseOut="this.style.backgroundColor='#{a4jSkin.tableBackgroundColor}'">
+
+ <f:facet name="PageControlView">
+ <onc:paginationControl id="ContentSourceReposList" />
+ </f:facet>
+
+ <rich:column>
+ <f:facet name="header">
+ <onc:allSelect target="selectedContentSourceRepos" />
+ </f:facet>
+
+ <onc:select name="selectedContentSourceRepos" value="#{repo.id}" />
+ </rich:column>
+
+ <rich:column rendered="#{param.debug}">
+ <f:facet name="header">
+ <onc:sortableColumnHeader sort="c.id">
+ <h:outputText styleClass="headerText" value="ID" />
+ </onc:sortableColumnHeader>
+ </f:facet>
+
+ <h:outputText value="#{repo.id}"/>
+ </rich:column>
+
+ <rich:column>
+ <f:facet name="header">
+ <onc:sortableColumnHeader sort="c.name">
+ <h:outputText styleClass="headerText" value="Name" />
+ </onc:sortableColumnHeader>
+ </f:facet>
+
+ <h:outputLink value="repo-plain.xhtml">
+ <f:param name="mode" value="view"/>
+ <f:param name="id" value="#{repo.id}"/>
+ <h:outputText value="#{repo.name}" />
+ </h:outputLink>
+ </rich:column>
+
+ <rich:column>
+ <f:facet name="header">
+ <onc:sortableColumnHeader sort="c.creationDate">
+ <h:outputText styleClass="headerText" value="Date Created" />
+ </onc:sortableColumnHeader>
+ </f:facet>
+
+ <h:outputText value="#{repo.creationDate}">
+ <f:convertDateTime pattern="M/d/yy, h:mm:ss aa, zzz" timeZone="#{ServerInfoUIBean.timeZone}"/>
+ </h:outputText>
+ </rich:column>
+
+ <rich:column>
+ <f:facet name="header">
+ <onc:sortableColumnHeader sort="c.lastModifiedDate">
+ <h:outputText styleClass="headerText" value="Date Modified" />
+ </onc:sortableColumnHeader>
+ </f:facet>
+
+ <h:outputText value="#{repo.lastModifiedDate}">
+ <f:convertDateTime pattern="M/d/yy, h:mm:ss aa, zzz" timeZone="#{ServerInfoUIBean.timeZone}"/>
+ </h:outputText>
+ </rich:column>
+
+ <rich:column>
+ <f:facet name="header">
+ <onc:sortableColumnHeader sort="c.description">
+ <h:outputText styleClass="headerText" value="Description" />
+ </onc:sortableColumnHeader>
+ </f:facet>
+
+ <h:outputText value="#{repo.description}"/>
+ </rich:column>
+
+ <f:facet name="footer">
+ <rich:columnGroup>
+ <!-- colspan 6:5 for the debug 'id' column -->
+ <rich:column colspan="#{param.debug ? 6 : 5}" width="100%">
+ <ui:remove>
+ <!--
+ <onc:selectCommandButton action="#{ContentSourceReposUIBean.deleteSelectedContentSourceRepos}"
+ value="DISASSOCIATE SELECTED" target="selectedContentSourceRepos"
+ styleClass="on-pager-button buttonsmall"/>
+ -->
+ </ui:remove>
+ <ui:param name="paginationDataTableName" value="contentProviderReposDataTable"/>
+ <ui:param name="paginationDataModel" value="#{contentProviderReposDataModel}"/>
+ <ui:param name="paginationPageControl" value="#{PageControl.ContentSourceReposList}"/>
+ <ui:include src="../resource/include/pagination.xhtml"/>
+ </rich:column>
+ </rich:columnGroup>
+ </f:facet>
+
+ </rich:dataTable>
+
+ </h:panelGrid>
+
+ </rich:panel>
+ </h:form>
+
+
+ <!-- SYNCHRONIZATION RESULTS HISTORY -->
+
+ <h:form id="contentSourceSyncResultsListForm">
+ <input type="hidden" name="id" value="${param.id}"/>
+ <input type="hidden" name="mode" value="${param.mode}"/>
+
+ <rich:panel>
+ <f:facet name="header">
+ <h:outputText value="Synchronization Results History"/>
+ </f:facet>
+
+ <h:panelGrid columns="1" width="100%">
+
+ <ui:param name="contentSourceSyncResultsDataModel" value="#{ContentSourceSyncResultsUIBean.dataModel}"/>
+ <rich:dataTable id="contentSourceSyncResultsDataTable"
+ rows="#{PageControl.ContentSourceSyncResultsList.pageSize}"
+ value="#{contentSourceSyncResultsDataModel}"
+ var="syncitem"
+ width="100%"
+ columnsWidth="1%, 10%, 20%, 20%, 10%"
+ headerClass="tableRowHeader"
+ footerClass="on-pager-footer"
+ onRowMouseOver="this.style.backgroundColor='#E7E7E7'"
+ onRowMouseOut="this.style.backgroundColor='#{a4jSkin.tableBackgroundColor}'">
+
+
+ <f:facet name="PageControlView">
+ <onc:paginationControl id="ContentSourceSyncResultsList" />
+ </f:facet>
+
+ <rich:column id="table-check-boxes">
+ <f:facet name="header">
+ <onc:allSelect target="selectedContentSourceSyncResults" />
+ </f:facet>
+
+ <onc:select name="selectedContentSourceSyncResults" value="#{syncitem.id}" />
+ </rich:column>
+
+ <rich:column id="table-id">
+ <f:facet name="header">
+ <h:outputText styleClass="headerText" value="ID" />
+ </f:facet>
+
+ <h:outputText value="#{syncitem.id}"/>
+ </rich:column>
+
+ <rich:column id="table-start">
+ <f:facet name="header">
+ <onc:sortableColumnHeader sort="cssr.startTime">
+ <h:outputText styleClass="headerText" value="Start Time" />
+ </onc:sortableColumnHeader>
+ </f:facet>
+
+ <h:outputText value="#{syncitem.startTime}">
+ <f:converter converterId="UserDateTimeConverter" />
+ </h:outputText>
+ </rich:column>
+
+ <rich:column id="table-end">
+ <f:facet name="header">
+ <onc:sortableColumnHeader sort="cssr.endTime">
+ <h:outputText styleClass="headerText" value="End Time" />
+ </onc:sortableColumnHeader>
+ </f:facet>
+
+ <h:outputText value="#{syncitem.endTime}">
+ <f:converter converterId="UserDateTimeConverter" />
+ </h:outputText>
+ </rich:column>
+
+ <rich:column id="table-status">
+ <f:facet name="header">
+ <onc:sortableColumnHeader sort="cssr.status">
+ <h:outputText styleClass="headerText" value="Status" />
+ </onc:sortableColumnHeader>
+ </f:facet>
+
+ <h:outputText value="#{syncitem.status}"/>
+ </rich:column>
+
+ <rich:column>
+ <f:facet name="header">
+ <h:outputText styleClass="headerText" value="Results" />
+ </f:facet>
+
+ <h:outputLink rendered="#{syncitem.results ne null}"
+ value="#" id="resultsLink">
+ <h:outputText value="Click here to view..."/>
+ <rich:componentControl for="resultsModalPanel" attachTo="resultsLink" operation="show" event="onclick"/>
+ </h:outputLink>
+ <h:outputText rendered="#{syncitem.results eq null}" value=""/>
+
+ <rich:modalPanel id="resultsModalPanel" width="640" height="480" moveable="false" resizeable="false"
+ style="overflow: auto;">
+ <f:facet name="header">
+ <h:panelGroup layout="block">
+ Results for synchronization request with id #{syncitem.id}
+ </h:panelGroup>
+ </f:facet>
+ <f:facet name="controls">
+ <h:panelGroup>
+ <h:graphicImage value="/images/close.png" style="cursor:pointer" id="resultsModelPanelHideLink"/>
+ <rich:componentControl for="resultsModalPanel" attachTo="resultsModelPanelHideLink" operation="hide" event="onclick"/>
+ </h:panelGroup>
+ </f:facet>
+ <h:panelGroup layout="block">
+ <pre>#{syncitem.results}</pre>
+ </h:panelGroup>
+ </rich:modalPanel>
+ </rich:column>
+
+ <f:facet name="footer">
+ <rich:columnGroup>
+ <rich:column colspan="6" width="100%">
+ <onc:selectCommandButton action="#{ContentSourceSyncResultsUIBean.deleteSelectedContentSourceSyncResults}"
+ value="DELETE SELECTED" target="selectedContentSourceSyncResults" styleClass="on-pager-button buttonsmall"/>
+
+ <ui:param name="paginationDataTableName" value="contentSourceSyncResultsDataTable"/>
+ <ui:param name="paginationDataModel" value="#{contentSourceSyncResultsDataModel}"/>
+ <ui:param name="paginationPageControl" value="#{PageControl.ContentSourceSyncResultsList}"/>
+ <ui:include src="../resource/include/pagination.xhtml"/>
+ </rich:column>
+ </rich:columnGroup>
+ </f:facet>
+
+ </rich:dataTable>
+
+ </h:panelGrid>
+
+ </rich:panel>
+
+ </h:form>
+
+
+
+ <!-- CANDIDATE (NOT IMPORTED) REPOS LIST -->
+
+ <h:form id="contentSourceRepoListForm" rendered="#{ContentSourceCandidateReposUIBean.dataModel.rowCount gt 0}">
+ <input type="hidden" name="id" value="${param.id}"/>
+ <input type="hidden" name="mode" value="${param.mode}"/>
+
+ <rich:panel>
+ <f:facet name="header">
+ <h:outputText value="Candidate Repositories"/>
+ </f:facet>
+
+ <h:panelGrid columns="2" width="100%">
+
+ <ui:param name="contentSourceReposDataModel" value="#{ContentSourceCandidateReposUIBean.dataModel}"/>
+ <rich:dataTable id="contentSourceReposDataTable"
+ rows="#{PageControl.ContentSourceCandidateReposList.pageSize}"
+ value="#{contentSourceReposDataModel}"
+ var="repo"
+ width="100%"
+ columnsWidth="1%,99%"
+ headerClass="tableRowHeader"
+ footerClass="on-pager-footer"
+ onRowMouseOver="this.style.backgroundColor='#E7E7E7'"
+ onRowMouseOut="this.style.backgroundColor='#{a4jSkin.tableBackgroundColor}'">
+
+ <f:facet name="PageControlView">
+ <onc:paginationControl id="ContentSourceCandidateReposList" />
+ </f:facet>
+
+ <rich:column>
+ <f:facet name="header">
+ <onc:allSelect target="selectedCandidateRepos" />
+ </f:facet>
+
+ <onc:select name="selectedCandidateRepos" value="#{repo.id}" />
+ </rich:column>
+
+ <rich:column>
+ <f:facet name="header">
+ <onc:sortableColumnHeader sort="c.name">
+ <h:outputText styleClass="headerText" value="Name" />
+ </onc:sortableColumnHeader>
+ </f:facet>
+
+ <h:outputText value="#{repo.name}" />
+ <h:outputText value="(id=#{repo.id})" rendered="#{param.debug}" />
+ </rich:column>
+
+ <f:facet name="footer">
+ <rich:columnGroup>
+ <!-- colspan 7:6 for the debug 'id' column -->
+ <rich:column colspan="2" width="100%">
+ <onc:selectCommandButton action="#{ContentSourceCandidateReposUIBean.importSelectedRepos}"
+ value="IMPORT SELECTED" target="selectedCandidateRepos" styleClass="on-pager-button buttonsmall"/>
+ <ui:param name="paginationDataTableName" value="contentSourceReposDataTable"/>
+ <ui:param name="paginationDataModel" value="#{contentSourceReposDataModel}"/>
+ <ui:param name="paginationPageControl" value="#{PageControl.ContentSourceCandidateReposList}"/>
+ <ui:include src="../resource/include/pagination.xhtml"/>
+ </rich:column>
+ </rich:columnGroup>
+ </f:facet>
+
+ </rich:dataTable>
+
+ </h:panelGrid>
+
+ </rich:panel>
+ </h:form>
+
+ </ui:define>
+
+</ui:composition>
+
+</html>
diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/content/contentProvider-view-map-plain.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/content/contentProvider-view-map-plain.xhtml
new file mode 100644
index 0000000..ac0e488
--- /dev/null
+++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/content/contentProvider-view-map-plain.xhtml
@@ -0,0 +1,58 @@
+<?xml version="1.0"?>
+
+<!DOCTYPE html
+ PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml"
+ xmlns:h="http://java.sun.com/jsf/html"
+ xmlns:f="http://java.sun.com/jsf/core"
+ xmlns:ui="http://java.sun.com/jsf/facelets"
+ xmlns:c="http://java.sun.com/jstl/core"
+ xmlns:onc="http://jboss.org/on/component">
+
+THIS TEXT WILL BE REMOVED.
+
+<ui:composition template="/rhq/resource/layout/main-plain.xhtml">
+
+ THIS TEXT WILL BE REMOVED AS WELL.
+
+ <ui:param name="pageTitle" value="Create Content Source - Add Map To List '#{param.listName}'"/>
+
+ <ui:define name="breadcrumbs">
+ <h:outputLink value="listContentProviders-plain.xhtml">
+ ${msg["contentprovider.list.breadcrumb"]}
+ </h:outputLink>
+ >
+ <h:outputLink value="createContentProvider-plain.xhtml">
+ ${msg["contentprovider.new.breadcrumb"]}
+ </h:outputLink>
+ </ui:define>
+
+ <ui:define name="content">
+
+ <h:form id="editContentProviderConfigurationForm" onsubmit="prepareInputsForSubmission(this)">
+
+ <input type="hidden" name="mode" value="edit"/>
+ <input type="hidden" name="id" value="#{ContentProviderDetailsUIBean.contentSource.id}"/>
+
+ <onc:config configurationDefinition="#{ContentProviderDetailsUIBean.contentSourceTypeConfigurationDefinition}"
+ configuration="#{ContentProviderDetailsUIBean.contentSource.configuration}"
+ listName="#{param.listName}"/>
+
+ <h:panelGrid columns="2" styleClass="buttons-table" columnClasses="button-cell">
+ <h:commandButton value="OK" type="submit" action="#{CreateContentSourceUIBean.finishAddMap}"
+ alt="Click to Add Map" styleClass="buttonmed"/>
+ <h:commandButton value="RESET" type="reset" immediate="true"
+ alt="Click to Reset Fields" styleClass="buttonmed"/>
+ </h:panelGrid>
+
+ </h:form>
+
+ </ui:define>
+
+</ui:composition>
+
+THIS TEXT WILL BE REMOVED AS WELL.
+
+</html>
diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/content/createContentProvider-add-map-plain.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/content/createContentProvider-add-map-plain.xhtml
new file mode 100644
index 0000000..23e06df
--- /dev/null
+++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/content/createContentProvider-add-map-plain.xhtml
@@ -0,0 +1,57 @@
+<?xml version="1.0"?>
+
+<!DOCTYPE html
+ PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml"
+ xmlns:h="http://java.sun.com/jsf/html"
+ xmlns:f="http://java.sun.com/jsf/core"
+ xmlns:ui="http://java.sun.com/jsf/facelets"
+ xmlns:c="http://java.sun.com/jstl/core"
+ xmlns:onc="http://jboss.org/on/component">
+
+THIS TEXT WILL BE REMOVED.
+
+<ui:composition template="/rhq/resource/layout/main-plain.xhtml">
+
+ THIS TEXT WILL BE REMOVED AS WELL.
+
+ <ui:param name="pageTitle" value="Create Content Source - Add Map To List '#{param.listName}'"/>
+
+ <ui:define name="breadcrumbs">
+ <h:outputLink value="listContentProviders-plain.xhtml">
+ ${msg["contentprovider.list.breadcrumb"]}
+ </h:outputLink>
+ >
+ <h:outputLink value="createContentProvider-plain.xhtml">
+ ${msg["contentprovider.new.breadcrumb"]}
+ </h:outputLink>
+ </ui:define>
+
+ <ui:define name="content">
+
+ <h:form id="editContentProviderConfigurationForm" onsubmit="prepareInputsForSubmission(this)">
+
+ <input type="hidden" name="typeName" value="#{param.typeName}"/>
+
+ <onc:config configurationDefinition="#{CreateContentSourceUIBean.contentSourceTypeConfigurationDefinition}"
+ configuration="#{CreateContentSourceUIBean.contentSource.configuration}"
+ listName="#{param.listName}"/>
+
+ <h:panelGrid columns="2" styleClass="buttons-table" columnClasses="button-cell">
+ <h:commandButton value="OK" type="submit" action="#{CreateContentSourceUIBean.finishAddMap}"
+ alt="Click to Add Map" styleClass="buttonmed"/>
+ <h:commandButton value="RESET" type="reset" immediate="true"
+ alt="Click to Reset Fields" styleClass="buttonmed"/>
+ </h:panelGrid>
+
+ </h:form>
+
+ </ui:define>
+
+</ui:composition>
+
+THIS TEXT WILL BE REMOVED AS WELL.
+
+</html>
diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/content/createContentProvider-edit-map-plain.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/content/createContentProvider-edit-map-plain.xhtml
new file mode 100644
index 0000000..716ddb8
--- /dev/null
+++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/content/createContentProvider-edit-map-plain.xhtml
@@ -0,0 +1,58 @@
+<?xml version="1.0"?>
+
+<!DOCTYPE html
+ PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml"
+ xmlns:h="http://java.sun.com/jsf/html"
+ xmlns:f="http://java.sun.com/jsf/core"
+ xmlns:ui="http://java.sun.com/jsf/facelets"
+ xmlns:c="http://java.sun.com/jstl/core"
+ xmlns:onc="http://jboss.org/on/component">
+
+THIS TEXT WILL BE REMOVED.
+
+<ui:composition template="/rhq/resource/layout/main-plain.xhtml">
+
+ THIS TEXT WILL BE REMOVED AS WELL.
+
+ <ui:param name="pageTitle" value="Create Content Source - Edit Map Entry '#{param.listName}'"/>
+
+ <ui:define name="breadcrumbs">
+ <h:outputLink value="listProviders-plain.xhtml">
+ ${msg["contentprovider.list.breadcrumb"]}
+ </h:outputLink>
+ >
+ <h:outputLink value="createContentProvider-plain.xhtml">
+ ${msg["contentprovider.new.breadcrumb"]}
+ </h:outputLink>
+ </ui:define>
+
+ <ui:define name="content">
+
+ <h:form id="editContentProviderConfigurationForm" onsubmit="prepareInputsForSubmission(this)">
+
+ <input type="hidden" name="typeName" value="#{param.typeName}"/>
+
+ <onc:config configurationDefinition="#{CreateContentSourceUIBean.contentSourceTypeConfigurationDefinition}"
+ configuration="#{CreateContentSourceUIBean.contentSource.configuration}"
+ listName="#{param.listName}"
+ listIndex="#{param.listIndex}"/>
+
+ <h:panelGrid columns="2" styleClass="buttons-table" columnClasses="button-cell">
+ <h:commandButton value="OK" type="submit" action="#{CreateContentSourceUIBean.finishEditMap}"
+ alt="Click to Add Map" styleClass="buttonmed"/>
+ <h:commandButton value="RESET" type="reset" immediate="true"
+ alt="Click to Reset Fields" styleClass="buttonmed"/>
+ </h:panelGrid>
+
+ </h:form>
+
+ </ui:define>
+
+</ui:composition>
+
+THIS TEXT WILL BE REMOVED AS WELL.
+
+</html>
diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/content/createContentProvider-plain.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/content/createContentProvider-plain.xhtml
new file mode 100644
index 0000000..00dff99
--- /dev/null
+++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/content/createContentProvider-plain.xhtml
@@ -0,0 +1,152 @@
+<?xml version="1.0"?>
+
+<!DOCTYPE html
+ PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml"
+ xmlns:h="http://java.sun.com/jsf/html"
+ xmlns:f="http://java.sun.com/jsf/core"
+ xmlns:ui="http://java.sun.com/jsf/facelets"
+ xmlns:c="http://java.sun.com/jstl/core"
+ xmlns:onc="http://jboss.org/on/component"
+ xmlns:onf="http://jboss.org/on/function"
+ xmlns:a4j="https://ajax4jsf.dev.java.net/ajax"
+ xmlns:rich="http://richfaces.ajax4jsf.org/rich">
+
+<ui:composition template="/rhq/resource/layout/main-plain.xhtml">
+
+ <ui:param name="pageTitle" value="Create New Content Source"/>
+
+ <ui:define name="breadcrumbs">
+ <h:outputLink value="listContentProviders-plain.xhtml">
+ ${msg["contentprovider.list.breadcrumb"]}
+ </h:outputLink>
+ >
+ <h:outputLink value="createContentProvider-plain.xhtml">
+ ${msg["contentprovider.new.breadcrumb"]}
+ </h:outputLink>
+ </ui:define>
+
+ <ui:define name="content">
+
+ <h:form id="setContentSourceType">
+ <input type="hidden" name="typeName" value="#{param.typeName}"/>
+
+ <rich:panel>
+ <f:facet name="header">Content Source Type</f:facet>
+
+ <h:panelGrid columns="1" styleClass="data-table">
+
+ <rich:dataTable id="contentProviderTypesDataTable"
+ rows="0"
+ value="#{CreateContentSourceUIBean.dataModel}"
+ var="item"
+ width="100%"
+ columnsWidth="35%, 65%"
+ styleClass="resources-table"
+ headerClass="tableRowHeader"
+ onRowMouseOver="this.style.backgroundColor='#E7E7E7'"
+ onRowMouseOut="this.style.backgroundColor='#{a4jSkin.tableBackgroundColor}'">
+
+ <f:facet name="PageControlView">
+ <onc:paginationControl id="NONE" />
+ </f:facet>
+
+ <rich:column>
+ <f:facet name="header">
+ <onc:sortableColumnHeader sort="cst.displayName">
+ <h:outputText styleClass="headerText" value="Name" />
+ </onc:sortableColumnHeader>
+ </f:facet>
+
+ <h:outputLink value="#{CreateContentSourceUIBean.getCreateContentProviderPageLink(item.name)}">
+ <!-- note, do not use f:param with perspectives -->
+
+ <h:outputText value="#{item.displayName}" />
+ <h:outputText value=" *" rendered="#{(not empty param.typeName) and (param.typeName eq item.name)}"/>
+ </h:outputLink>
+ </rich:column>
+
+ <rich:column>
+ <f:facet name="header">
+ <onc:sortableColumnHeader sort="cst.description">
+ <h:outputText styleClass="headerText" value="Description" />
+ </onc:sortableColumnHeader>
+ </f:facet>
+
+ <h:outputText value="#{item.description}"/>
+ </rich:column>
+
+ </rich:dataTable>
+
+ </h:panelGrid>
+ </rich:panel>
+
+ <rich:panel rendered="#{not empty param.typeName}">
+ <f:facet name="header">Basic Details</f:facet>
+ <table>
+ <tr>
+ <td align="right"><b>Name:</b></td>
+ <td align="left">
+ <h:inputText id="name" value="#{CreateContentSourceUIBean.contentSource.name}" />
+ </td>
+ </tr>
+ <tr>
+ <td align="right"><b>Description:</b></td>
+ <td align="left">
+ <h:inputTextarea id="description" rows="3" cols="20" value="#{CreateContentSourceUIBean.contentSource.description}"/>
+ </td>
+ </tr>
+ <tr>
+ <td align="right"><b>Sync Schedule:</b></td>
+ <td align="left">
+ <h:inputText id="syncSchedule" value="#{CreateContentSourceUIBean.contentSource.syncSchedule}" />
+ </td>
+ </tr>
+ <tr>
+ <td align="right"><b>Lazy Load:</b></td>
+ <td align="left">
+ <h:selectBooleanCheckbox id="lazyLoad" value="#{CreateContentSourceUIBean.contentSource.lazyLoad}" />
+ </td>
+ </tr>
+ <tr>
+ <td align="right"><b>Download Mode:</b></td>
+ <td align="left">
+ <h:selectOneMenu id="downloadMode"
+ value="#{CreateContentSourceUIBean.selectedDownloadMode}">
+ <f:selectItems value="#{CreateContentSourceUIBean.downloadModes}" />
+ </h:selectOneMenu>
+ </td>
+ </tr>
+ </table>
+ </rich:panel>
+
+ <rich:panel rendered="#{not empty param.typeName}">
+ <f:facet name="header">Configuration</f:facet>
+ <table>
+ <tr>
+ <td>
+ <onc:config configurationDefinition="#{CreateContentSourceUIBean.contentSourceTypeConfigurationDefinition}"
+ configuration="#{CreateContentSourceUIBean.contentSource.configuration}"
+ readOnly="false"
+ nullConfigurationDefinitionMessage="#{CreateContentSourceUIBean.nullConfigurationDefinitionMessage}"
+ nullConfigurationMessage="#{CreateContentSourceUIBean.nullConfigurationMessage}"
+ nullConfigurationStyle="InfoBlock"/>
+ </td>
+ </tr>
+ </table>
+ </rich:panel>
+
+ <rich:panel rendered="#{not empty param.typeName}"
+ id="buttonGrid" columns="2" styleClass="buttons-table" columnClasses="button-cell">
+ <h:commandButton value="SAVE" action="#{CreateContentSourceUIBean.save}"
+ alt="save" styleClass="buttonmed" id="saveButton"/>
+ <h:commandButton value="CANCEL" action="#{CreateContentSourceUIBean.cancel}" immediate="true"
+ alt="cancel" styleClass="buttonmed" id="cancelButton"/>
+ </rich:panel>
+
+ </h:form>
+ </ui:define>
+</ui:composition>
+</html>
diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/content/createRepo-plain.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/content/createRepo-plain.xhtml
new file mode 100644
index 0000000..fd3f440
--- /dev/null
+++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/content/createRepo-plain.xhtml
@@ -0,0 +1,90 @@
+<?xml version="1.0"?>
+
+<!DOCTYPE html
+ PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml"
+ xmlns:h="http://java.sun.com/jsf/html"
+ xmlns:f="http://java.sun.com/jsf/core"
+ xmlns:ui="http://java.sun.com/jsf/facelets"
+ xmlns:c="http://java.sun.com/jstl/core"
+ xmlns:onc="http://jboss.org/on/component"
+ xmlns:onf="http://jboss.org/on/function"
+ xmlns:a4j="https://ajax4jsf.dev.java.net/ajax"
+ xmlns:rich="http://richfaces.ajax4jsf.org/rich">
+
+<ui:composition template="/rhq/resource/layout/main-plain.xhtml">
+
+ <ui:define name="content">
+
+ <ui:param name="pageTitle" value="Create New Repository"/>
+
+ <ui:define name="breadcrumbs">
+ <h:outputLink value="listRepos.xhtml">
+ ${msg["repo.list.breadcrumb"]}
+ </h:outputLink>
+ >
+ <h:outputLink value="createRepo.xhtml">
+ ${msg["repo.new.breadcrumb"]}
+ </h:outputLink>
+ </ui:define>
+
+
+ <h:messages showSummary="true"
+ showDetail="true"
+ infoClass="InfoBlock"
+ warnClass="WarnBlock"
+ errorClass="ErrorBlock"
+ fatalClass="FatalBlock"
+ globalOnly="true"
+ layout="table"
+ width="100%"/>
+
+ <h:form id="createRepoDetailsForm">
+
+ <rich:panel>
+ <f:facet name="header">Basic Details</f:facet>
+ <table>
+ <tr>
+ <td align="right">Name:</td>
+ <td align="left">
+ <h:inputText id="name" value="#{CreateRepoUIBean.repo.name}" />
+ </td>
+ </tr>
+ <tr>
+ <td align="right">Description:</td>
+ <td align="left">
+ <h:inputTextarea id="description" rows="3" cols="20" value="#{CreateRepoUIBean.repo.description}"/>
+ </td>
+ </tr>
+ <tr>
+ <td align="right">Private:</td>
+ <td align="left"><h:selectBooleanCheckbox id="isPrivate" value="#{CreateRepoUIBean.repo.private}"/></td>
+ </tr>
+ <tr>
+ <td align="right">Owner:</td>
+ <td align="left">
+ <h:selectOneMenu rendered="#{CreateRepoUIBean.repositoryManager}"
+ value="#{CreateRepoUIBean.repo.owner.name}">
+ <f:selectItems value="#{CreateRepoUIBean.availableOwners}" />
+ </h:selectOneMenu>
+ <h:outputText rendered="#{not CreateRepoUIBean.repositoryManager}"
+ value="#{CreateRepoUIBean.repo.owner.name}"/>
+ </td>
+ </tr>
+ </table>
+ </rich:panel>
+
+ <h:panelGrid id="buttonGrid" columns="2" styleClass="buttons-table" columnClasses="button-cell">
+ <h:commandButton value="SAVE" action="#{CreateRepoUIBean.save}"
+ alt="Save" styleClass="buttonmed" id="saveButton"/>
+ <h:commandButton value="CANCEL" action="#{CreateRepoUIBean.cancel}"
+ alt="Cancel" styleClass="buttonmed" id="cancelButton"/>
+ </h:panelGrid>
+
+ </h:form>
+ </ui:define>
+</ui:composition>
+
+</html>
diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/content/importRepos-plain.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/content/importRepos-plain.xhtml
new file mode 100644
index 0000000..a9880ae
--- /dev/null
+++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/content/importRepos-plain.xhtml
@@ -0,0 +1,118 @@
+<?xml version="1.0"?>
+<!DOCTYPE html
+ PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"
+ xmlns:h="http://java.sun.com/jsf/html"
+ xmlns:f="http://java.sun.com/jsf/core"
+ xmlns:ui="http://java.sun.com/jsf/facelets"
+ xmlns:c="http://java.sun.com/jstl/core"
+ xmlns:onc="http://jboss.org/on/component"
+ xmlns:onf="http://jboss.org/on/function"
+ xmlns:a4j="http://richfaces.org/a4j"
+ xmlns:rich="http://richfaces.ajax4jsf.org/rich">
+<ui:composition template="/rhq/resource/layout/main-plain.xhtml">
+ <ui:param name="id" value="${param.id}" />
+ <ui:param name="pageTitle" value="Import Repositories"/>
+ <ui:define name="breadcrumbs">
+ <h:outputLink value="listRepos.xhtml">
+ ${msg["repo.list.breadcrumb"]}
+ </h:outputLink>
+ >
+ <h:outputLink value="importRepos.xhtml">
+ Import
+ </h:outputLink>
+ </ui:define>
+ <ui:define name="content">
+
+ <h:form id="importRepoForm">
+ <input type="hidden" name="id" value="${param.id}"/>
+ <!-- CONTENT SOURCES -->
+ <rich:panel>
+ <f:facet name="header">
+ <h:outputText value="Content Sources"/>
+ </f:facet>
+ <h:panelGrid columns="1" width="100%">
+ <h:selectOneRadio
+ id="providers"
+ value="#{RepoImportUIBean.selectedProvider}"
+ layout="pageDirection">
+ <f:selectItems value="#{RepoImportUIBean.providerOptions}"/>
+ <a4j:support ajaxSingle="true" event="onchange" reRender="repoPanel"/>
+ </h:selectOneRadio>
+ </h:panelGrid>
+ </rich:panel>
+ <!-- REPOS -->
+ <rich:panel id="repoPanel">
+ <c:if test="#{RepoImportUIBean.selectedProvider != '0'}">
+ <f:facet name="header">
+ <h:outputText value="Available repositories provided by #{RepoImportUIBean.providerName}"/>
+ </f:facet>
+ <h:panelGrid columns="1" width="100%">
+ <ui:param name="repoModel" value="#{RepoImportUIBean.dataModel}"/>
+ <rich:dataTable id="repoTable"
+ rows="#{PageControl.ReposToImportList.pageSize}"
+ value="#{repoModel}"
+ var="item"
+ width="100%"
+ columnsWidth="1%, 99%"
+ headerClass="tableRowHeader"
+ footerClass="on-pager-footer"
+ onRowMouseOver="this.style.backgroundColor='#E7E7E7'"
+ onRowMouseOut="this.style.backgroundColor='#{a4jSkin.tableBackgroundColor}'">
+ <a4j:keepAlive beanName="RepoImportUIBean" />
+ <f:facet name="PageControlView">
+ <onc:paginationControl id="ReposToImportList" />
+ </f:facet>
+ <rich:column>
+ <f:facet name="header">
+ <onc:allSelect target="selectedRepos" />
+ </f:facet>
+ <onc:select rendered="#{RepoImportUIBean.selectedRepos[item.id] eq null}"
+ name="selectedRepos"
+ value="#{item.id}" />
+ </rich:column>
+ <rich:column rendered="#{param.debug}">
+ <f:facet name="header">
+ <onc:sortableColumnHeader sort="c.id">
+ <h:outputText styleClass="headerText" value="ID" />
+ </onc:sortableColumnHeader>
+ </f:facet>
+ <h:outputText value="#{item.id}"/>
+ </rich:column>
+ <rich:column>
+ <f:facet name="header">
+ <onc:sortableColumnHeader sort="c.name">
+ <h:outputText styleClass="headerText" value="Name" />
+ </onc:sortableColumnHeader>
+ </f:facet>
+ <h:outputLink value="repo.xhtml">
+ <f:param name="mode" value="view"/>
+ <f:param name="id" value="#{item.id}"/>
+ <h:outputText value="#{item.name}" />
+ </h:outputLink>
+ </rich:column>
+ <f:facet name="footer">
+ <rich:columnGroup>
+ <!-- colspan 6:5 for the debug 'id' column -->
+ <rich:column colspan="#{param.debug ? 6 : 5}" width="100%">
+ <onc:selectCommandButton
+ action="#{RepoImportUIBean.importSelected}"
+ value="IMPORT SELECTED"
+ target="selectedRepos"
+ styleClass="on-pager-button buttonsmall"/>
+ <ui:param name="paginationDataTableName" value="repoTable"/>
+ <ui:param name="paginationDataModel" value="#{repoModel}"/>
+ <ui:param name="paginationPageControl" value="#{PageControl.ReposToImportList}"/>
+ <ui:include src="../resource/include/pagination.xhtml"/>
+ </rich:column>
+ </rich:columnGroup>
+ </f:facet>
+ </rich:dataTable>
+ </h:panelGrid>
+ </c:if>
+ </rich:panel>
+ </h:form>
+ </ui:define>
+</ui:composition>
+</html>
diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/content/listContentProviders-plain.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/content/listContentProviders-plain.xhtml
new file mode 100644
index 0000000..ca72d1d
--- /dev/null
+++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/content/listContentProviders-plain.xhtml
@@ -0,0 +1,171 @@
+<?xml version="1.0"?>
+
+<!DOCTYPE html
+ PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml"
+ xmlns:h="http://java.sun.com/jsf/html"
+ xmlns:f="http://java.sun.com/jsf/core"
+ xmlns:ui="http://java.sun.com/jsf/facelets"
+ xmlns:c="http://java.sun.com/jstl/core"
+ xmlns:onc="http://jboss.org/on/component"
+ xmlns:rich="http://richfaces.ajax4jsf.org/rich">
+
+<ui:composition template="/rhq/resource/layout/main-plain.xhtml">
+
+ <ui:param name="pageTitle" value="Content Sources"/>
+
+ <ui:define name="breadcrumbs">
+ <h:outputLink value="listContentProviders-plain.xhtml">
+ ${msg["contentprovider.list.breadcrumb"]}
+ </h:outputLink>
+ </ui:define>
+
+ <ui:define name="content">
+
+ <h:form id="contentProvidersListForm">
+
+ <rich:panel>
+ <f:facet name="header">
+ <h:outputText value="Content Sources"/>
+ </f:facet>
+
+ <h:panelGrid columns="1" width="100%">
+
+ <ui:param name="contentProvidersDataModel" value="#{ListContentSourcesUIBean.dataModel}"/>
+ <rich:dataTable id="contentProvidersDataTable"
+ rows="#{PageControl.ContentSourcesList.pageSize}"
+ value="#{contentProvidersDataModel}"
+ var="item"
+ width="100%"
+ columnsWidth="1%, 20%, 15%, 15%, 9%, 9%"
+ headerClass="tableRowHeader"
+ footerClass="on-pager-footer"
+ onRowMouseOver="this.style.backgroundColor='#E7E7E7'"
+ onRowMouseOut="this.style.backgroundColor='#{a4jSkin.tableBackgroundColor}'">
+
+
+ <f:facet name="PageControlView">
+ <onc:paginationControl id="ContentSourcesList" />
+ </f:facet>
+
+ <rich:column>
+ <f:facet name="header">
+ <onc:allSelect target="selectedContentProviders" />
+ </f:facet>
+
+ <onc:select name="selectedContentProviders" value="#{item.id}" />
+ </rich:column>
+
+ <rich:column rendered="#{param.debug}">
+ <f:facet name="header">
+ <onc:sortableColumnHeader sort="cs.id">
+ <h:outputText styleClass="headerText" value="ID" />
+ </onc:sortableColumnHeader>
+ </f:facet>
+
+ <h:outputText value="#{item.id}"/>
+ </rich:column>
+
+ <rich:column>
+ <f:facet name="header">
+ <onc:sortableColumnHeader sort="cs.name">
+ <h:outputText styleClass="headerText" value="Name" />
+ </onc:sortableColumnHeader>
+ </f:facet>
+
+ <h:outputLink value="contentProvider-plain.xhtml">
+ <f:param name="mode" value="view"/>
+ <f:param name="id" value="#{item.id}"/>
+ <h:outputText value="#{item.name}" />
+ </h:outputLink>
+ </rich:column>
+
+ <rich:column>
+ <f:facet name="header">
+ <onc:sortableColumnHeader sort="cs.creationDate">
+ <h:outputText styleClass="headerText" value="Date Created" />
+ </onc:sortableColumnHeader>
+ </f:facet>
+
+ <h:outputText value="#{item.creationDate}">
+ <f:convertDateTime pattern="M/d/yy, h:mm:ss aa, zzz" timeZone="#{ServerInfoUIBean.timeZone}"/>
+ </h:outputText>
+ </rich:column>
+
+ <rich:column>
+ <f:facet name="header">
+ <onc:sortableColumnHeader sort="cs.lastModifiedDate">
+ <h:outputText styleClass="headerText" value="Date Modified" />
+ </onc:sortableColumnHeader>
+ </f:facet>
+
+ <h:outputText value="#{item.lastModifiedDate}">
+ <f:convertDateTime pattern="M/d/yy, h:mm:ss aa, zzz" timeZone="#{ServerInfoUIBean.timeZone}"/>
+ </h:outputText>
+ </rich:column>
+
+ <rich:column>
+ <f:facet name="header">
+ <onc:sortableColumnHeader sort="cs.lazyLoad">
+ <h:outputText styleClass="headerText" value="Lazy Load?" />
+ </onc:sortableColumnHeader>
+ </f:facet>
+
+ <h:outputText value="#{item.lazyLoad}"/>
+ </rich:column>
+
+ <rich:column>
+ <f:facet name="header">
+ <onc:sortableColumnHeader sort="cs.downloadMode">
+ <h:outputText styleClass="headerText" value="Download Mode" />
+ </onc:sortableColumnHeader>
+ </f:facet>
+
+ <h:outputText value="#{item.downloadMode}"/>
+ </rich:column>
+
+ <rich:column>
+ <f:facet name="header">
+ <onc:sortableColumnHeader sort="cs.description">
+ <h:outputText styleClass="headerText" value="Description" />
+ </onc:sortableColumnHeader>
+ </f:facet>
+
+ <h:outputText value="#{item.description}"/>
+ </rich:column>
+
+ <f:facet name="footer">
+ <rich:columnGroup>
+ <!-- colspan 8:7 for the debug 'id' column -->
+ <rich:column colspan="#{param.debug ? 8 : 7}" width="100%">
+ <h:commandButton action="#{ListContentSourcesUIBean.createNewContentSource}"
+ value="CREATE NEW" styleClass="on-pager-button buttonsmall">
+ <f:param name="mode" value="new"/>
+ </h:commandButton>
+
+ <onc:selectCommandButton action="#{ListContentSourcesUIBean.deleteSelectedContentSources}"
+ value="DELETE SELECTED" target="selectedContentProviders" styleClass="on-pager-button buttonsmall"/>
+ <onc:selectCommandButton action="#{ListContentSourcesUIBean.syncSelectedContentSources}"
+ value="SYNC SELECTED" target="selectedContentProviders" styleClass="on-pager-button buttonsmall"/>
+
+ <ui:param name="paginationDataTableName" value="contentProvidersDataTable"/>
+ <ui:param name="paginationDataModel" value="#{contentProvidersDataModel}"/>
+ <ui:param name="paginationPageControl" value="#{PageControl.ContentSourcesList}"/>
+ <ui:include src="../resource/include/pagination.xhtml"/>
+ </rich:column>
+ </rich:columnGroup>
+ </f:facet>
+
+ </rich:dataTable>
+
+ </h:panelGrid>
+
+ </rich:panel>
+ </h:form>
+ </ui:define>
+
+</ui:composition>
+
+</html>
diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/content/listRepos-plain.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/content/listRepos-plain.xhtml
new file mode 100644
index 0000000..70a4837
--- /dev/null
+++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/content/listRepos-plain.xhtml
@@ -0,0 +1,151 @@
+<ui:composition template="/rhq/resource/layout/main-plain.xhtml"
+ xmlns="http://www.w3.org/1999/xhtml"
+ xmlns:h="http://java.sun.com/jsf/html"
+ xmlns:f="http://java.sun.com/jsf/core"
+ xmlns:ui="http://java.sun.com/jsf/facelets"
+ xmlns:c="http://java.sun.com/jstl/core"
+ xmlns:onc="http://jboss.org/on/component"
+ xmlns:a4j="http://richfaces.org/a4j"
+ xmlns:rich="http://richfaces.ajax4jsf.org/rich">
+
+ <ui:define name="content">
+
+ <ui:param name="pageTitle" value="Repositories"/>
+
+ <ui:define name="breadcrumbs">
+ <h:outputLink value="listRepos.xhtml">
+ ${msg["repo.list.breadcrumb"]}
+ </h:outputLink>
+ </ui:define>
+
+
+ <h:form id="reposListForm">
+
+ <rich:panel>
+ <f:facet name="header">
+ <h:outputText value="Repositories"/>
+ </f:facet>
+
+ <h:panelGrid columns="1" width="100%">
+
+ <ui:param name="reposDataModel" value="#{ListReposUIBean.dataModel}"/>
+ <rich:dataTable id="reposDataTable"
+ rows="#{PageControl.ReposList.pageSize}"
+ value="#{reposDataModel}"
+ var="item"
+ width="100%"
+ columnsWidth="1%, 20%, 15%, 15%"
+ headerClass="tableRowHeader"
+ footerClass="on-pager-footer"
+ onRowMouseOver="this.style.backgroundColor='#E7E7E7'"
+ onRowMouseOut="this.style.backgroundColor='#{a4jSkin.tableBackgroundColor}'">
+
+
+ <f:facet name="PageControlView">
+ <onc:paginationControl id="ReposList" />
+ </f:facet>
+
+ <rich:column>
+ <f:facet name="header">
+ <onc:allSelect target="selectedRepos" />
+ </f:facet>
+
+ <onc:select name="selectedRepos" value="#{item.id}" />
+ </rich:column>
+
+ <rich:column rendered="#{param.debug}">
+ <f:facet name="header">
+ <onc:sortableColumnHeader sort="c.id">
+ <h:outputText styleClass="headerText" value="ID" />
+ </onc:sortableColumnHeader>
+ </f:facet>
+
+ <h:outputText value="#{item.id}"/>
+ </rich:column>
+
+ <rich:column>
+ <f:facet name="header">
+ <onc:sortableColumnHeader sort="c.name">
+ <h:outputText styleClass="headerText" value="Name" />
+ </onc:sortableColumnHeader>
+ </f:facet>
+
+ <h:outputLink value="repo-plain.xhtml">
+ <f:param name="mode" value="view"/>
+ <f:param name="id" value="#{item.id}"/>
+ <h:outputText value="#{item.name}" />
+ </h:outputLink>
+ </rich:column>
+
+ <rich:column>
+ <f:facet name="header">
+ <onc:sortableColumnHeader sort="c.creationDate">
+ <h:outputText styleClass="headerText" value="Date Created" />
+ </onc:sortableColumnHeader>
+ </f:facet>
+
+ <h:outputText value="#{item.creationDate}">
+ <f:convertDateTime pattern="M/d/yy, h:mm:ss aa, zzz" timeZone="#{ServerInfoUIBean.timeZone}"/>
+ </h:outputText>
+ </rich:column>
+
+ <rich:column id="statusid">
+ <f:facet name="header">
+ <onc:sortableColumnHeader sort="c.lastModifiedDate">
+ <h:outputText styleClass="headerText" value="Sync Status" />
+ </onc:sortableColumnHeader>
+ </f:facet>
+
+ <a4j:region>
+ <a4j:poll id="poll" interval="5000" reRender="statusid" />
+ <h:outputText styleClass="headerText" value="#{item.syncStatus}" />
+ </a4j:region>
+ </rich:column>
+
+ <rich:column>
+ <f:facet name="header">
+ <onc:sortableColumnHeader sort="c.description">
+ <h:outputText styleClass="headerText" value="Description" />
+ </onc:sortableColumnHeader>
+ </f:facet>
+
+ <h:outputText value="#{item.description}"/>
+ </rich:column>
+
+ <f:facet name="footer">
+ <rich:columnGroup>
+ <!-- colspan 6:5 for the debug 'id' column -->
+ <rich:column colspan="#{param.debug ? 6 : 5}" width="100%">
+ <h:commandButton action="#{ListReposUIBean.createNewRepo}"
+ value="CREATE NEW" styleClass="on-pager-button buttonsmall">
+ <f:param name="mode" value="new"/>
+ </h:commandButton>
+
+ <h:commandButton action="#{ListReposUIBean.importRepos}"
+ value="IMPORT" styleClass="on-pager-button buttonsmall">
+ <f:param name="mode" value="new"/>
+ </h:commandButton>
+
+ <onc:selectCommandButton action="#{ListReposUIBean.deleteSelectedRepos}"
+ value="DELETE SELECTED" target="selectedRepos" styleClass="on-pager-button buttonsmall"/>
+ <onc:selectCommandButton action="#{ListReposUIBean.syncSelectedRepos}"
+ value="SYNC SELECTED" target="selectedRepos" styleClass="on-pager-button buttonsmall"/>
+
+ <ui:param name="paginationDataTableName" value="reposDataTable"/>
+ <ui:param name="paginationDataModel" value="#{reposDataModel}"/>
+ <ui:param name="paginationPageControl" value="#{PageControl.ReposList}"/>
+ <ui:include src="../resource/include/pagination.xhtml"/>
+ </rich:column>
+ </rich:columnGroup>
+ </f:facet>
+
+ </rich:dataTable>
+
+ </h:panelGrid>
+
+ </rich:panel>
+
+ </h:form>
+ </ui:define>
+
+</ui:composition>
diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/content/packageVersion-plain.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/content/packageVersion-plain.xhtml
new file mode 100644
index 0000000..0fef6a5
--- /dev/null
+++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/content/packageVersion-plain.xhtml
@@ -0,0 +1,192 @@
+<?xml version="1.0"?>
+
+<!DOCTYPE html
+ PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml"
+ xmlns:h="http://java.sun.com/jsf/html"
+ xmlns:f="http://java.sun.com/jsf/core"
+ xmlns:ui="http://java.sun.com/jsf/facelets"
+ xmlns:c="http://java.sun.com/jstl/core"
+ xmlns:onc="http://jboss.org/on/component"
+ xmlns:onf="http://jboss.org/on/function"
+ xmlns:rich="http://richfaces.ajax4jsf.org/rich">
+
+<ui:composition template="/rhq/resource/layout/main-plain.xhtml">
+
+ <ui:param name="pageTitle" value="Package Version '#{PackageVersionDetailsUIBean.packageVersionComposite.packageVersion.displayName}'"/>
+ <ui:param name="item" value="#{PackageVersionDetailsUIBean.packageVersionComposite}" />
+ <ui:param name="id" value="${param.id}" />
+ <ui:param name="content_source_id" value="${param.content_source_id}" />
+ <ui:param name="content_source_name" value="${param.content_source_name}" />
+
+ <ui:define name="breadcrumbs">
+ <h:outputLink value="listContentProviders.xhtml">
+ ${msg["contentprovider.list.breadcrumb"]}
+ </h:outputLink>
+ >
+ <h:outputLink value="contentProvider.xhtml">
+ #{content_source_name}
+ <f:param name="mode" value="view" />
+ <f:param name="id" value="#{content_source_id}" />
+ </h:outputLink>
+ >
+ <h:outputLink value="packageVersion.xhtml">
+ #{item.packageVersion.displayName}
+ <f:param name="id" value="#{item.packageVersion.id}" />
+ <f:param name="content_source_id" value="#{content_source_id}"/>
+ <f:param name="content_source_name" value="#{content_source_name}"/>
+ </h:outputLink>
+ </ui:define>
+
+ <ui:define name="content">
+
+ <h:form id="repoDetailsForm">
+ <input type="hidden" name="id" value="${param.id}"/>
+
+ <rich:panel>
+ <f:facet name="header">Package Details</f:facet>
+
+ <table cellspacing="0" cellpadding="4" width="100%">
+ <tr class="package-details-even-row">
+ <td align="right" class="package-details-key-column"><b>Package Name:</b></td>
+ <td class="package-details-value-column">
+ <h:outputText value="#{item.packageVersion.displayName}" rendered="#{!empty item.packageVersion.displayName}"/>
+ <h:outputText value="#{item.packageName}" rendered="#{empty item.packageVersion.displayName}"/>
+ </td>
+ </tr>
+ <tr class="package-details-odd-row">
+ <td class="package-details-key-column"><b>Package Type:</b></td>
+ <td class="package-details-value-column">
+ <h:outputText value="#{item.packageVersion.generalPackage.packageType.displayName}"
+ rendered="#{!empty item.packageVersion.generalPackage.packageType.displayName}"/>
+ <h:outputText value="#{item.packageVersion.generalPackage.packageType.name}"
+ rendered="#{empty item.packageVersion.generalPackage.packageType.displayName}"/>
+ </td>
+ </tr>
+ <tr class="package-details-even-row">
+ <td class="package-details-key-column"><b>Version:</b></td>
+ <td class="package-details-value-column">
+ <h:outputText value="#{item.packageVersion.displayVersion}" />
+ </td>
+ </tr>
+ <tr class="package-details-odd-row">
+ <td class="package-details-key-column"><b>Architecture:</b></td>
+ <td class="package-details-value-column">
+ <h:outputText value="#{item.packageVersion.architecture.name}" />
+ </td>
+ </tr>
+ <tr class="package-details-even-row">
+ <td class="package-details-key-column"><b>Category:</b></td>
+ <td class="package-details-value-column">
+ <h:outputText value="#{item.packageCategory}" />
+ </td>
+ </tr>
+ <tr class="package-details-odd-row">
+ <td class="package-details-key-column"><b>Classification:</b></td>
+ <td class="package-details-value-column">
+ <h:outputText value="#{item.packageClassification}" />
+ </td>
+ </tr>
+ <tr class="package-details-even-row">
+ <td class="package-details-key-column"><b>Short Description:</b></td>
+ <td class="package-details-value-column">
+ <h:outputText value="#{item.packageVersion.shortDescription}" escape="false"/>
+ </td>
+ </tr>
+ <tr class="package-details-odd-row">
+ <td class="package-details-key-column"><b>Long Description:</b></td>
+ <td class="package-details-value-column">
+ <h:outputText value="#{item.packageVersion.longDescription}" escape="false"/>
+ </td>
+ </tr>
+ <tr class="package-details-even-row">
+ <td class="package-details-key-column"><b>File Name:</b></td>
+ <td class="package-details-value-column">
+ <h:outputText value="#{item.packageVersion.fileName}" />
+ </td>
+ </tr>
+ <tr class="package-details-odd-row">
+ <td class="package-details-key-column"><b>File Size:</b></td>
+ <td class="package-details-value-column">
+ <h:outputText value="#{item.packageVersion.fileSize}" />
+ </td>
+ </tr>
+ <tr class="package-details-even-row">
+ <td class="package-details-key-column"><b>MD5:</b></td>
+ <td class="package-details-value-column">
+ <h:outputText value="#{item.packageVersion.MD5}" />
+ </td>
+ </tr>
+ <tr class="package-details-odd-row">
+ <td class="package-details-key-column"><b>SHA256:</b></td>
+ <td class="package-details-value-column">
+ <h:outputText value="#{item.packageVersion.SHA256}" />
+ </td>
+ </tr>
+ <tr class="package-details-even-row">
+ <td class="package-details-key-column"><b>File Created Date:</b></td>
+ <td class="package-details-value-column">
+ <h:outputText value="#{item.packageVersion.fileCreatedDate}">
+ <f:convertDateTime pattern="M/d/yy, h:mm:ss aa, zzz" timeZone="#{ServerInfoUIBean.timeZone}"/>
+ </h:outputText>
+ </td>
+ </tr>
+ <tr class="package-details-odd-row">
+ <td class="package-details-key-column"><b>License Name:</b></td>
+ <td class="package-details-value-column">
+ <h:outputText value="#{item.packageVersion.licenseName}" />
+ </td>
+ </tr>
+ <tr class="package-details-even-row">
+ <td class="package-details-key-column"><b>License Version:</b></td>
+ <td class="package-details-value-column">
+ <h:outputText value="#{item.packageVersion.licenseVersion}" />
+ </td>
+ </tr>
+ <tr class="package-details-odd-row">
+ <td class="package-details-key-column"><b>Package Content Downloaded:</b></td>
+ <td class="package-details-value-column">
+ <h:outputText value="#{item.packageBitsAvailable}" />
+ </td>
+ </tr>
+ <tr class="package-details-even-row">
+ <td class="package-details-key-column"><b>Package Content Stored in the Database:</b></td>
+ <td class="package-details-value-column">
+ <h:outputText value="#{item.packageBitsInDatabase}" />
+ </td>
+ </tr>
+
+ <c:if test="#{!empty item.extraProperties}">
+ <c:forEach items="#{item.extraProperties.properties}" var="prop" varStatus="rowCounter">
+
+ <c:choose>
+ <c:when test="#{rowCounter.index % 2 == 1}">
+ <c:set var="rowStyle" scope="page" value="package-details-even-row"/>
+ </c:when>
+ <c:otherwise>
+ <c:set var="rowStyle" scope="page" value="package-details-odd-row"/>
+ </c:otherwise>
+ </c:choose>
+
+ <tr class="${rowStyle}">
+ <td class="package-details-key-column"><b><h:outputText value="#{prop.name}"/></b></td>
+ <td class="package-details-value-column">
+ <h:outputText value="#{prop.stringValue}" escape="false"/>
+ </td>
+ </tr>
+
+ </c:forEach>
+ </c:if>
+
+ </table>
+
+ </rich:panel>
+
+ </h:form>
+
+ </ui:define>
+</ui:composition>
+
+</html>
diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/content/repo-plain.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/content/repo-plain.xhtml
new file mode 100644
index 0000000..7b7c974
--- /dev/null
+++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/content/repo-plain.xhtml
@@ -0,0 +1,893 @@
+<?xml version="1.0"?>
+
+<!DOCTYPE html
+ PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml"
+ xmlns:h="http://java.sun.com/jsf/html"
+ xmlns:f="http://java.sun.com/jsf/core"
+ xmlns:ui="http://java.sun.com/jsf/facelets"
+ xmlns:c="http://java.sun.com/jstl/core"
+ xmlns:onc="http://jboss.org/on/component"
+ xmlns:onf="http://jboss.org/on/function"
+ xmlns:s="http://jboss.com/products/seam/taglib"
+ xmlns:a4j="https://ajax4jsf.dev.java.net/ajax"
+ xmlns:rich="http://richfaces.ajax4jsf.org/rich">
+
+<ui:composition template="/rhq/resource/layout/main-plain.xhtml">
+
+ <ui:define name="content">
+
+ <h:form id="repoDetailsForm">
+ <input type="hidden" name="id" value="${param.id}" />
+ <input type="hidden" name="mode" value="${param.mode}" />
+
+ <rich:panel>
+ <f:facet name="header">Basic Details</f:facet>
+ <table>
+ <tr>
+ <td align="right"><b>Name:</b></td>
+ <td align="left"><h:inputText
+ rendered="${mode eq 'edit'}"
+ value="#{RepoDetailsUIBean.repo.name}" /> <h:outputText
+ rendered="${mode ne 'edit'}"
+ value="#{RepoDetailsUIBean.repo.name}" /></td>
+ </tr>
+ <tr>
+ <td align="right"><b>Description:</b></td>
+ <td align="left"><h:inputTextarea
+ rendered="${mode eq 'edit'}" rows="3" cols="20"
+ value="#{RepoDetailsUIBean.repo.description}" /> <h:outputText
+ rendered="${mode ne 'edit'}"
+ value="#{RepoDetailsUIBean.repo.description}" /></td>
+ </tr>
+ <tr>
+ <td align="right"><b>Private:</b></td>
+ <td align="left"><h:selectBooleanCheckbox
+ rendered="${mode eq 'edit'}" value="#{CreateRepoUIBean.repo.private}"/>
+ <h:outputText rendered="${mode ne 'edit'}" value="#{RepoDetailsUIBean.repo.private}" />
+ </td>
+ </tr>
+ <tr>
+ <td align="right"><b>Owner:</b></td>
+ <td align="left">
+ <h:selectOneMenu rendered="${mode eq 'edit' and RepoDetailsUIBean.repositoryManager}"
+ value="#{RepoDetailsUIBean.repo.owner.name}">
+ <f:selectItems value="#{RepoDetailsUIBean.availableOwners}"/>
+ </h:selectOneMenu>
+ <h:outputText rendered="${mode ne 'edit' or not RepoDetailsUIBean.repositoryManager}" value="#{RepoDetailsUIBean.repo.owner.name}"/>
+ </td>
+ </tr>
+ <tr>
+ <td align="right"><b>Sync Schedule:</b></td>
+ <td align="left"><h:inputText
+ rendered="${RepoDetailsUIBean.repositoryManager and mode eq 'edit'}"
+ value="#{RepoDetailsUIBean.repo.syncSchedule}" /> <h:outputText
+ rendered="${mode ne 'edit' or not RepoDetailsUIBean.repositoryManager}"
+ value="#{RepoDetailsUIBean.repo.syncSchedule}" /></td>
+ </tr>
+ <tr>
+ <td align="right"><b>Creation Date:</b></td>
+ <td align="left"><h:outputText
+ value="#{RepoDetailsUIBean.repo.creationDate}">
+ <f:convertDateTime pattern="M/d/yy, h:mm:ss aa, zzz"
+ timeZone="#{ServerInfoUIBean.timeZone}" />
+ </h:outputText></td>
+ </tr>
+ <tr>
+ <td align="right"><b>Last Modified Date:</b></td>
+ <td align="left"><h:outputText
+ value="#{RepoDetailsUIBean.repo.lastModifiedDate}">
+ <f:convertDateTime pattern="M/d/yy, h:mm:ss aa, zzz"
+ timeZone="#{ServerInfoUIBean.timeZone}" />
+ </h:outputText></td>
+ </tr>
+
+ <!-- ******* START AJAX REFRESH/POLLING BLOCK ****** -->
+ <a4j:region>
+ <a4j:poll id="statusPoll" interval="1005"
+ reRender="syncPercent,syncStatus" />
+ <tr>
+ <td align="right"><b>Synchronization Status:</b></td>
+ <td align="left"><c:choose>
+ <c:when
+ test="#{RepoDetailsUIBean.percentComplete != '100'}">
+ <h:outputText id="syncStatus"
+ value="#{RepoDetailsUIBean.syncStatus}" />
+ </c:when>
+ <c:otherwise>
+ <h:outputText id="syncStatus"
+ value="#{RepoDetailsUIBean.syncStatus}" />
+ </c:otherwise>
+ </c:choose></td>
+ </tr>
+ <tr>
+ <td align="right"><b>Raw Percentage:</b></td>
+ <td align="left">
+ <h:outputText id="syncPercent"
+ value="#{RepoDetailsUIBean.percentComplete}" />
+ </td>
+ </tr>
+ <tr>
+ <td align="right"><b>Synchronization Progress:</b></td>
+ <td align="left">
+ <c:choose>
+ <c:when
+ test="#{RepoDetailsUIBean.currentlySyncing}">
+ <rich:progressBar id="syncProgress"
+ value="#{RepoDetailsUIBean.percentComplete}"
+ label="#{RepoDetailsUIBean.percentComplete} %"
+ interval="999" minValue="-1" maxValue="99">
+ <f:facet name="complete">
+ <h:outputText value="Synchronizing Complete" />
+ </f:facet>
+ </rich:progressBar>
+ </c:when>
+ <c:otherwise>
+ Not Synching
+ </c:otherwise>
+ </c:choose>
+ </td>
+ </tr>
+ <!--
+ <tr>
+ <td align="right"><b>Synchronization Progress:</b></td>
+ <td align="left">
+ <rich:progressBar id="syncProgress"
+ value="#{RepoDetailsUIBean.percentComplete}"
+ label="#{RepoDetailsUIBean.percentComplete} %"
+ interval="999" minValue="-1" maxValue="99">
+ <f:facet name="complete">
+ <h:outputText value="Synchronizing Complete" />
+ </f:facet>
+ <f:facet name="initial">
+ <h:outputText value="Not Synching" />
+ </f:facet>
+ </rich:progressBar>
+ </td>
+ </tr>
+ -->
+ <tr>
+ <td align="right"><b>Synchronization Results:</b></td>
+ <td align="left"><h:outputLink
+ rendered="#{RepoDetailsUIBean.syncResults.results ne null}"
+ value="#" id="resultsLink">
+ <h:outputText value="Click here to view..." />
+ <rich:componentControl for="resultsModalPanel"
+ attachTo="resultsLink" operation="show" event="onclick" />
+ </h:outputLink> <h:outputText rendered="#{syncitem.results eq null}"
+ value="" /> <rich:modalPanel id="resultsModalPanel"
+ width="640" height="300" style="overflow: auto;">
+ <f:facet name="header">
+ <h:panelGroup>
+ <h:outputText value="Results" />
+ </h:panelGroup>
+ </f:facet>
+ <f:facet name="controls">
+ <h:panelGroup>
+ <h:graphicImage value="/images/close.png"
+ style="cursor:pointer"
+ id="resultsModelPanelHideLink" />
+ <rich:componentControl for="resultsModalPanel"
+ attachTo="resultsModelPanelHideLink"
+ operation="hide" event="onclick" />
+ </h:panelGroup>
+ </f:facet>
+ <PRE><h:outputText value="#{RepoDetailsUIBean.syncResults.results}" /></PRE>
+ </rich:modalPanel></td>
+ </tr>
+ </a4j:region>
+ <!-- ******* END AJAX REFRESH/POLLING BLOCK ****** -->
+ </table>
+ </rich:panel>
+
+ <h:panelGrid columns="3" styleClass="buttons-table"
+ columnClasses="button-cell">
+ <h:commandButton rendered="${mode ne 'edit' and RepoDetailsUIBean.editable}" value="EDIT"
+ action="#{RepoDetailsUIBean.edit}" alt="Edit"
+ styleClass="buttonmed" id="editButton" />
+ <h:commandButton rendered="${mode ne 'edit' and not RepoDetailsUIBean.currentlySyncing and RepoDetailsUIBean.repositoryManager}"
+ value="SYNCHRONIZE" action="#{RepoDetailsUIBean.sync}"
+ alt="Synchronize" styleClass="buttonmed" id="syncButton" />
+ <h:commandButton rendered="#{RepoDetailsUIBean.repositoryManager and RepoDetailsUIBean.currentlySyncing}"
+ value="CANCEL SYNCH" action="#{RepoDetailsUIBean.cancelSync}"
+ alt="Cancel Synch" styleClass="buttonmed" id="cancelSyncButton" />
+ <h:commandButton rendered="${mode eq 'edit'}" value="SAVE"
+ action="#{RepoDetailsUIBean.save}" alt="Save"
+ styleClass="buttonmed" id="saveButton" />
+ <h:commandButton rendered="${mode eq 'edit'}" value="CANCEL"
+ action="#{RepoDetailsUIBean.cancel}" alt="Cancel"
+ styleClass="buttonmed" id="cancelButton" />
+ </h:panelGrid>
+
+ </h:form>
+
+ <!-- CONTENT SOURCE LIST -->
+
+ <h:form id="repoContentProvidersListForm" rendered="#{RepoDetailsUIBean.repositoryManager}">
+ <input type="hidden" name="id" value="${param.id}" />
+ <input type="hidden" name="mode" value="${param.mode}" />
+
+ <rich:panel>
+ <f:facet name="header">
+ <h:outputText
+ value="Content Sources Associated with This Repository" />
+ </f:facet>
+
+ <h:panelGrid columns="1" width="100%">
+
+ <ui:param name="repoContentProvidersDataModel"
+ value="#{RepoContentSourcesUIBean.dataModel}" />
+ <rich:dataTable id="repoContentProvidersDataTable"
+ rows="#{PageControl.RepoContentSourcesList.pageSize}"
+ value="#{repoContentProvidersDataModel}"
+ var="contentprovideritem" width="100%"
+ columnsWidth="1%, 20%, 15%, 15%, 9%, 9%"
+ headerClass="tableRowHeader" footerClass="on-pager-footer"
+ onRowMouseOver="this.style.backgroundColor='#E7E7E7'"
+ onRowMouseOut="this.style.backgroundColor='#{a4jSkin.tableBackgroundColor}'">
+
+
+ <f:facet name="PageControlView">
+ <onc:paginationControl id="RepoContentSourcesList" />
+ </f:facet>
+
+ <rich:column>
+ <f:facet name="header">
+ <onc:allSelect target="selectedRepoContentProviders" />
+ </f:facet>
+
+ <onc:select name="selectedRepoContentProviders"
+ value="#{contentprovideritem.id}" />
+ </rich:column>
+
+ <rich:column rendered="#{param.debug}">
+ <f:facet name="header">
+ <onc:sortableColumnHeader sort="cs.id">
+ <h:outputText styleClass="headerText" value="ID" />
+ </onc:sortableColumnHeader>
+ </f:facet>
+ <h:outputText value="#{contentprovideritem.id}" />
+ </rich:column>
+
+ <rich:column>
+ <f:facet name="header">
+ <onc:sortableColumnHeader sort="cs.name">
+ <h:outputText styleClass="headerText" value="Name" />
+ </onc:sortableColumnHeader>
+ </f:facet>
+ <h:outputLink value="contentProvider.xhtml">
+ <f:param name="mode" value="view" />
+ <f:param name="id" value="#{contentprovideritem.id}" />
+ <h:outputText value="#{contentprovideritem.name}" />
+ </h:outputLink>
+ </rich:column>
+
+ <rich:column>
+ <f:facet name="header">
+ <onc:sortableColumnHeader sort="cs.creationDate">
+ <h:outputText styleClass="headerText"
+ value="Date Created" />
+ </onc:sortableColumnHeader>
+ </f:facet>
+ <h:outputText value="#{contentprovideritem.creationDate}">
+ <f:convertDateTime pattern="M/d/yy, h:mm:ss aa, zzz"
+ timeZone="#{ServerInfoUIBean.timeZone}" />
+ </h:outputText>
+ </rich:column>
+
+ <rich:column>
+ <f:facet name="header">
+ <onc:sortableColumnHeader sort="cs.lastModifiedDate">
+ <h:outputText styleClass="headerText"
+ value="Date Modified" />
+ </onc:sortableColumnHeader>
+ </f:facet>
+ <h:outputText
+ value="#{contentprovideritem.lastModifiedDate}">
+ <f:convertDateTime pattern="M/d/yy, h:mm:ss aa, zzz"
+ timeZone="#{ServerInfoUIBean.timeZone}" />
+ </h:outputText>
+ </rich:column>
+
+ <rich:column>
+ <f:facet name="header">
+ <onc:sortableColumnHeader sort="cs.lazyLoad">
+ <h:outputText styleClass="headerText"
+ value="Lazy Load?" />
+ </onc:sortableColumnHeader>
+ </f:facet>
+ <h:outputText value="#{contentprovideritem.lazyLoad}" />
+ </rich:column>
+
+ <rich:column>
+ <f:facet name="header">
+ <onc:sortableColumnHeader sort="cs.downloadMode">
+ <h:outputText styleClass="headerText"
+ value="Download Mode" />
+ </onc:sortableColumnHeader>
+ </f:facet>
+ <h:outputText value="#{contentprovideritem.downloadMode}" />
+ </rich:column>
+
+ <rich:column>
+ <f:facet name="header">
+ <onc:sortableColumnHeader sort="cs.description">
+ <h:outputText styleClass="headerText"
+ value="Description" />
+ </onc:sortableColumnHeader>
+ </f:facet>
+ <h:outputText value="#{contentprovideritem.description}" />
+ </rich:column>
+
+ <f:facet name="footer">
+ <rich:columnGroup>
+ <!-- colspan 8:7 for the debug 'id' column -->
+ <rich:column colspan="#{param.debug ? 8 : 7}"
+ width="100%">
+
+ <!-- The ability to associate/disassociate repos with content sources is not needed for JON. -->
+ <h:commandButton
+ action="#{RepoContentSourcesUIBean.associateWithContentProviders}"
+ value="ASSOCIATE..."
+ styleClass="on-pager-button buttonsmall" />
+ <onc:selectCommandButton
+ action="#{RepoContentSourcesUIBean.disassociateWithContentProviders}"
+ value="DISASSOCIATE SELECTED"
+ target="selectedRepoContentProviders"
+ styleClass="on-pager-button buttonsmall" />
+
+ <ui:param name="paginationDataTableName"
+ value="repoContentProvidersDataTable" />
+ <ui:param name="paginationDataModel"
+ value="#{repoContentProvidersDataModel}" />
+ <ui:param name="paginationPageControl"
+ value="#{PageControl.RepoContentSourcesList}" />
+ <ui:include src="../resource/include/pagination.xhtml" />
+ </rich:column>
+ </rich:columnGroup>
+ </f:facet>
+
+ </rich:dataTable>
+
+ </h:panelGrid>
+
+ </rich:panel>
+ </h:form>
+
+ <!-- SUBSCRIBER RESOURCE LIST -->
+
+ <h:form id="repoResourcesListForm" rendered="#{RepoDetailsUIBean.repositoryManager}">
+ <input type="hidden" name="id" value="${param.id}" />
+ <input type="hidden" name="mode" value="${param.mode}" />
+
+ <rich:panel>
+ <f:facet name="header">
+ <h:outputText value="Resources Subscribed To This Repository" />
+ </f:facet>
+
+ <h:panelGrid columns="1" width="100%">
+
+ <ui:param name="repoResourcesDataModel"
+ value="#{RepoResourcesUIBean.dataModel}" />
+ <rich:dataTable id="repoResourcesDataTable"
+ rows="#{PageControl.RepoResourcesList.pageSize}"
+ value="#{repoResourcesDataModel}" var="resourceitem"
+ width="100%" columnsWidth="1%, 20%, 15%, 15%"
+ headerClass="tableRowHeader" footerClass="on-pager-footer"
+ onRowMouseOver="this.style.backgroundColor='#E7E7E7'"
+ onRowMouseOut="this.style.backgroundColor='#{a4jSkin.tableBackgroundColor}'">
+
+
+ <f:facet name="PageControlView">
+ <onc:paginationControl id="RepoResourcesList" />
+ </f:facet>
+
+ <rich:column>
+ <f:facet name="header">
+ <onc:allSelect target="selectedRepoResources" />
+ </f:facet>
+
+ <onc:select name="selectedRepoResources"
+ value="#{resourceitem.original.id}" />
+ </rich:column>
+
+ <rich:column rendered="#{param.debug}">
+ <f:facet name="header">
+ <onc:sortableColumnHeader sort="rc.resource.id">
+ <h:outputText styleClass="headerText" value="ID" />
+ </onc:sortableColumnHeader>
+ </f:facet>
+
+ <h:outputText value="#{resourceitem.original.id}" />
+ </rich:column>
+
+ <rich:column>
+ <f:facet name="header">
+ <onc:sortableColumnHeader sort="rc.resource.name">
+ <h:outputText styleClass="headerText" value="Resource" />
+ </onc:sortableColumnHeader>
+ </f:facet>
+
+ <onc:disambiguatedResourceName resourceName="#{resourceitem.original.name}"
+ resourceId="#{resourceitem.original.id}" disambiguationReport="#{resourceitem}" />
+ </rich:column>
+
+ <rich:column>
+ <f:facet name="header">
+ <h:outputText value="Location" />
+ </f:facet>
+ <onc:disambiguatedResourceLineage parents="#{resourceitem.parents}"/>
+ </rich:column>
+
+ <rich:column>
+ <f:facet name="header">
+ <onc:sortableColumnHeader sort="rc.resource.version">
+ <h:outputText styleClass="headerText" value="Version" />
+ </onc:sortableColumnHeader>
+ </f:facet>
+
+ <h:outputText value="#{resourceitem.original.version}" />
+ </rich:column>
+
+ <rich:column>
+ <f:facet name="header">
+ <onc:sortableColumnHeader sort="rc.resource.description">
+ <h:outputText styleClass="headerText"
+ value="Description" />
+ </onc:sortableColumnHeader>
+ </f:facet>
+
+ <h:outputText value="#{resourceitem.original.description}" />
+ </rich:column>
+
+ <f:facet name="footer">
+ <rich:columnGroup>
+ <!-- colspan 6:5 for the debug 'id' column -->
+ <rich:column colspan="#{param.debug ? 7 : 6}"
+ width="100%">
+ <h:commandButton
+ action="#{RepoResourcesUIBean.subscribeResources}"
+ value="SUBSCRIBE..."
+ styleClass="on-pager-button buttonsmall" />
+ <onc:selectCommandButton
+ action="#{RepoResourcesUIBean.deleteSelectedRepoResources}"
+ value="UNSUBSCRIBE SELECTED"
+ target="selectedRepoResources"
+ styleClass="on-pager-button buttonsmall" />
+
+ <ui:param name="paginationDataTableName"
+ value="repoResourcesDataTable" />
+ <ui:param name="paginationDataModel"
+ value="#{repoResourcesDataModel}" />
+ <ui:param name="paginationPageControl"
+ value="#{PageControl.RepoResourcesList}" />
+ <ui:include src="../resource/include/pagination.xhtml" />
+ </rich:column>
+ </rich:columnGroup>
+ </f:facet>
+
+ </rich:dataTable>
+
+ </h:panelGrid>
+
+ </rich:panel>
+ </h:form>
+
+
+
+ <!-- PACKAGE LIST -->
+
+ <h:form id="repoPackageVersionsListForm">
+ <a4j:region id="packageList">
+ <input type="hidden" name="id" value="${param.id}" />
+ <input type="hidden" name="mode" value="${param.mode}" />
+
+ <rich:panel>
+ <f:facet name="header">
+ <h:outputText
+ value="Packages" />
+ </f:facet>
+
+ <h:panelGrid columns="1" width="100%">
+
+ <h:panelGroup layout="block" style="margin-bottom: 6px;">
+
+ <b>Filter By: </b>
+ <h:inputText id="packageFilter"
+ value="#{RepoPackageVersionsUIBean.packageFilter}">
+ <a4j:support event="onchange"
+ reRender="repoPackageVersionsDataTable, repoPackageVersionsDataTableScroller" />
+ </h:inputText>
+ <a4j:commandButton value="GO"
+ reRender="repoPackageVersionsDataTable, repoPackageVersionsDataTableScroller"
+ styleClass="buttonmed">
+ <s:defaultAction />
+ </a4j:commandButton>
+
+ <a4j:status>
+ <f:facet name="start">
+ <h:graphicImage
+ value="/images/status_bar.gif" />
+ </f:facet>
+ </a4j:status>
+
+ </h:panelGroup>
+
+ <ui:param name="repoPackageVersionsDataModel"
+ value="#{RepoPackageVersionsUIBean.dataModel}" />
+ <rich:dataTable id="repoPackageVersionsDataTable"
+ rows="#{PageControl.RepoPackageVersionsList.pageSize}"
+ value="#{repoPackageVersionsDataModel}" var="package"
+ width="100%" columnsWidth="5%,20%, 10%, 5%, 60%"
+ headerClass="tableRowHeader" footerClass="on-pager-footer"
+ onRowMouseOver="this.style.backgroundColor='#E7E7E7'"
+ onRowMouseOut="this.style.backgroundColor='#{a4jSkin.tableBackgroundColor}'">
+
+ <f:facet name="PageControlView">
+ <onc:paginationControl id="RepoPackageVersionsList" />
+ </f:facet>
+
+ <rich:column>
+ <f:facet name="header">
+ <onc:allSelect target="selectedPackages" />
+ </f:facet>
+
+ <onc:select name="selectedPackages" value="#{package.id}" />
+ </rich:column>
+
+ <rich:column rendered="#{param.debug}">
+ <f:facet name="header">
+ <onc:sortableColumnHeader sort="pv.id">
+ <h:outputText styleClass="headerText" value="ID" />
+ </onc:sortableColumnHeader>
+ </f:facet>
+
+ <h:outputText value="#{package.id}" />
+ </rich:column>
+
+ <rich:column>
+ <f:facet name="header">
+ <onc:sortableColumnHeader sort="pv.displayName">
+ <h:outputText styleClass="headerText" value="Name" />
+ </onc:sortableColumnHeader>
+ </f:facet>
+
+ <h:outputLink value="packageVersion-plain.xhtml">
+ <f:param name="id" value="#{package.id}" />
+ <h:outputText value="#{package.displayName}" />
+ </h:outputLink>
+ </rich:column>
+
+ <rich:column>
+ <f:facet name="header">
+ <onc:sortableColumnHeader sort="pv.version">
+ <h:outputText styleClass="headerText"
+ value="Version" />
+ </onc:sortableColumnHeader>
+ </f:facet>
+
+ <h:outputText value="#{package.displayVersion}" />
+ </rich:column>
+
+ <rich:column>
+ <f:facet name="header">
+ <onc:sortableColumnHeader sort="pv.architecture.name">
+ <h:outputText styleClass="headerText" value="Arch" />
+ </onc:sortableColumnHeader>
+ </f:facet>
+
+ <h:outputText value="#{package.architecture.name}" />
+ </rich:column>
+
+ <rich:column>
+ <f:facet name="header">
+ <onc:sortableColumnHeader sort="pv.shortDescription">
+ <h:outputText styleClass="headerText"
+ value="Description" />
+ </onc:sortableColumnHeader>
+ </f:facet>
+
+ <h:panelGroup layout="block">
+ <h:outputText value="#{package.shortDescription}" escape="false" />
+ </h:panelGroup>
+ </rich:column>
+
+ <f:facet name="footer">
+ <rich:columnGroup>
+ <!-- colspan 5:4 for the debug 'id' column -->
+ <rich:column colspan="#{param.debug ? 6 : 5}"
+ width="100%">
+
+ <ui:param name="confirmInstallMessage"
+ value="#{msg['repo.view.deployPackageConfirm']}" />
+ <ui:remove>
+ <!-- NOTE: The onclick JavaScript block below should not return true under any circumstance. It is does so,
+ the JSF-RI-generated JavaScript will never get executed, and the browser will proceed to
+ redirect to "#", which will do nothing but refresh the current page. -->
+ </ui:remove>
+ <onc:selectCommandButton
+ action="#{RepoPackageVersionsUIBean.installSelectedPackages}"
+ value="INSTALL PACKAGES" target="selectedPackages"
+ onclick="if (!confirm('#{confirmInstallMessage}')) return false"
+ styleClass="on-pager-button buttonsmall"
+ rendered="#{RepoDetailsUIBean.inventoryManager}" />
+ <onc:selectCommandButton
+ action="#{RepoPackageVersionsUIBean.deleteSelectedPackages}"
+ value="DELETE PACKAGES" target="selectedPackages"
+ onclick="if (!confirm('Are you sure to delete the selected packages?\n\nOnly packages that don\'t come from content sources and that aren\'t and never have been installed to some resource will actually be deleted.')) return false"
+ styleClass="on-pager-button buttonsmall"
+ rendered="#{not RepoDetailsUIBean.hasContentSources}" />
+
+ <ui:param name="paginationDataTableName"
+ value="repoPackageVersionsDataTable" />
+ <ui:param name="paginationDataModel"
+ value="#{repoPackageVersionsDataModel}" />
+ <ui:param name="paginationPageControl"
+ value="#{PageControl.RepoPackageVersionsList}" />
+ <ui:include
+ src="../resource/include/pagination.xhtml" />
+ </rich:column>
+ </rich:columnGroup>
+ </f:facet>
+
+ </rich:dataTable>
+
+ </h:panelGrid>
+
+ </rich:panel>
+ </a4j:region>
+ </h:form>
+
+ <h:form rendered="#{not RepoDetailsUIBean.hasContentSources and RepoDetailsUIBean.editable}">
+ <rich:panel >
+ <f:facet name="header">
+ <h:outputText value="Upload New Package"/>
+ </f:facet>
+
+ <h:panelGrid columns="2">
+
+ <h:panelGroup style="float:right">
+ <b>File <span class="required-marker-text">*</span></b>
+ </h:panelGroup>
+ <h:panelGroup style="clear:both">
+ <input type="button"
+ class="buttonmed"
+ value="UPLOAD FILE..."
+ onclick="javascript:open('/rhq/resource/content/file-upload.xhtml', 'uploadwin', 'titlebar=0,toolbar=0,location=0,menubar=0,directories=0,resizable=0,height=160,width=450')"/>
+ <rich:spacer width="5" />
+ <h:outputText rendered="#{UploadNewPackageUIBean.fileUploaded}"
+ value="File Uploaded: #{UploadNewPackageUIBean.fileItem.fileName}"/>
+ </h:panelGroup>
+
+ <ui:remove><!-- row 1 --></ui:remove>
+ <h:panelGroup style="float: right">
+ <b>Type <span class="required-marker-text">*</span></b>
+ </h:panelGroup>
+ <h:panelGroup style="clear: both">
+ <h:selectOneMenu value="#{CreateNewPackageUIBean.selectedPackageTypeId}">
+ <f:selectItems value="#{CreateNewPackageUIBean.packageTypes}"/>
+ </h:selectOneMenu>
+ </h:panelGroup>
+
+ <ui:remove><!-- row 2 --></ui:remove>
+ <h:panelGroup style="float: right">
+ <b>Name <span class="required-marker-text">*</span></b>
+ </h:panelGroup>
+ <h:panelGroup style="clear: both">
+ <h:inputText id="packageName" value="#{CreateNewPackageUIBean.packageName}" required="true"/>
+ <h:message for="packageName" styleClass="ValidationErrorText"/>
+ </h:panelGroup>
+
+ <ui:remove><!-- row 3 --></ui:remove>
+ <h:panelGroup style="float: right">
+ <b>Version <span class="required-marker-text">*</span></b>
+ </h:panelGroup>
+ <h:panelGroup style="clear: both">
+ <h:inputText id="initialVersion" value="#{CreateNewPackageUIBean.version}" required="true"/>
+ <h:message for="initialVersion" styleClass="ValidationErrorText"/>
+ </h:panelGroup>
+
+ <ui:remove><!-- row 4 --></ui:remove>
+ <h:panelGroup style="float: right">
+ <b>Architecture <span class="required-marker-text">*</span></b>
+ </h:panelGroup>
+ <h:panelGroup style="clear: both">
+ <h:selectOneMenu value="#{CreateNewPackageUIBean.selectedArchitectureId}">
+ <f:selectItems value="#{CreateNewPackageUIBean.architectures}" />
+ </h:selectOneMenu>
+ </h:panelGroup>
+
+ </h:panelGrid>
+
+ <input type="hidden" name="repoOption" value="dummy-non-null-value-to-trick-the-ui-bean-to-do-our-thing"/>
+ <input type="hidden" name="id" value="${param.id}" />
+ <input type="hidden" name="mode" value="${param.mode}" />
+ <h:commandButton action="#{CreateNewPackageUIBean.createPackage}" value="CREATE PACKAGE" styleClass="buttonmed"/>
+ </rich:panel>
+ </h:form>
+
+ <h:form id="repoDistributionListForm" rendered="#{RepoDetailsUIBean.repositoryManager and RepoDistributionUIBean.dataModel.rowCount gt 0}">
+ <a4j:region id="distributionList">
+ <input type="hidden" name="id" value="${param.id}" />
+ <input type="hidden" name="mode" value="${param.mode}" />
+
+ <rich:panel>
+ <f:facet name="header">
+ <h:outputText
+ value="Distribution Trees" />
+ </f:facet>
+
+ <h:panelGrid columns="1" width="100%">
+
+
+ <ui:param name="repoDistributionDataModel"
+ value="#{RepoDistributionUIBean.dataModel}" />
+ <rich:dataTable id="repoDistributionDataTable"
+ rows="#{PageControl.RepoDistributionList.pageSize}"
+ value="#{repoDistributionDataModel}" var="dist"
+ width="100%" columnsWidth="20%,30%,50%"
+ headerClass="tableRowHeader" footerClass="on-pager-footer"
+ onRowMouseOver="this.style.backgroundColor='#E7E7E7'"
+ onRowMouseOut="this.style.backgroundColor='#{a4jSkin.tableBackgroundColor}'">
+
+
+ <f:facet name="PageControlView">
+ <onc:paginationControl id="RepoDistributionList" />
+ </f:facet>
+
+ <rich:column>
+ <f:facet name="header">
+ <h:outputText styleClass="headerText"
+ value="Distribution Label" />
+ </f:facet>
+ <h:outputText value="#{dist.label}" />
+
+ </rich:column>
+
+
+ <rich:column>
+ <f:facet name="header">
+ <h:outputText styleClass="headerText"
+ value="Distribution Type" />
+ </f:facet>
+ <h:outputText value="#{dist.distributionType}" />
+
+ </rich:column>
+
+ <rich:column>
+ <f:facet name="header">
+ <h:outputText styleClass="headerText"
+ value="Base Path" />
+ </f:facet>
+ <h:outputText value="#{dist.basePath}" />
+
+ </rich:column>
+
+ <rich:column>
+ <f:facet name="header">
+ <h:outputText styleClass="headerText"
+ value="Last Modified" />
+ </f:facet>
+ <h:outputText value="#{dist.lastModifiedDate}">
+ <f:converter converterId="UserDateTimeConverter" />
+ </h:outputText>
+
+ </rich:column>
+
+
+ <f:facet name="footer">
+ <rich:columnGroup>
+ <!-- colspan 5:4 for the debug 'id' column -->
+ <rich:column colspan="#{param.debug ? 6 : 5}"
+ width="100%">
+
+ <ui:param name="paginationDataTableName"
+ value="repoDistributionDataTable" />
+ <ui:param name="paginationDataModel"
+ value="#{repoDistributionDataModel}" />
+ <ui:param name="paginationPageControl"
+ value="#{PageControl.RepoDistributionList}" />
+ <ui:include
+ src="../resource/include/pagination.xhtml" />
+ </rich:column>
+ </rich:columnGroup>
+ </f:facet>
+
+ </rich:dataTable>
+
+ </h:panelGrid>
+
+ </rich:panel>
+ </a4j:region>
+ </h:form>
+
+ <h:form id="repoAdvisoryListForm" rendered="#{RepoDetailsUIBean.repositoryManager and RepoAdvisoryUIBean.dataModel.rowCount gt 0}">
+ <a4j:region id="advisoryList">
+ <input type="hidden" name="id" value="${param.id}" />
+ <input type="hidden" name="mode" value="${param.mode}" />
+
+ <rich:panel>
+ <f:facet name="header">
+ <h:outputText value="Advisories" />
+ </f:facet>
+
+ <h:panelGrid columns="1" width="100%">
+
+
+ <ui:param name="repoAdvisoryDataModel"
+ value="#{RepoAdvisoryUIBean.dataModel}" />
+ <rich:dataTable id="repoAdvisoryDataTable"
+ rows="#{PageControl.RepoAdvisoryList.pageSize}"
+ value="#{repoAdvisoryDataModel}" var="adv" width="100%"
+ columnsWidth="20%,20%,60%" headerClass="tableRowHeader"
+ footerClass="on-pager-footer"
+ onRowMouseOver="this.style.backgroundColor='#E7E7E7'"
+ onRowMouseOut="this.style.backgroundColor='#{a4jSkin.tableBackgroundColor}'">
+
+
+ <f:facet name="PageControlView">
+ <onc:paginationControl id="RepoAdvisoryList" />
+ </f:facet>
+
+ <rich:column>
+ <f:facet name="header">
+ <h:outputText styleClass="headerText"
+ value="Advisory Label" />
+ </f:facet>
+ <!--<h:outputText value="#{adv.advisory}"/>-->
+
+ <h:outputLink value="advisoryInfo.xhtml">
+ <f:param name="id" value="#{adv.id}" />
+ <h:outputText value="#{adv.advisory}" />
+ </h:outputLink>
+ </rich:column>
+
+
+ <rich:column>
+ <f:facet name="header">
+ <h:outputText styleClass="headerText" value="Type" />
+ </f:facet>
+ <h:outputText value="#{adv.advisoryType}" />
+
+ </rich:column>
+
+ <rich:column>
+ <f:facet name="header">
+ <h:outputText styleClass="headerText" value="Synopsis" />
+ </f:facet>
+ <h:outputText value="#{adv.synopsis}" />
+
+ </rich:column>
+
+ <f:facet name="footer">
+ <rich:columnGroup>
+ <!-- colspan 5:4 for the debug 'id' column -->
+ <rich:column colspan="#{param.debug ? 6 : 5}"
+ width="100%">
+
+ <ui:param name="paginationDataTableName"
+ value="repoAdvisoryDataTable" />
+ <ui:param name="paginationDataModel"
+ value="#{repoAdvisoryDataModel}" />
+ <ui:param name="paginationPageControl"
+ value="#{PageControl.RepoAdvisoryList}" />
+ <ui:include
+ src="../resource/include/pagination.xhtml" />
+ </rich:column>
+ </rich:columnGroup>
+ </f:facet>
+
+ </rich:dataTable>
+
+ </h:panelGrid>
+
+ </rich:panel>
+ </a4j:region>
+ </h:form>
+
+ </ui:define>
+</ui:composition>
+
+</html>
diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/content/repoAssociations-plain.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/content/repoAssociations-plain.xhtml
new file mode 100644
index 0000000..a43ce92
--- /dev/null
+++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/content/repoAssociations-plain.xhtml
@@ -0,0 +1,288 @@
+<?xml version="1.0"?>
+
+<!DOCTYPE html
+ PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml"
+ xmlns:h="http://java.sun.com/jsf/html"
+ xmlns:f="http://java.sun.com/jsf/core"
+ xmlns:ui="http://java.sun.com/jsf/facelets"
+ xmlns:c="http://java.sun.com/jstl/core"
+ xmlns:onc="http://jboss.org/on/component"
+ xmlns:onf="http://jboss.org/on/function"
+ xmlns:rich="http://richfaces.ajax4jsf.org/rich">
+
+<ui:composition template="/rhq/resource/layout/main-plain.xhtml">
+
+ <ui:param name="id" value="${param.id}" />
+ <ui:param name="pageTitle" value="Associate Content Sources to Repository '#{RepoDetailsUIBean.repo.name}'"/>
+ <ui:param name="item" value="#{RepoDetailsUIBean.repo}" />
+
+ <ui:define name="breadcrumbs">
+ <h:outputLink value="listRepos-plain.xhtml">
+ ${msg["repo.list.breadcrumb"]}
+ </h:outputLink>
+ >
+ <h:outputLink value="repo-plain.xhtml">
+ #{item.name}
+ <f:param name="mode" value="view" />
+ <f:param name="id" value="#{item.id}" />
+ </h:outputLink>
+ >
+ <h:outputLink value="repoAssociations-plain.xhtml">
+ Associate With Content Sources
+ <f:param name="id" value="#{item.id}" />
+ </h:outputLink>
+ </ui:define>
+
+ <ui:define name="content">
+
+ <!-- ASSOCIATED CONTENT SOURCE LIST -->
+
+ <h:form id="repoAssociationsListForm">
+ <input type="hidden" name="id" value="${param.id}"/>
+
+ <rich:panel>
+ <f:facet name="header">
+ <h:outputText value="Content Sources Associated With This Repository"/>
+ </f:facet>
+
+ <h:panelGrid columns="1" width="100%">
+
+ <ui:param name="repoAssociationsDataModel" value="#{RepoAssociationsUIBean.dataModel}"/>
+ <rich:dataTable id="repoAssociationsDataTable"
+ rows="#{PageControl.RepoAssociationsList.pageSize}"
+ value="#{repoAssociationsDataModel}"
+ var="contentprovideritem"
+ width="100%"
+ columnsWidth="1%, 20%, 15%, 15%, 9%"
+ headerClass="tableRowHeader"
+ footerClass="on-pager-footer"
+ onRowMouseOver="this.style.backgroundColor='#E7E7E7'"
+ onRowMouseOut="this.style.backgroundColor='#{a4jSkin.tableBackgroundColor}'">
+
+
+ <f:facet name="PageControlView">
+ <onc:paginationControl id="RepoAssociationsList" />
+ </f:facet>
+
+ <rich:column>
+ <f:facet name="header">
+ <onc:allSelect target="selectedRepoAssociations" />
+ </f:facet>
+ <onc:select name="selectedRepoAssociations" value="#{contentprovideritem.id}" />
+ </rich:column>
+
+ <rich:column rendered="#{param.debug}">
+ <f:facet name="header">
+ <onc:sortableColumnHeader sort="cs.id">
+ <h:outputText styleClass="headerText" value="ID" />
+ </onc:sortableColumnHeader>
+ </f:facet>
+ <h:outputText value="#{contentprovideritem.id}"/>
+ </rich:column>
+
+ <rich:column>
+ <f:facet name="header">
+ <onc:sortableColumnHeader sort="cs.name">
+ <h:outputText styleClass="headerText" value="Name" />
+ </onc:sortableColumnHeader>
+ </f:facet>
+ <h:outputLink value="contentProvider-plain.xhtml">
+ <f:param name="mode" value="view"/>
+ <f:param name="id" value="#{contentprovideritem.id}"/>
+ <h:outputText value="#{contentprovideritem.name}" />
+ </h:outputLink>
+ </rich:column>
+
+ <rich:column>
+ <f:facet name="header">
+ <onc:sortableColumnHeader sort="cs.creationDate">
+ <h:outputText styleClass="headerText" value="Date Created" />
+ </onc:sortableColumnHeader>
+ </f:facet>
+ <h:outputText value="#{contentprovideritem.creationDate}">
+ <f:convertDateTime pattern="M/d/yy, h:mm:ss aa, zzz" timeZone="#{ServerInfoUIBean.timeZone}"/>
+ </h:outputText>
+ </rich:column>
+
+ <rich:column>
+ <f:facet name="header">
+ <onc:sortableColumnHeader sort="cs.lastModifiedDate">
+ <h:outputText styleClass="headerText" value="Date Modified" />
+ </onc:sortableColumnHeader>
+ </f:facet>
+ <h:outputText value="#{contentprovideritem.lastModifiedDate}">
+ <f:convertDateTime pattern="M/d/yy, h:mm:ss aa, zzz" timeZone="#{ServerInfoUIBean.timeZone}"/>
+ </h:outputText>
+ </rich:column>
+
+ <rich:column>
+ <f:facet name="header">
+ <onc:sortableColumnHeader sort="cs.lazyLoad">
+ <h:outputText styleClass="headerText" value="Lazy Load?" />
+ </onc:sortableColumnHeader>
+ </f:facet>
+ <h:outputText value="#{contentprovideritem.lazyLoad}"/>
+ </rich:column>
+
+ <rich:column>
+ <f:facet name="header">
+ <onc:sortableColumnHeader sort="cs.description">
+ <h:outputText styleClass="headerText" value="Description" />
+ </onc:sortableColumnHeader>
+ </f:facet>
+ <h:outputText value="#{contentprovideritem.description}"/>
+ </rich:column>
+
+ <f:facet name="footer">
+ <rich:columnGroup>
+ <!-- colspan 7:6 for the debug 'id' column -->
+ <rich:column colspan="#{param.debug ? 7 : 6}" width="100%">
+ <onc:selectCommandButton action="#{RepoAssociationsUIBean.deleteSelectedRepoAssociations}"
+ value="DISASSOCIATE SELECTED" target="selectedRepoAssociations" styleClass="on-pager-button buttonsmall"/>
+
+ <ui:param name="paginationDataTableName" value="repoAssociationsDataTable"/>
+ <ui:param name="paginationDataModel" value="#{repoAssociationsDataModel}"/>
+ <ui:param name="paginationPageControl" value="#{PageControl.RepoAssociationsList}"/>
+ <ui:include src="../resource/include/pagination.xhtml"/>
+ </rich:column>
+ </rich:columnGroup>
+ </f:facet>
+
+ </rich:dataTable>
+
+ </h:panelGrid>
+
+ </rich:panel>
+ </h:form>
+
+ <!-- DISASSOCIATED CONTENT SOURCE LIST
+ (this actually lists all content sources,
+ but only those disassocated can you select) -->
+
+ <h:form id="repoDisassociationsListForm">
+ <input type="hidden" name="id" value="${param.id}"/>
+
+ <rich:panel>
+ <f:facet name="header">
+ <h:outputText value="Available Content Sources"/>
+ </f:facet>
+
+ <h:panelGrid columns="1" width="100%">
+
+ <ui:param name="repoDisassociationsDataModel" value="#{RepoDisassociationsUIBean.dataModel}"/>
+ <rich:dataTable id="repoDisassociationsDataTable"
+ rows="#{PageControl.RepoDisassociationsList.pageSize}"
+ value="#{repoDisassociationsDataModel}"
+ var="contentprovideritem"
+ width="100%"
+ columnsWidth="1%, 20%, 15%, 15%, 9%"
+ headerClass="tableRowHeader"
+ footerClass="on-pager-footer"
+ onRowMouseOver="this.style.backgroundColor='#E7E7E7'"
+ onRowMouseOut="this.style.backgroundColor='#{a4jSkin.tableBackgroundColor}'">
+
+
+ <f:facet name="PageControlView">
+ <onc:paginationControl id="RepoDisassociationsList" />
+ </f:facet>
+
+ <rich:column>
+ <f:facet name="header">
+ <onc:allSelect target="selectedRepoDisassociations" />
+ </f:facet>
+
+ <onc:select rendered="#{RepoAssociationsUIBean.associatedList[contentsourceitem.id] eq null}"
+ name="selectedRepoDisassociations" value="#{contentprovideritem.id}" />
+ </rich:column>
+
+ <rich:column rendered="#{param.debug}">
+ <f:facet name="header">
+ <onc:sortableColumnHeader sort="cs.id">
+ <h:outputText styleClass="headerText" value="ID" />
+ </onc:sortableColumnHeader>
+ </f:facet>
+ <h:outputText value="#{contentprovideritem.id}"/>
+ </rich:column>
+
+ <rich:column>
+ <f:facet name="header">
+ <onc:sortableColumnHeader sort="cs.name">
+ <h:outputText styleClass="headerText" value="Name" />
+ </onc:sortableColumnHeader>
+ </f:facet>
+ <h:outputLink value="contentProvider-plain.xhtml">
+ <f:param name="mode" value="view"/>
+ <f:param name="id" value="#{contentprovideritem.id}"/>
+ <h:outputText value="#{contentprovideritem.name}" />
+ </h:outputLink>
+ </rich:column>
+
+ <rich:column>
+ <f:facet name="header">
+ <onc:sortableColumnHeader sort="cs.creationDate">
+ <h:outputText styleClass="headerText" value="Date Created" />
+ </onc:sortableColumnHeader>
+ </f:facet>
+ <h:outputText value="#{contentprovideritem.creationDate}">
+ <f:convertDateTime pattern="M/d/yy, h:mm:ss aa, zzz" timeZone="#{ServerInfoUIBean.timeZone}"/>
+ </h:outputText>
+ </rich:column>
+
+ <rich:column>
+ <f:facet name="header">
+ <onc:sortableColumnHeader sort="cs.lastModifiedDate">
+ <h:outputText styleClass="headerText" value="Date Modified" />
+ </onc:sortableColumnHeader>
+ </f:facet>
+ <h:outputText value="#{contentprovideritem.lastModifiedDate}">
+ <f:convertDateTime pattern="M/d/yy, h:mm:ss aa, zzz" timeZone="#{ServerInfoUIBean.timeZone}"/>
+ </h:outputText>
+ </rich:column>
+
+ <rich:column>
+ <f:facet name="header">
+ <onc:sortableColumnHeader sort="cs.lazyLoad">
+ <h:outputText styleClass="headerText" value="Lazy Load?" />
+ </onc:sortableColumnHeader>
+ </f:facet>
+ <h:outputText value="#{contentprovideritem.lazyLoad}"/>
+ </rich:column>
+
+ <rich:column>
+ <f:facet name="header">
+ <onc:sortableColumnHeader sort="cs.description">
+ <h:outputText styleClass="headerText" value="Description" />
+ </onc:sortableColumnHeader>
+ </f:facet>
+ <h:outputText value="#{contentprovideritem.description}"/>
+ </rich:column>
+
+ <f:facet name="footer">
+ <rich:columnGroup>
+ <!-- colspan 7:6 for the debug 'id' column -->
+ <rich:column colspan="#{param.debug ? 7 : 6}" width="100%">
+ <onc:selectCommandButton action="#{RepoDisassociationsUIBean.associateSelectedContentSourcesWithRepo}"
+ value="ASSOCIATE SELECTED" target="selectedRepoDisassociations" styleClass="on-pager-button buttonsmall"/>
+
+ <ui:param name="paginationDataTableName" value="repoDisassociationsDataTable"/>
+ <ui:param name="paginationDataModel" value="#{repoDisassociationsDataModel}"/>
+ <ui:param name="paginationPageControl" value="#{PageControl.RepoDisassociationsList}"/>
+ <ui:include src="../resource/include/pagination.xhtml"/>
+ </rich:column>
+ </rich:columnGroup>
+ </f:facet>
+
+ </rich:dataTable>
+
+ </h:panelGrid>
+
+ </rich:panel>
+ </h:form>
+
+ </ui:define>
+</ui:composition>
+
+</html>
diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/content/repoSubscriptions-plain.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/content/repoSubscriptions-plain.xhtml
new file mode 100644
index 0000000..07eb418
--- /dev/null
+++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/content/repoSubscriptions-plain.xhtml
@@ -0,0 +1,282 @@
+<?xml version="1.0"?>
+
+<!DOCTYPE html
+ PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml"
+ xmlns:h="http://java.sun.com/jsf/html"
+ xmlns:f="http://java.sun.com/jsf/core"
+ xmlns:ui="http://java.sun.com/jsf/facelets"
+ xmlns:c="http://java.sun.com/jstl/core"
+ xmlns:onc="http://jboss.org/on/component"
+ xmlns:onf="http://jboss.org/on/function"
+ xmlns:a4j="https://ajax4jsf.dev.java.net/ajax"
+ xmlns:rich="http://richfaces.ajax4jsf.org/rich">
+
+<ui:composition template="/rhq/resource/layout/main-plain.xhtml">
+
+ <ui:param name="id" value="${param.id}" />
+ <ui:param name="pageTitle" value="Subscribe Resources to Repository '#{RepoDetailsUIBean.repo.name}'"/>
+ <ui:param name="item" value="#{RepoDetailsUIBean.repo}" />
+
+ <ui:define name="breadcrumbs">
+ <h:outputLink value="listRepos-plain.xhtml">
+ ${msg["repo.list.breadcrumb"]}
+ </h:outputLink>
+ >
+ <h:outputLink value="repo-plain.xhtml">
+ #{item.name}
+ <f:param name="mode" value="view" />
+ <f:param name="id" value="#{item.id}" />
+ </h:outputLink>
+ >
+ <h:outputLink value="repoSubscriptions-plain.xhtml">
+ Subscribe Resources
+ <f:param name="id" value="#{item.id}" />
+ </h:outputLink>
+ </ui:define>
+
+ <ui:define name="content">
+
+ <!-- ASSOCIATED RESOURCE LIST -->
+
+ <h:form id="repoSubscriptionsListForm">
+ <input type="hidden" name="id" value="${param.id}"/>
+
+ <rich:panel>
+ <f:facet name="header">
+ <h:outputText value="Resources Subscribed To This Repository"/>
+ </f:facet>
+
+ <h:panelGrid columns="1" width="100%">
+
+ <ui:param name="repoSubscriptionsDataModel" value="#{RepoSubscriptionsUIBean.dataModel}"/>
+ <rich:dataTable id="repoSubscriptionsDataTable"
+ rows="#{PageControl.RepoSubscriptionsList.pageSize}"
+ value="#{repoSubscriptionsDataModel}"
+ var="resourceitem"
+ width="100%"
+ columnsWidth="1%, 20%, 49%, 15%, 15%"
+ headerClass="tableRowHeader"
+ footerClass="on-pager-footer"
+ onRowMouseOver="this.style.backgroundColor='#E7E7E7'"
+ onRowMouseOut="this.style.backgroundColor='#{a4jSkin.tableBackgroundColor}'">
+
+
+ <f:facet name="PageControlView">
+ <onc:paginationControl id="RepoSubscriptionsList" />
+ </f:facet>
+
+ <rich:column>
+ <f:facet name="header">
+ <onc:allSelect target="selectedRepoSubscriptions" />
+ </f:facet>
+
+ <onc:select name="selectedRepoSubscriptions" value="#{resourceitem.original.id}" />
+ </rich:column>
+
+ <rich:column rendered="#{param.debug}">
+ <f:facet name="header">
+ <onc:sortableColumnHeader sort="rc.resource.id">
+ <h:outputText styleClass="headerText" value="ID" />
+ </onc:sortableColumnHeader>
+ </f:facet>
+
+ <h:outputText value="#{resourceitem.original.id}"/>
+ </rich:column>
+
+ <rich:column>
+ <f:facet name="header">
+ <onc:sortableColumnHeader sort="rc.resource.name">
+ <h:outputText styleClass="headerText" value="Resource" />
+ </onc:sortableColumnHeader>
+ </f:facet>
+
+ <onc:disambiguatedResourceName resourceName="#{resourceitem.original.name}"
+ resourceId="#{resourceitem.original.id}" disambiguationReport="#{resourceitem}" />
+ </rich:column>
+
+ <rich:column>
+ <f:facet name="header">
+ <h:outputText value="Location" />
+ </f:facet>
+ <onc:disambiguatedResourceLineage parents="#{resourceitem.parents}" />
+ </rich:column>
+
+ <rich:column>
+ <f:facet name="header">
+ <h:outputText styleClass="headerText" value="Version" />
+ </f:facet>
+
+ <h:outputText value="#{resourceitem.original.version}"/>
+ </rich:column>
+
+ <rich:column>
+ <f:facet name="header">
+ <h:outputText styleClass="headerText" value="Description" />
+ </f:facet>
+
+ <h:outputText value="#{resourceitem.original.description}"/>
+ </rich:column>
+
+ <f:facet name="footer">
+ <rich:columnGroup>
+ <!-- colspan 6:5 for the debug 'id' column -->
+ <rich:column colspan="#{param.debug ? 6 : 5}" width="100%">
+ <onc:selectCommandButton action="#{RepoSubscriptionsUIBean.deleteSelectedRepoSubscriptions}"
+ value="UNSUBSCRIBE SELECTED" target="selectedRepoSubscriptions" styleClass="on-pager-button buttonsmall"/>
+
+ <ui:param name="paginationDataTableName" value="repoSubscriptionsDataTable"/>
+ <ui:param name="paginationDataModel" value="#{repoSubscriptionsDataModel}"/>
+ <ui:param name="paginationPageControl" value="#{PageControl.RepoSubscriptionsList}"/>
+ <ui:include src="../resource/include/pagination.xhtml"/>
+ </rich:column>
+ </rich:columnGroup>
+ </f:facet>
+
+ </rich:dataTable>
+
+ </h:panelGrid>
+
+ </rich:panel>
+ </h:form>
+
+ <!-- UNSUBSCRIBED RESOURCE LIST (this actually lists all resources ) -->
+
+ <h:form id="repoUnsubscriptionsListForm">
+ <input type="hidden" name="id" value="${param.id}"/>
+
+ <rich:panel>
+ <f:facet name="header">
+ <h:outputText value="Available Resources"/>
+ </f:facet>
+
+ <table>
+ <tr>
+ <td>Search:</td>
+ <td>
+ <h:inputText id="searchStringFilter" value="#{RepoUnsubscriptionsUIBean.searchString}" />
+ </td>
+ <td>
+ <h:selectOneMenu id="searchCategoryFilter" value="#{RepoUnsubscriptionsUIBean.searchCategory}">
+ <f:selectItem itemValue="PLATFORM" itemLabel="Platform" />
+ <f:selectItem itemValue="SERVER" itemLabel="Server" />
+ <f:selectItem itemValue="SERVICE" itemLabel="Service" />
+ </h:selectOneMenu>
+ </td>
+ <td>
+ <h:graphicImage value="/images/dash-button_go-arrow.gif">
+ <a4j:support event="onclick" reRender="repoUnsubscriptionsDataTable, repoUnsubscriptionsDataTableScroller"/>
+ </h:graphicImage>
+ </td>
+ <td>
+ <a4j:status>
+ <f:facet name="start">
+ <h:graphicImage value="/images/status_bar.gif"/>
+ </f:facet>
+ </a4j:status>
+ </td>
+ </tr>
+ </table>
+
+ <h:panelGrid columns="1" width="100%">
+
+ <ui:param name="repoUnsubscriptionsDataModel" value="#{RepoUnsubscriptionsUIBean.dataModel}"/>
+ <rich:dataTable id="repoUnsubscriptionsDataTable"
+ rows="#{PageControl.RepoUnsubscriptionsList.pageSize}"
+ value="#{repoUnsubscriptionsDataModel}"
+ var="availableitem"
+ width="100%"
+ columnsWidth="1%, 20%, 49%, 15%, 15%"
+ headerClass="tableRowHeader"
+ footerClass="on-pager-footer"
+ onRowMouseOver="this.style.backgroundColor='#E7E7E7'"
+ onRowMouseOut="this.style.backgroundColor='#{a4jSkin.tableBackgroundColor}'">
+
+
+ <f:facet name="PageControlView">
+ <onc:paginationControl id="RepoUnsubscriptionsList" />
+ </f:facet>
+
+ <rich:column>
+ <f:facet name="header">
+ <onc:allSelect target="selectedRepoUnsubscriptions" />
+ </f:facet>
+
+ <onc:select name="selectedRepoUnsubscriptions" value="#{availableitem.original.id}" />
+ </rich:column>
+
+ <rich:column rendered="#{param.debug}">
+ <f:facet name="header">
+ <onc:sortableColumnHeader sort="res.id">
+ <h:outputText styleClass="headerText" value="ID" />
+ </onc:sortableColumnHeader>
+ </f:facet>
+
+ <h:outputText value="#{availableitem.original.id}"/>
+ </rich:column>
+
+ <rich:column>
+ <f:facet name="header">
+ <onc:sortableColumnHeader sort="res.name">
+ <h:outputText styleClass="headerText" value="Resource" />
+ </onc:sortableColumnHeader>
+ </f:facet>
+
+ <onc:disambiguatedResourceName resourceName="#{availableitem.original.name}"
+ resourceId="#{availableitem.original.id}" disambiguationReport="#{availableitem}" />
+ </rich:column>
+
+ <rich:column>
+ <f:facet name="header">
+ <h:outputText value="Location"/>
+ </f:facet>
+
+ <onc:disambiguatedResourceLineage parents="#{availableitem.parents}"/>
+ </rich:column>
+
+ <rich:column>
+ <f:facet name="header">
+ <onc:sortableColumnHeader sort="res.version">
+ <h:outputText styleClass="headerText" value="Version" />
+ </onc:sortableColumnHeader>
+ </f:facet>
+
+ <h:outputText value="#{availableitem.original.version}"/>
+ </rich:column>
+
+ <rich:column>
+ <f:facet name="header">
+ <h:outputText styleClass="headerText" value="Description" />
+ </f:facet>
+
+ <h:outputText value="#{availableitem.original.description}"/>
+ </rich:column>
+
+ <f:facet name="footer">
+ <rich:columnGroup>
+ <!-- colspan 6:5 for the debug 'id' column -->
+ <rich:column colspan="#{param.debug ? 6 : 5}" width="100%">
+ <onc:selectCommandButton action="#{RepoUnsubscriptionsUIBean.associateSelectedContentSourcesWithRepo}"
+ value="SUBSCRIBE SELECTED" target="selectedRepoUnsubscriptions" styleClass="on-pager-button buttonsmall"/>
+
+ <ui:param name="paginationDataTableName" value="repoUnsubscriptionsDataTable"/>
+ <ui:param name="paginationDataModel" value="#{repoUnsubscriptionsDataModel}"/>
+ <ui:param name="paginationPageControl" value="#{PageControl.RepoUnsubscriptionsList}"/>
+ <ui:include src="../resource/include/pagination.xhtml"/>
+ </rich:column>
+ </rich:columnGroup>
+ </f:facet>
+
+ </rich:dataTable>
+
+ </h:panelGrid>
+
+ </rich:panel>
+ </h:form>
+
+ </ui:define>
+</ui:composition>
+
+</html>
commit 5868ba9529cc2e048dc1f82e1942f8ed2b86aaeb
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Thu Feb 17 16:44:15 2011 +0100
Correctly reinitializing CreateRepoUIBean so that cancelling works once again.
diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/content/CreateRepoUIBean.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/content/CreateRepoUIBean.java
index b752ac4..6aaafdd 100644
--- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/content/CreateRepoUIBean.java
+++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/content/CreateRepoUIBean.java
@@ -36,15 +36,10 @@ import org.rhq.enterprise.server.content.RepoManagerLocal;
import org.rhq.enterprise.server.util.LookupUtil;
public class CreateRepoUIBean {
- private Repo newRepo = new Repo();
+ private Repo newRepo;
- {
- SubjectManagerLocal subjectManager = LookupUtil.getSubjectManager();
-
- //use a copy so that we can modify it without invalidating the user in the session
- Subject currenUserCopy = subjectManager.getSubjectById(EnterpriseFacesContextUtility.getSubject().getId());
-
- newRepo.setOwner(currenUserCopy);
+ public CreateRepoUIBean() {
+ initNewRepo();
}
public Repo getRepo() {
@@ -92,12 +87,12 @@ public class CreateRepoUIBean {
return "failed";
}
- newRepo = new Repo();
+ initNewRepo();
return "save";
}
public String cancel() {
- newRepo = new Repo();
+ initNewRepo();
return "cancel";
}
@@ -112,4 +107,15 @@ public class CreateRepoUIBean {
newRepo.setOwner(s);
}
}
+
+ private void initNewRepo() {
+ newRepo = new Repo();
+
+ SubjectManagerLocal subjectManager = LookupUtil.getSubjectManager();
+
+ //use a copy so that we can modify it without invalidating the user in the session
+ Subject currenUserCopy = subjectManager.getSubjectById(EnterpriseFacesContextUtility.getSubject().getId());
+
+ newRepo.setOwner(currenUserCopy);
+ }
}
\ No newline at end of file
commit 74c11bffd504038b5a5dee256bf47d47bf68eb5d
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Thu Feb 17 13:31:23 2011 +0100
GWT UI for CLI alert notification editing. Yet to be finished.
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/CliNotificationSenderForm.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/CliNotificationSenderForm.java
index 8ca863e..5041dde 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/CliNotificationSenderForm.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/CliNotificationSenderForm.java
@@ -20,13 +20,18 @@
package org.rhq.enterprise.gui.coregui.client.alert.definitions;
import java.util.Collections;
+import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
+import java.util.ListIterator;
import com.google.gwt.user.client.rpc.AsyncCallback;
+import com.smartgwt.client.types.TitleOrientation;
import com.smartgwt.client.widgets.form.DynamicForm;
import com.smartgwt.client.widgets.form.fields.ButtonItem;
+import com.smartgwt.client.widgets.form.fields.FormItem;
import com.smartgwt.client.widgets.form.fields.PasswordItem;
+import com.smartgwt.client.widgets.form.fields.SectionItem;
import com.smartgwt.client.widgets.form.fields.SelectItem;
import com.smartgwt.client.widgets.form.fields.TextItem;
import com.smartgwt.client.widgets.form.fields.events.ChangedEvent;
@@ -34,6 +39,7 @@ import com.smartgwt.client.widgets.form.fields.events.ChangedHandler;
import org.rhq.core.domain.alert.notification.AlertNotification;
import org.rhq.core.domain.auth.Subject;
+import org.rhq.core.domain.configuration.PropertySimple;
import org.rhq.core.domain.content.Package;
import org.rhq.core.domain.content.PackageType;
import org.rhq.core.domain.content.Repo;
@@ -44,6 +50,8 @@ import org.rhq.core.domain.util.PageList;
import org.rhq.enterprise.gui.coregui.client.CoreGUI;
import org.rhq.enterprise.gui.coregui.client.UserSessionManager;
import org.rhq.enterprise.gui.coregui.client.components.form.RadioGroupWithComponentsItem;
+import org.rhq.enterprise.gui.coregui.client.components.upload.FileUploadForm;
+import org.rhq.enterprise.gui.coregui.client.components.upload.PackageVersionFileUploadForm;
import org.rhq.enterprise.gui.coregui.client.gwt.GWTServiceLookup;
import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableDynamicForm;
@@ -57,16 +65,8 @@ public class CliNotificationSenderForm extends AbstractNotificationSenderForm {
private static final String PROP_PACKAGE_ID = "packageId";
private static final String PROP_REPO_ID = "repoId";
private static final String PROP_USER_ID = "userId";
-
- boolean formBuilt;
-
- private SelectItem repoSelector;
- private SelectItem packageSelector;
- private RadioGroupWithComponentsItem userSelector;
-
- private PackageType cliScriptPackageType;
private static final String PACKAGE_TYPE_NAME = "__SERVER_SIDE_CLI_SCRIPT";
-
+
private static class Config {
List<Repo> allRepos;
Repo selectedRepo;
@@ -113,6 +113,45 @@ public class CliNotificationSenderForm extends AbstractNotificationSenderForm {
}
}
+ private static class PackageVersionFileUploadFormWithVersion extends PackageVersionFileUploadForm {
+
+ /**
+ * @param locatorId
+ * @param packageTypeId
+ */
+ public PackageVersionFileUploadFormWithVersion(String locatorId, int packageTypeId) {
+ super(locatorId, packageTypeId, null, null, null, null, true, false, false);
+ setName("File");
+ }
+
+ protected List<FormItem> getOnDrawItems() {
+ List<FormItem> items = super.getOnDrawItems();
+
+ TextItem version = new TextItem("editableVersion", "Version"); //TODO i18n
+ version.setColSpan(getNumCols());
+ version.addChangedHandler(new ChangedHandler() {
+ public void onChanged(ChangedEvent event) {
+ getField("version").setValue(event.getValue());
+ }
+ });
+
+ items.add(version);
+
+ return items;
+ }
+ }
+
+
+ private boolean formBuilt;
+
+ private SelectItem repoSelector;
+ private RadioGroupWithComponentsItem packageSelector;
+ private SelectItem existingPackageSelector;
+ private RadioGroupWithComponentsItem userSelector;
+ private PackageVersionFileUploadFormWithVersion uploadForm;
+ private PackageType cliScriptPackageType;
+ private Config config;
+
public CliNotificationSenderForm(String locatorId, AlertNotification notif, String sender) {
super(locatorId, notif, sender);
}
@@ -121,40 +160,7 @@ public class CliNotificationSenderForm extends AbstractNotificationSenderForm {
protected void onInit() {
super.onInit();
- if (!formBuilt) {
- LocatableDynamicForm form = new LocatableDynamicForm(extendLocatorId("form"));
-
- repoSelector = new SelectItem("repoSelector", MSG.view_alert_definition_notification_cliScript_editor_repository());
- repoSelector.setDefaultToFirstOption(false);
- repoSelector.setWrapTitle(false);
- repoSelector.setRedrawOnChange(true);
- repoSelector.setWidth("*");
- repoSelector.setValueMap(MSG.common_msg_loading());
- repoSelector.setDisabled(true);
-
- packageSelector = new SelectItem("packageSelector", MSG.view_alert_definition_notification_cliScript_editor_script());
- packageSelector.setDefaultToFirstOption(false);
- packageSelector.setWrapTitle(false);
- packageSelector.setRedrawOnChange(true);
- packageSelector.setWidth("*");
- packageSelector.setValueMap(MSG.common_msg_loading());
- packageSelector.setDisabled(true);
-
-
- DynamicForm anotherUserForm = createAnotherUserForm();
-
- LinkedHashMap<String, DynamicForm> userSelectItems = new LinkedHashMap<String, DynamicForm>();
-
- userSelectItems.put(MSG.view_alert_definition_notification_cliScript_editor_thisUser(), null);
- userSelectItems.put(MSG.view_alert_definition_notification_cliScript_editor_anotherUser(), anotherUserForm);
-
- userSelector = new RadioGroupWithComponentsItem(
- extendLocatorId("userSelector"),
- MSG.view_alert_definition_notification_cliScript_editor_whichUser(), userSelectItems, form);
-
- form.setFields(repoSelector, packageSelector, userSelector);
- addMember(form);
-
+ if (!formBuilt) {
loadPackageType(new AsyncCallback<PackageType>() {
public void onFailure(Throwable t) {
CoreGUI.getErrorHandler().handleError(MSG.view_alert_definition_notification_cliScript_editor_loadFailed(),
@@ -164,6 +170,50 @@ public class CliNotificationSenderForm extends AbstractNotificationSenderForm {
public void onSuccess(PackageType result) {
cliScriptPackageType = result;
+ LocatableDynamicForm form = new LocatableDynamicForm(extendLocatorId("form"));
+ form.setTitleOrientation(TitleOrientation.TOP);
+ form.setWidth(500);
+
+ SectionItem repoSection = new SectionItem("repoSection");
+ repoSection.setDefaultValue(MSG.view_alert_definition_notification_cliScript_editor_repository());
+ repoSection.setWidth("100%");
+ SectionItem packageSection = new SectionItem("packageSection");
+ packageSection.setDefaultValue(MSG.view_alert_definition_notification_cliScript_editor_script());
+ SectionItem userSection = new SectionItem("userSection");
+ userSection.setDefaultValue(MSG.view_alert_definition_notification_cliScript_editor_whichUser());
+
+ repoSelector = new SelectItem(extendLocatorId("repoSelector"), "Select the repository to look for the script in"); //TODO i18n
+ repoSelector.setDefaultToFirstOption(true);
+ repoSelector.setWrapTitle(false);
+ repoSelector.setWidth(400);
+ repoSelector.setValueMap(MSG.common_msg_loading());
+ repoSelector.setDisabled(true);
+
+ LinkedHashMap<String, DynamicForm> packageSelectItems = new LinkedHashMap<String, DynamicForm>();
+ packageSelectItems.put(MSG.view_alert_definition_notification_cliScript_editor_existingScript(), createExistingPackageForm());
+ packageSelectItems.put(MSG.view_alert_definition_notification_cliScript_editor_uploadNewScript(), createUploadNewScriptForm());
+ packageSelector = new RadioGroupWithComponentsItem(extendLocatorId("packageSelector"),
+ "", packageSelectItems, form);
+ packageSelector.setWidth("100%");
+
+ LinkedHashMap<String, DynamicForm> userSelectItems = new LinkedHashMap<String, DynamicForm>();
+ userSelectItems.put(MSG.view_alert_definition_notification_cliScript_editor_thisUser(),
+ null);
+ userSelectItems.put(MSG.view_alert_definition_notification_cliScript_editor_anotherUser(),
+ createAnotherUserForm());
+ userSelector = new RadioGroupWithComponentsItem(
+ extendLocatorId("userSelector"),
+ "", userSelectItems, form);
+ userSelector.setWidth("100%");
+
+ repoSection.setItemIds(extendLocatorId("repoSelector"));
+ packageSection.setItemIds(extendLocatorId("packageSelector"));
+ userSection.setItemIds(extendLocatorId("userSelector"));
+
+ form.setFields(userSection, userSelector, repoSection, repoSelector, packageSection, packageSelector);
+
+ addMember(form);
+
loadConfig(new AsyncCallback<Config>() {
public void onFailure(Throwable t) {
CoreGUI.getErrorHandler().handleError(MSG.view_alert_definition_notification_cliScript_editor_loadFailed(),
@@ -171,44 +221,61 @@ public class CliNotificationSenderForm extends AbstractNotificationSenderForm {
}
public void onSuccess(Config config) {
- setupRepoSelector(config);
- setupPackageSelector(config);
- setupUserSelector(config);
+ CliNotificationSenderForm.this.config = config;
+ setupRepoSelector();
+ setupPackageSelector();
+ setupUserSelector();
+
+ formBuilt = true;
+
+ markForRedraw();
}
});
}
- });
-
- formBuilt = true;
+ });
}
}
- private void setupUserSelector(Config config) {
+ private void setupUserSelector() {
if (config.selectedSubject != null && !UserSessionManager.getSessionSubject().equals(config.selectedSubject)) {
- //TODO select the second radio and put it the user name..
+ userSelector.setSelected(MSG.view_alert_definition_notification_cliScript_editor_anotherUser());
+ LocatableDynamicForm anotherUserForm = (LocatableDynamicForm) userSelector.getSelectedComponent();
+ anotherUserForm.getItem("userName").setValue(config.selectedSubject.getName());
+ } else {
+ userSelector.setSelected(MSG.view_alert_definition_notification_cliScript_editor_thisUser());
}
markForRedraw();
}
- private void setupPackageSelector(Config config) {
+ private void setupPackageSelector() {
LinkedHashMap<String, String> map = new LinkedHashMap<String, String>();
for(Package p : config.allPackages) {
map.put(String.valueOf(p.getId()), p.getName());
}
- packageSelector.setValueMap(map);
+ existingPackageSelector.setValueMap(map);
if (config.selectedPackage != null) {
- packageSelector.setValue(config.selectedPackage.getId());
+ existingPackageSelector.setValue(config.selectedPackage.getId());
+ packageSelector.setSelected(MSG.view_alert_definition_notification_cliScript_editor_existingScript());
} else {
- packageSelector.setValue("");
+ packageSelector.setSelected(MSG.view_alert_definition_notification_cliScript_editor_uploadNewScript());
}
- packageSelector.setDisabled(false);
+ if (!formBuilt) {
+ existingPackageSelector.addChangedHandler(new ChangedHandler() {
+ public void onChanged(ChangedEvent event) {
+ int packageId = Integer.valueOf(event.getItem().getValue().toString());
+ config.setSelectedPackage(packageId);
+ }
+ });
+ }
+ existingPackageSelector.setDisabled(false);
+
markForRedraw();
}
- private void setupRepoSelector(final Config config) {
+ private void setupRepoSelector() {
LinkedHashMap<String, String> map = new LinkedHashMap<String, String>();
for(Repo r : config.allRepos) {
map.put(String.valueOf(r.getId()), r.getName());
@@ -217,36 +284,43 @@ public class CliNotificationSenderForm extends AbstractNotificationSenderForm {
repoSelector.setValueMap(map);
if (config.selectedRepo != null) {
repoSelector.setValue(config.selectedRepo.getId());
+ packageSelector.setDisabled(false);
} else {
repoSelector.setValue("");
+ packageSelector.setDisabled(true);
}
- repoSelector.addChangedHandler(new ChangedHandler() {
- public void onChanged(ChangedEvent event) {
- Integer repoId = Integer.valueOf(event.getItem().getValue().toString());
- config.setSelectedRepo(repoId);
-
- PackageCriteria pc = new PackageCriteria();
- pc.addFilterRepoId(repoId);
- pc.addFilterPackageTypeId(cliScriptPackageType.getId());
-
- packageSelector.setDisabled(true);
- packageSelector.setValueMap(MSG.common_msg_loading());
-
- GWTServiceLookup.getContentService().findPackagesByCriteria(pc, new AsyncCallback<PageList<Package>>() {
- public void onSuccess(PageList<Package> result) {
- config.allPackages = result;
- config.selectedPackage = null;
- setupPackageSelector(config);
- }
+ if (!formBuilt) {
+ repoSelector.addChangedHandler(new ChangedHandler() {
+ public void onChanged(ChangedEvent event) {
+ final Integer repoId = Integer.valueOf(event.getItem().getValue().toString());
+ config.setSelectedRepo(repoId);
- public void onFailure(Throwable caught) {
- CoreGUI.getErrorHandler().handleError(MSG.view_alert_definition_notification_cliScript_editor_loadFailed(),
- caught);
- }
- });
- }
- });
+ PackageCriteria pc = new PackageCriteria();
+ pc.addFilterRepoId(repoId);
+ pc.addFilterPackageTypeId(cliScriptPackageType.getId());
+
+ packageSelector.setDisabled(false);
+ existingPackageSelector.setDisabled(true);
+ existingPackageSelector.setValueMap(MSG.common_msg_loading());
+
+ GWTServiceLookup.getContentService().findPackagesByCriteria(pc, new AsyncCallback<PageList<Package>>() {
+ public void onSuccess(PageList<Package> result) {
+ config.allPackages = result;
+ config.selectedPackage = result.isEmpty() ? null : result.get(0); //we're autoselecting the first item
+ setupPackageSelector();
+
+ uploadForm.setRepoId(repoId);
+ }
+
+ public void onFailure(Throwable caught) {
+ CoreGUI.getErrorHandler().handleError(MSG.view_alert_definition_notification_cliScript_editor_loadFailed(),
+ caught);
+ }
+ });
+ }
+ });
+ }
repoSelector.setDisabled(false);
@@ -254,7 +328,34 @@ public class CliNotificationSenderForm extends AbstractNotificationSenderForm {
}
public boolean validate() {
- // TODO implement
+ // TODO add validation messages to the individual fields
+
+ if (userSelector.getSelectedIndex() != 0 && config.selectedSubject == null) {
+ return false;
+ }
+
+ if (config.selectedRepo == null) {
+ return false;
+ }
+
+ if (packageSelector.getSelectedIndex() == 0 && config.selectedPackage == null) {
+ return false;
+ }
+
+ if (userSelector.getSelectedIndex() == 0) {
+ getConfiguration().put(new PropertySimple(PROP_USER_ID, UserSessionManager.getSessionSubject().getId()));
+ } else {
+ getConfiguration().put(new PropertySimple(PROP_USER_ID, config.selectedSubject.getId()));
+ }
+
+ getConfiguration().put(new PropertySimple(PROP_REPO_ID, config.selectedRepo.getId()));
+
+ if (packageSelector.getSelectedIndex() == 0) {
+ getConfiguration().put(new PropertySimple(PROP_PACKAGE_ID, config.selectedPackage.getId()));
+ } else {
+ //TODO do upload here and wait for the result before returning...
+ }
+
return true;
}
@@ -339,20 +440,41 @@ public class CliNotificationSenderForm extends AbstractNotificationSenderForm {
}
}
- DynamicForm createAnotherUserForm() {
+ private DynamicForm createAnotherUserForm() {
LocatableDynamicForm form = new LocatableDynamicForm(extendLocatorId("anotherUserForm"));
-
+ form.setTitleOrientation(TitleOrientation.TOP);
TextItem userNameItem = new TextItem("userName", MSG.dataSource_users_field_name());
PasswordItem passwordItem = new PasswordItem("password", MSG.dataSource_users_field_password());
ButtonItem verifyItem = new ButtonItem("verify", MSG.view_alert_definition_notification_cliScript_editor_verifyAuthentication());
form.setFields(userNameItem, passwordItem, verifyItem);
+ //TODO add verification functionality
return form;
}
- private void loadPackageType(AsyncCallback<PackageType> handler) {
- GWTServiceLookup.getContentService().findPackageType(null, PACKAGE_TYPE_NAME, handler);
+ private DynamicForm createExistingPackageForm() {
+ LocatableDynamicForm form = new LocatableDynamicForm(extendLocatorId("existingPackageForm"));
+ form.setTitleOrientation(TitleOrientation.TOP);
+ existingPackageSelector = new SelectItem(extendLocatorId("existingPackageSelector"), "");
+ existingPackageSelector.setDefaultToFirstOption(true);
+ existingPackageSelector.setWrapTitle(false);
+ existingPackageSelector.setRedrawOnChange(true);
+ existingPackageSelector.setWidth("*");
+ existingPackageSelector.setValueMap(MSG.common_msg_loading());
+ existingPackageSelector.setDisabled(true);
+
+ form.setFields(existingPackageSelector);
+ return form;
}
+ private DynamicForm createUploadNewScriptForm() {
+ uploadForm = new PackageVersionFileUploadFormWithVersion(extendLocatorId("uploadForm"), cliScriptPackageType.getId());
+ uploadForm.setTitleOrientation(TitleOrientation.TOP);
+
+ return uploadForm;
+ }
+ private void loadPackageType(AsyncCallback<PackageType> handler) {
+ GWTServiceLookup.getContentService().findPackageType(null, PACKAGE_TYPE_NAME, handler);
+ }
}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/form/RadioGroupWithComponentsItem.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/form/RadioGroupWithComponentsItem.java
index 54435ce..7c7bd91 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/form/RadioGroupWithComponentsItem.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/form/RadioGroupWithComponentsItem.java
@@ -43,6 +43,7 @@ import org.rhq.enterprise.gui.coregui.client.util.selenium.SeleniumUtility;
* TODO
*
* @author Greg Hinkle
+ * @author Lukas Krejci
*/
public class RadioGroupWithComponentsItem extends CanvasItem {
@@ -72,12 +73,38 @@ public class RadioGroupWithComponentsItem extends CanvasItem {
return this.selected;
}
+ public int getSelectedIndex() {
+ if (selected == null) {
+ return -1;
+ }
+
+ int idx = 0;
+ for(NameAndTitle t : valueMap.keySet()) {
+ if (selected.equals(t.getTitle())) {
+ break;
+ }
+ ++idx;
+ }
+
+ return idx;
+ }
+
+ public void setSelected(String selected) {
+ RadioGroupItem radio = (RadioGroupItem) canvas.getItem(SeleniumUtility.getSafeId(selected));
+ if (radio != null) {
+ this.selected = selected;
+ radio.setValue(selected);
+ canvas.updateEnablement();
+ form.markForRedraw();
+ }
+ }
+
public Canvas getSelectedComponent() {
if (null == this.selected) {
return null;
}
- return valueMap.get(this.selected);
+ return valueMap.get(new NameAndTitle(this.selected));
}
private static class NameAndTitle {
@@ -162,7 +189,7 @@ public class RadioGroupWithComponentsItem extends CanvasItem {
for (NameAndTitle key : valueMap.keySet()) {
Canvas value = valueMap.get(key);
- Boolean disabled = !selected.equals(key.getName());
+ Boolean disabled = !selected.equals(key.getTitle());
if (disabled) {
canvas.getItem(key.getName()).clearValue();
canvas.getItem(key.getName()).redraw();
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/upload/FileUploadForm.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/upload/FileUploadForm.java
index 286e382..3e74575 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/upload/FileUploadForm.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/upload/FileUploadForm.java
@@ -56,8 +56,8 @@ public class FileUploadForm extends DynamicCallbackForm {
private String uploadError;
private boolean uploadInProgress;
- private final String name;
- private final String version;
+ private String name;
+ private String version;
private final boolean showNameLabel;
private final boolean showUploadButton;
private final FormItemIcon iconLoading;
@@ -111,6 +111,24 @@ public class FileUploadForm extends DynamicCallbackForm {
return name;
}
+ public void setName(String name) {
+ this.name = name;
+ if (onDrawCalled()) {
+ getItem("name").setValue(name);
+ }
+ }
+
+ public String getVersion() {
+ return version;
+ }
+
+ public void setVersion(String version) {
+ this.version = version;
+ if (onDrawCalled()) {
+ getItem("version").setValue(version);
+ }
+ }
+
/**
* Returns true if the file was successfully uploaded, false if an error occurred.
* Returns null if this upload form has not be submitted yet (see {@link #submitForm()}).
@@ -280,8 +298,10 @@ public class FileUploadForm extends DynamicCallbackForm {
protected void onDraw() {
super.onDraw();
- List<FormItem> onDrawItems = getOnDrawItems();
+ //set the number of columns before we create the items so that
+ //they have this value available
setNumCols(((this.showUploadButton) ? 2 : 1) + ((this.showNameLabel) ? 1 : 0));
+ List<FormItem> onDrawItems = getOnDrawItems();
setItems(onDrawItems.toArray(new FormItem[onDrawItems.size()]));
// push the form handler so it executes first if the form creator has also added a handler
@@ -295,6 +315,10 @@ public class FileUploadForm extends DynamicCallbackForm {
}
}
+ protected boolean onDrawCalled() {
+ return getItem("sessionid") != null;
+ }
+
public List<String> getUploadedFilePaths() {
return uploadedFilePaths;
}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/upload/PackageVersionFileUploadForm.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/upload/PackageVersionFileUploadForm.java
index bd41379..802ffea 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/upload/PackageVersionFileUploadForm.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/upload/PackageVersionFileUploadForm.java
@@ -30,21 +30,24 @@ import org.rhq.enterprise.gui.coregui.client.CoreGUI;
* Upload a single file and use it to create a new PackageVersion.
*
* @author Jay Shaughnessy
+ * @author Lukas Krejci
*/
public class PackageVersionFileUploadForm extends FileUploadForm {
private int packageTypeId;
private Integer archId;
+ private Integer repoId;
private int packageVersionId;
public PackageVersionFileUploadForm(String locatorId, int packageTypeId, String packageName, String version,
- Integer archId, boolean showNameLabel, Boolean isAlreadyUploaded) {
+ Integer archId, Integer repoId, boolean showNameLabel, boolean showUploadButton, Boolean isAlreadyUploaded) {
- super(locatorId, packageName, version, showNameLabel, true, isAlreadyUploaded);
+ super(locatorId, packageName, version, showNameLabel, showUploadButton, isAlreadyUploaded);
this.packageTypeId = packageTypeId;
this.archId = archId;
-
+ this.repoId = repoId;
+
setAction(GWT.getModuleBaseURL() + "PackageVersionFileUploadServlet");
}
@@ -58,6 +61,57 @@ public class PackageVersionFileUploadForm extends FileUploadForm {
return this.packageVersionId;
}
+ public int getPackageTypeId() {
+ return packageTypeId;
+ }
+
+ public void setPackageTypeId(int value) {
+ packageTypeId = value;
+ if (onDrawCalled()) {
+ getItem("packageTypeId").setValue(value);
+ }
+ }
+
+ public Integer getArchitectureId() {
+ return archId;
+ }
+
+ public void setArchitectureId(Integer value) {
+ archId = value;
+ FormItem item = getItem("archId");
+ if (item != null) {
+ if (value == null) {
+ removeField("archId");
+ } else {
+ item.setDefaultValue(value);
+ }
+ } else if (value != null && onDrawCalled()) {
+ HiddenItem archIdField = new HiddenItem("archId");
+ archIdField.setDefaultValue(value);
+ addField(archIdField);
+ }
+ }
+
+ public Integer getRepoId() {
+ return repoId;
+ }
+
+ public void setRepoId(Integer value) {
+ repoId = value;
+ FormItem item = getItem("repoId");
+ if (item != null) {
+ if (value != null) {
+ removeField("repoId");
+ } else {
+ item.setDefaultValue(value);
+ }
+ } else if (value != null && onDrawCalled()) {
+ HiddenItem repoIdField = new HiddenItem("repoId");
+ repoIdField.setDefaultValue(value);
+ addField(repoIdField);
+ }
+ }
+
@Override
protected List<FormItem> getOnDrawItems() {
List<FormItem> onDrawItems = super.getOnDrawItems();
@@ -72,6 +126,12 @@ public class PackageVersionFileUploadForm extends FileUploadForm {
onDrawItems.add(archIdField);
}
+ if (null != repoId) {
+ HiddenItem repoIdField = new HiddenItem("repoId");
+ repoIdField.setDefaultValue(repoId);
+ onDrawItems.add(repoIdField);
+ }
+
return onDrawItems;
}
@@ -114,4 +174,25 @@ public class PackageVersionFileUploadForm extends FileUploadForm {
super.submitForm();
}
+ private void removeField(String fieldName) {
+ FormItem[] items = getFields();
+ FormItem[] newItems = new FormItem[items.length - 1];
+ int idx = 0;
+ for (FormItem i : items) {
+ if (!fieldName.equals(i.getName())) {
+ newItems[idx] = i;
+ }
+ ++idx;
+ }
+
+ setFields(newItems);
+ }
+
+ private void addField(FormItem item) {
+ FormItem[] items = getFields();
+ FormItem[] newItems = new FormItem[items.length + 1];
+
+ System.arraycopy(items, 0, newItems, 0, items.length);
+ newItems[items.length] = item;
+ }
}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/factory/ResourceFactoryPackageStep.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/factory/ResourceFactoryPackageStep.java
index 3ae99b1..d0cde69 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/factory/ResourceFactoryPackageStep.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/factory/ResourceFactoryPackageStep.java
@@ -51,11 +51,11 @@ public class ResourceFactoryPackageStep extends AbstractWizardStep {
if (parent != null) {
form = new PackageVersionFileUploadForm(parent.extendLocatorId("ResFactPackageStep"), wizard
.getNewResourcePackageType().getId(), wizard.getChildType().getName(), wizard
- .getNewResourceVersion(), wizard.getNewResourceArchitectureId(), true, null);
+ .getNewResourceVersion(), wizard.getNewResourceArchitectureId(), null, true, true, null);
} else {
form = new PackageVersionFileUploadForm("ResFactPackageStep", wizard.getNewResourcePackageType()
.getId(), wizard.getChildType().getName(), wizard.getNewResourceVersion(), wizard
- .getNewResourceArchitectureId(), true, null);
+ .getNewResourceArchitectureId(), null, true, true, null);
}
form.setPadding(20);
form.addFormHandler(new DynamicFormHandler() {
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/PackageVersionFileUploadServlet.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/PackageVersionFileUploadServlet.java
index 4511b9b..c07d06e 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/PackageVersionFileUploadServlet.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/PackageVersionFileUploadServlet.java
@@ -31,6 +31,7 @@ import javax.servlet.http.HttpServletResponse;
import org.rhq.core.domain.auth.Subject;
import org.rhq.core.domain.content.PackageVersion;
import org.rhq.enterprise.server.content.ContentManagerLocal;
+import org.rhq.enterprise.server.content.RepoManagerLocal;
import org.rhq.enterprise.server.util.LookupUtil;
/**
@@ -65,10 +66,22 @@ public class PackageVersionFileUploadServlet extends FileUploadServlet {
String archIdField = getFormField(formFields, "archId", null);
int architectureId = (null != archIdField) ? Integer.parseInt(archIdField) : contentManager
.getNoArchitecture().getId();
+ Integer repoId = null;
+ String repoIdS = getFormField(formFields, "repoId", null);
+ if (repoIdS != null) {
+ repoId = Integer.parseInt(repoIdS);
+ }
+
InputStream fileStream = new FileInputStream(file);
PackageVersion packageVersion = contentManager.createPackageVersion(packageName, packageTypeId, version,
architectureId, fileStream);
+
+ if (repoId != null) {
+ RepoManagerLocal repoManager = LookupUtil.getRepoManagerLocal();
+ repoManager.addPackageVersionsToRepo(subject, repoId, new int[] { packageVersion.getId() });
+ }
+
successMsg = "success [" + packageVersion.getId() + "]";
} catch (Exception e) {
writeExceptionResponse(response, "Failed to upload file", e); // clients will look for this string!
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 2817514..3122b86 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
@@ -802,12 +802,14 @@ view_alert_definition_notification_user_editor_restoreFailed = Cannot use curren
view_alert_definition_notification_user_editor_saveFailed = Cannot save the selected users
view_alert_definition_notification_cliScript_editor_repository = Repository
view_alert_definition_notification_cliScript_editor_script = Script
-view_alert_definition_notification_cliScript_editor_whichUser = User to run the script as
+view_alert_definition_notification_cliScript_editor_whichUser = User To Run The Script As
view_alert_definition_notification_cliScript_editor_thisUser = Myself
-view_alert_definition_notification_cliScript_editor_anotherUser = Another user
+view_alert_definition_notification_cliScript_editor_anotherUser = Another User
view_alert_definition_notification_cliScript_editor_verifyAuthentication = Verify
-view_alert_definition_notification_cliScript_editor_loadFailed = Loading the CLI notification editor failed.
+view_alert_definition_notification_cliScript_editor_loadFailed = Loading the CLI Notification Editor Failed.
view_alert_definition_notification_cliScript_editor_selectRepoFirst = Select a repo first.
+view_alert_definition_notification_cliScript_editor_existingScript = Existing Script
+view_alert_definition_notification_cliScript_editor_uploadNewScript = Upload New Script
view_alert_definition_recovery_editor_disable_when_fired = Disable When Fired
view_alert_definition_recovery_editor_disable_when_fired_tooltip = Indicates if this alert will be disabled after it fires. Once disabled, the alert can be manually re-enabled or a recovery alert can be set up to automatically re-enable it. If this alert is a recovery alert itself, this setting cannot be turned on.
view_alert_definition_recovery_editor_recovery_alert = Recover Alert
commit def54be15f2c4ca6e0993658585b37e84c0b68e8
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Thu Feb 17 13:29:40 2011 +0100
UI updates for JSF UI:
* public/private repos
* repo owner
* manual upload and delete of packages in the repo
diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/content/CreateNewPackageUIBean.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/content/CreateNewPackageUIBean.java
index bafa62f..35a70a7 100644
--- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/content/CreateNewPackageUIBean.java
+++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/content/CreateNewPackageUIBean.java
@@ -90,7 +90,7 @@ public class CreateNewPackageUIBean {
private static final String REPO_OPTION_NONE = "none";
private String packageName;
- private String version;
+ private String version = "1.0";
private int selectedArchitectureId;
private int selectedPackageTypeId;
@@ -141,7 +141,7 @@ public class CreateNewPackageUIBean {
// Collect the necessary information
Subject subject = EnterpriseFacesContextUtility.getSubject();
- Resource resource = EnterpriseFacesContextUtility.getResource();
+ Resource resource = EnterpriseFacesContextUtility.getResourceIfExists();
HttpServletRequest request = FacesContextUtility.getRequest();
UploadNewPackageUIBean uploadUIBean = FacesContextUtility.getManagedBean(UploadNewPackageUIBean.class);
@@ -185,16 +185,22 @@ public class CreateNewPackageUIBean {
// Determine which repo the package will go into
String repoId = null;
if (usingARepo) {
- try {
- repoId = determineRepo(repoOption, subject, resource.getId());
- } catch (ContentException ce) {
- String errorMessages = ThrowableUtil.getAllMessages(ce);
- FacesContextUtility.addMessage(FacesMessage.SEVERITY_ERROR, "Failed to determine repository. Cause: "
- + errorMessages);
- return "failure";
+ if (resource != null) {
+ try {
+ repoId = determineRepo(repoOption, subject, resource.getId());
+ } catch (ContentException ce) {
+ String errorMessages = ThrowableUtil.getAllMessages(ce);
+ FacesContextUtility.addMessage(FacesMessage.SEVERITY_ERROR, "Failed to determine repository. Cause: "
+ + errorMessages);
+ return "failure";
+ }
+ } else {
+ //we're creating a package directly inside a repo. The repo id
+ //will be in the request params.
+ repoId = FacesContextUtility.getRequiredRequestParameter("id");
}
}
-
+
try {
// Grab a stream for the file being uploaded
InputStream packageStream;
@@ -240,7 +246,7 @@ public class CreateNewPackageUIBean {
}
//TODO: need to get parent id instead right? ref to app server inst itself?
- int newResourceTypeId = resource.getResourceType().getId();
+ Integer newResourceTypeId = resource == null ? null : resource.getResourceType().getId();
packageVersion = contentManager.getUploadedPackageVersion(packageName, packageTypeId, version,
architectureId, packageStream, packageUploadDetails, newResourceTypeId);
@@ -323,10 +329,15 @@ public class CreateNewPackageUIBean {
}
public SelectItem[] getPackageTypes() {
- Resource resource = EnterpriseFacesContextUtility.getResource();
+ Resource resource = EnterpriseFacesContextUtility.getResourceIfExists();
+ List<PackageType> packageTypes = null;
ContentUIManagerLocal contentUIManager = LookupUtil.getContentUIManager();
- List<PackageType> packageTypes = contentUIManager.getPackageTypes(resource.getResourceType().getId());
+ if (resource != null) {
+ packageTypes = contentUIManager.getPackageTypes(resource.getResourceType().getId());
+ } else {
+ packageTypes = contentUIManager.getPackageTypes();
+ }
SelectItem[] items = new SelectItem[packageTypes.size()];
int itemCounter = 0;
@@ -373,12 +384,20 @@ public class CreateNewPackageUIBean {
}
public boolean isNeedRequestPackageDetails() {
+ if (!isResourcePackage()) {
+ return true;
+ }
+
boolean isPackageBacked = isResourcePackageBacked();
boolean backingPackageExists = lookupBackingPackage() != null;
return !isPackageBacked || !backingPackageExists;
}
+ public boolean isResourcePackage() {
+ return EnterpriseFacesContextUtility.getResourceIfExists() != null;
+ }
+
public boolean isResourcePackageBacked() {
Resource resource = EnterpriseFacesContextUtility.getResource();
ResourceType resourceType = resource.getResourceType();
@@ -426,7 +445,14 @@ public class CreateNewPackageUIBean {
}
public String getPackageName() {
- return packageName;
+ if (packageName != null) {
+ return packageName;
+ }
+
+ UploadNewPackageUIBean uploadUIBean = FacesContextUtility.getManagedBean(UploadNewPackageUIBean.class);
+ UploadItem fileItem = uploadUIBean.getFileItem();
+
+ return fileItem == null ? null : fileItem.getFileName();
}
public void setPackageName(String packageName) {
diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/content/CreateRepoUIBean.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/content/CreateRepoUIBean.java
index 9173dec..b752ac4 100644
--- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/content/CreateRepoUIBean.java
+++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/content/CreateRepoUIBean.java
@@ -18,12 +18,19 @@
*/
package org.rhq.enterprise.gui.content;
+import java.util.ArrayList;
+import java.util.List;
+
import javax.faces.application.FacesMessage;
+import javax.faces.model.SelectItem;
import org.rhq.core.domain.auth.Subject;
+import org.rhq.core.domain.authz.Permission;
import org.rhq.core.domain.content.Repo;
+import org.rhq.core.domain.util.PageControl;
import org.rhq.core.gui.util.FacesContextUtility;
import org.rhq.enterprise.gui.util.EnterpriseFacesContextUtility;
+import org.rhq.enterprise.server.auth.SubjectManagerLocal;
import org.rhq.enterprise.server.content.RepoException;
import org.rhq.enterprise.server.content.RepoManagerLocal;
import org.rhq.enterprise.server.util.LookupUtil;
@@ -31,6 +38,15 @@ import org.rhq.enterprise.server.util.LookupUtil;
public class CreateRepoUIBean {
private Repo newRepo = new Repo();
+ {
+ SubjectManagerLocal subjectManager = LookupUtil.getSubjectManager();
+
+ //use a copy so that we can modify it without invalidating the user in the session
+ Subject currenUserCopy = subjectManager.getSubjectById(EnterpriseFacesContextUtility.getSubject().getId());
+
+ newRepo.setOwner(currenUserCopy);
+ }
+
public Repo getRepo() {
return newRepo;
}
@@ -39,11 +55,34 @@ public class CreateRepoUIBean {
this.newRepo = newRepo;
}
+ public SelectItem[] getAvailableOwners() {
+ SubjectManagerLocal subjectManager = LookupUtil.getSubjectManager();
+
+ List<Subject> subjects = subjectManager.findAllSubjects(PageControl.getUnlimitedInstance());
+
+ ArrayList<SelectItem> items = new ArrayList<SelectItem>(subjects.size());
+
+ items.add(new SelectItem(null, "--None--"));
+
+ for(Subject s : subjects) {
+ SelectItem item = new SelectItem(s.getName(), s.getName());
+ items.add(item);
+ }
+
+ return items.toArray(new SelectItem[items.size()]);
+ }
+
+ public boolean isRepositoryManager() {
+ Subject subject = EnterpriseFacesContextUtility.getSubject();
+ return LookupUtil.getAuthorizationManager().hasGlobalPermission(subject, Permission.MANAGE_REPOSITORIES);
+ }
+
public String save() {
Subject subject = EnterpriseFacesContextUtility.getSubject();
RepoManagerLocal manager = LookupUtil.getRepoManagerLocal();
try {
+ updateRepoOwner(subject);
newRepo.setCandidate(false);
Repo created = manager.createRepo(subject, newRepo);
FacesContextUtility.addMessage(FacesMessage.SEVERITY_INFO, "Saved [" + created.getName()
@@ -56,9 +95,21 @@ public class CreateRepoUIBean {
newRepo = new Repo();
return "save";
}
-
+
public String cancel() {
newRepo = new Repo();
return "cancel";
}
+
+ private void updateRepoOwner(Subject loggedInSubject) {
+ if (newRepo.getOwner().getName() == null) {
+ newRepo.setOwner(null);
+ } else if (newRepo.getOwner().getName().equals(loggedInSubject.getName())) {
+ newRepo.setOwner(loggedInSubject);
+ } else {
+ SubjectManagerLocal subjectManager = LookupUtil.getSubjectManager();
+ Subject s = subjectManager.getSubjectByName(newRepo.getOwner().getName());
+ newRepo.setOwner(s);
+ }
+ }
}
\ No newline at end of file
diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/content/RepoDetailsUIBean.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/content/RepoDetailsUIBean.java
index d1dd640..d74a836 100644
--- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/content/RepoDetailsUIBean.java
+++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/content/RepoDetailsUIBean.java
@@ -18,7 +18,11 @@
*/
package org.rhq.enterprise.gui.content;
+import java.util.ArrayList;
+import java.util.List;
+
import javax.faces.application.FacesMessage;
+import javax.faces.model.SelectItem;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -29,8 +33,11 @@ import org.rhq.core.domain.authz.Permission;
import org.rhq.core.domain.content.ContentSyncStatus;
import org.rhq.core.domain.content.Repo;
import org.rhq.core.domain.content.RepoSyncResults;
+import org.rhq.core.domain.util.PageControl;
import org.rhq.core.gui.util.FacesContextUtility;
import org.rhq.enterprise.gui.util.EnterpriseFacesContextUtility;
+import org.rhq.enterprise.server.auth.SubjectManagerBean;
+import org.rhq.enterprise.server.auth.SubjectManagerLocal;
import org.rhq.enterprise.server.content.ContentException;
import org.rhq.enterprise.server.content.RepoManagerLocal;
import org.rhq.enterprise.server.util.LookupUtil;
@@ -50,6 +57,11 @@ public class RepoDetailsUIBean {
return "edit";
}
+ public void reloadRepo() {
+ this.repo = null;
+ loadRepo();
+ }
+
public boolean getCurrentlySyncing() {
String syncStatus = getSyncStatus();
if (!syncStatus.equals(ContentSyncStatus.SUCCESS.toString())
@@ -108,6 +120,23 @@ public class RepoDetailsUIBean {
return getRepo().getContentSources().size() > 0;
}
+ public SelectItem[] getAvailableOwners() {
+ SubjectManagerLocal subjectManager = LookupUtil.getSubjectManager();
+
+ List<Subject> subjects = subjectManager.findAllSubjects(PageControl.getUnlimitedInstance());
+
+ ArrayList<SelectItem> items = new ArrayList<SelectItem>(subjects.size());
+
+ items.add(new SelectItem(null, "--None--"));
+
+ for(Subject s : subjects) {
+ SelectItem item = new SelectItem(s.getName(), s.getName());
+ items.add(item);
+ }
+
+ return items.toArray(new SelectItem[items.size()]);
+ }
+
public String sync() {
Subject subject = EnterpriseFacesContextUtility.getSubject();
int[] repoIds = { FacesContextUtility.getRequiredRequestParameter("id", Integer.class) };
@@ -132,6 +161,7 @@ public class RepoDetailsUIBean {
RepoManagerLocal manager = LookupUtil.getRepoManagerLocal();
try {
+ updateRepoOwner(subject);
manager.updateRepo(subject, repo);
FacesContextUtility.addMessage(FacesMessage.SEVERITY_INFO, "The repository has been updated.");
} catch (ContentException ce) {
@@ -161,12 +191,6 @@ public class RepoDetailsUIBean {
return "success";
}
- public void packageUploadListener(UploadEvent event) {
- if (!isEditable()) {
- return;
- }
- }
-
private void loadRepo() {
if (this.repo == null) {
Subject subject = EnterpriseFacesContextUtility.getSubject();
@@ -174,6 +198,21 @@ public class RepoDetailsUIBean {
RepoManagerLocal manager = LookupUtil.getRepoManagerLocal();
this.repo = manager.getRepo(subject, id);
this.repo.setSyncStatus(manager.calculateSyncStatus(subject, id));
+ if (repo.getOwner() == null) {
+ repo.setOwner(new Subject());
+ }
+ }
+ }
+
+ private void updateRepoOwner(Subject loggedInSubject) {
+ if (repo.getOwner().getName() == null) {
+ repo.setOwner(null);
+ } else if (repo.getOwner().getName().equals(loggedInSubject.getName())) {
+ repo.setOwner(loggedInSubject);
+ } else {
+ SubjectManagerLocal subjectManager = LookupUtil.getSubjectManager();
+ Subject s = subjectManager.getSubjectByName(repo.getOwner().getName());
+ repo.setOwner(s);
}
}
}
\ No newline at end of file
diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/content/RepoPackageVersionsUIBean.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/content/RepoPackageVersionsUIBean.java
index 5d1305d..f00118b 100644
--- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/content/RepoPackageVersionsUIBean.java
+++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/content/RepoPackageVersionsUIBean.java
@@ -75,6 +75,31 @@ public class RepoPackageVersionsUIBean extends PagedDataTableUIBean {
}
}
+ public void deleteSelectedPackages() {
+ Subject subject = EnterpriseFacesContextUtility.getSubject();
+ String[] selectedPackages = FacesContextUtility.getRequest().getParameterValues("selectedPackages");
+ int repoId = Integer.valueOf(FacesContextUtility.getRequiredRequestParameter("id"));
+
+ RepoManagerLocal repoManager = LookupUtil.getRepoManagerLocal();
+
+ int[] packageIds = new int[selectedPackages.length];
+ for (int i = 0; i < packageIds.length; i++) {
+ packageIds[i] = Integer.parseInt(selectedPackages[i]);
+ }
+
+ try {
+ if (!repoManager.deletePackageVersionsFromRepo(subject, repoId, packageIds)) {
+ FacesContextUtility.addMessage(FacesMessage.SEVERITY_INFO, "Not all packages where deleted because some of them are provided by content sources.");
+ }
+
+ //force reload of the package version list
+ dataModel = null;
+ } catch(Exception e) {
+ FacesContextUtility.addMessage(FacesMessage.SEVERITY_ERROR, "Failed to delete packages: " + packageIds
+ + " from repository: " + repoId + " Error: " + e.getMessage());
+ }
+ }
+
@Override
public DataModel getDataModel() {
if (dataModel == null) {
diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/util/EnterpriseFacesContextUtility.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/util/EnterpriseFacesContextUtility.java
index 3d758a3..dd0adc2 100644
--- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/util/EnterpriseFacesContextUtility.java
+++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/util/EnterpriseFacesContextUtility.java
@@ -71,18 +71,22 @@ public class EnterpriseFacesContextUtility {
int resourceId = FacesContextUtility.getOptionalRequestParameter(ParamConstants.CURRENT_RESOURCE_ID_PARAM,
Integer.class, -1);
- if (resourceId == -1) {
+ if (resourceId == -1 && externalContext.getRequestServletPath().contains("/resource/")) {
resourceId = FacesContextUtility.getRequiredRequestParameter(ParamConstants.RESOURCE_ID_PARAM,
Integer.class);
+ // TODO: Instead call a manager method that returns a ResourceComposite, so we can stick the
+ // ResourceComposite in the request map, rather than just the Resource.
+ resource = LookupUtil.getResourceManager().getResourceById(EnterpriseFacesContextUtility.getSubject(),
+ resourceId);
+ externalContext.getRequestMap().put(AttrConstants.RESOURCE_ATTR, resource);
+
+ return resource;
}
- // TODO: Instead call a manager method that returns a ResourceComposite, so we can stick the
- // ResourceComposite in the request map, rather than just the Resource.
- resource = LookupUtil.getResourceManager().getResourceById(EnterpriseFacesContextUtility.getSubject(),
- resourceId);
- externalContext.getRequestMap().put(AttrConstants.RESOURCE_ATTR, resource);
+ } else {
+ return resource;
}
- return resource;
+ throw new IllegalStateException("Resource not found in the request params.");
}
/**
diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/content/createRepo.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/content/createRepo.xhtml
index 393b688..518df01 100644
--- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/content/createRepo.xhtml
+++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/content/createRepo.xhtml
@@ -61,6 +61,17 @@
<td align="right">Private:</td>
<td align="left"><h:selectBooleanCheckbox id="isPrivate" value="#{CreateRepoUIBean.repo.private}"/></td>
</tr>
+ <tr>
+ <td align="right">Owner:</td>
+ <td align="left">
+ <h:selectOneMenu rendered="#{CreateRepoUIBean.repositoryManager}"
+ value="#{CreateRepoUIBean.repo.owner.name}">
+ <f:selectItems value="#{CreateRepoUIBean.availableOwners}" />
+ </h:selectOneMenu>
+ <h:outputText rendered="#{not CreateRepoUIBean.repositoryManager}"
+ value="#{CreateRepoUIBean.repo.owner.name}"/>
+ </td>
+ </tr>
</table>
</rich:panel>
diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/content/repo.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/content/repo.xhtml
index 5e63d51..e5b20a2 100644
--- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/content/repo.xhtml
+++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/content/repo.xhtml
@@ -64,7 +64,24 @@
value="#{RepoDetailsUIBean.repo.description}" /> <h:outputText
rendered="${mode ne 'edit'}"
value="#{RepoDetailsUIBean.repo.description}" /></td>
- </tr>
+ </tr>
+ <tr>
+ <td align="right"><b>Private:</b></td>
+ <td align="left"><h:selectBooleanCheckbox
+ rendered="${mode eq 'edit'}" value="#{CreateRepoUIBean.repo.private}"/>
+ <h:outputText rendered="${mode ne 'edit'}" value="#{RepoDetailsUIBean.repo.private}" />
+ </td>
+ </tr>
+ <tr>
+ <td align="right"><b>Owner:</b></td>
+ <td align="left">
+ <h:selectOneMenu rendered="${mode eq 'edit' and RepoDetailsUIBean.repositoryManager}"
+ value="#{RepoDetailsUIBean.repo.owner.name}">
+ <f:selectItems value="#{RepoDetailsUIBean.availableOwners}"/>
+ </h:selectOneMenu>
+ <h:outputText rendered="${mode ne 'edit' or not RepoDetailsUIBean.repositoryManager}" value="#{RepoDetailsUIBean.repo.owner.name}"/>
+ </td>
+ </tr>
<tr>
<td align="right"><b>Sync Schedule:</b></td>
<td align="left"><h:inputText
@@ -619,7 +636,13 @@
onclick="if (!confirm('#{confirmInstallMessage}')) return false"
styleClass="on-pager-button buttonsmall"
rendered="#{RepoDetailsUIBean.inventoryManager}" />
-
+ <onc:selectCommandButton
+ action="#{RepoPackageVersionsUIBean.deleteSelectedPackages}"
+ value="DELETE PACKAGES" target="selectedPackages"
+ onclick="if (!confirm('Are you sure to delete the selected packages?\n\nOnly packages that don\'t come from content sources and that aren\'t and never have been installed to some resource will actually be deleted.')) return false"
+ styleClass="on-pager-button buttonsmall"
+ rendered="#{not RepoDetailsUIBean.hasContentSources}" />
+
<ui:param name="paginationDataTableName"
value="repoPackageVersionsDataTable" />
<ui:param name="paginationDataModel"
@@ -637,35 +660,75 @@
</h:panelGrid>
</rich:panel>
-
- <rich:panel rendered="#{not RepoDetailsUIBean.hasContentSources}">
+ </a4j:region>
+ </h:form>
+
+ <h:form rendered="#{not RepoDetailsUIBean.hasContentSources and RepoDetailsUIBean.editable}">
+ <rich:panel >
<f:facet name="header">
<h:outputText value="Upload New Package"/>
</f:facet>
- <h:messages id="uploadmessages"
- showSummary="true"
- showDetail="true"
- infoClass="InfoBlock"
- warnClass="WarnBlock"
- errorClass="ErrorBlock"
- fatalClass="FatalBlock"
- globalOnly="true"
- layout="table"
- width="100%"/>
-
- <rich:fileUpload
- id="upload"
- fileUploadListener="#{RepoDetailsUIBean.packageUploadListener}"
- acceptedTypes="*"
- noDuplicate="true"
- immediateUpload="true"
- autoclear="false"
- allowFlash="false">
- <a4j:support event="onuploadcomplete" reRender="uploadmessages" />
- </rich:fileUpload>
- </rich:panel>
- </a4j:region>
+ <h:panelGrid columns="2">
+
+ <h:panelGroup style="float:right">
+ <b>File <span class="required-marker-text">*</span></b>
+ </h:panelGroup>
+ <h:panelGroup style="clear:both">
+ <input type="button"
+ class="buttonmed"
+ value="UPLOAD FILE..."
+ onclick="javascript:open('/rhq/resource/content/file-upload.xhtml', 'uploadwin', 'titlebar=0,toolbar=0,location=0,menubar=0,directories=0,resizable=0,height=160,width=450')"/>
+ <rich:spacer width="5" />
+ <h:outputText rendered="#{UploadNewPackageUIBean.fileUploaded}"
+ value="File Uploaded: #{UploadNewPackageUIBean.fileItem.fileName}"/>
+ </h:panelGroup>
+
+ <ui:remove><!-- row 1 --></ui:remove>
+ <h:panelGroup style="float: right">
+ <b>Type <span class="required-marker-text">*</span></b>
+ </h:panelGroup>
+ <h:panelGroup style="clear: both">
+ <h:selectOneMenu value="#{CreateNewPackageUIBean.selectedPackageTypeId}">
+ <f:selectItems value="#{CreateNewPackageUIBean.packageTypes}"/>
+ </h:selectOneMenu>
+ </h:panelGroup>
+
+ <ui:remove><!-- row 2 --></ui:remove>
+ <h:panelGroup style="float: right">
+ <b>Name <span class="required-marker-text">*</span></b>
+ </h:panelGroup>
+ <h:panelGroup style="clear: both">
+ <h:inputText id="packageName" value="#{CreateNewPackageUIBean.packageName}" required="true"/>
+ <h:message for="packageName" styleClass="ValidationErrorText"/>
+ </h:panelGroup>
+
+ <ui:remove><!-- row 3 --></ui:remove>
+ <h:panelGroup style="float: right">
+ <b>Version <span class="required-marker-text">*</span></b>
+ </h:panelGroup>
+ <h:panelGroup style="clear: both">
+ <h:inputText id="initialVersion" value="#{CreateNewPackageUIBean.version}" required="true"/>
+ <h:message for="initialVersion" styleClass="ValidationErrorText"/>
+ </h:panelGroup>
+
+ <ui:remove><!-- row 4 --></ui:remove>
+ <h:panelGroup style="float: right">
+ <b>Architecture <span class="required-marker-text">*</span></b>
+ </h:panelGroup>
+ <h:panelGroup style="clear: both">
+ <h:selectOneMenu value="#{CreateNewPackageUIBean.selectedArchitectureId}">
+ <f:selectItems value="#{CreateNewPackageUIBean.architectures}" />
+ </h:selectOneMenu>
+ </h:panelGroup>
+
+ </h:panelGrid>
+
+ <input type="hidden" name="repoOption" value="dummy-non-null-value-to-trick-the-ui-bean-to-do-our-thing"/>
+ <input type="hidden" name="id" value="${param.id}" />
+ <input type="hidden" name="mode" value="${param.mode}" />
+ <h:commandButton action="#{CreateNewPackageUIBean.createPackage}" value="CREATE PACKAGE" styleClass="buttonmed"/>
+ </rich:panel>
</h:form>
<h:form id="repoDistributionListForm" rendered="#{RepoDetailsUIBean.repositoryManager and RepoDistributionUIBean.dataModel.rowCount gt 0}">
diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/content/create-plain.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/content/create-plain.xhtml
new file mode 100644
index 0000000..dba508b
--- /dev/null
+++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/content/create-plain.xhtml
@@ -0,0 +1,149 @@
+<ui:composition template="/rhq/resource/layout/main-plain.xhtml"
+ xmlns="http://www.w3.org/1999/xhtml"
+ xmlns:h="http://java.sun.com/jsf/html"
+ xmlns:f="http://java.sun.com/jsf/core"
+ xmlns:ui="http://java.sun.com/jsf/facelets"
+ xmlns:c="http://java.sun.com/jstl/core"
+ xmlns:a4j="http://richfaces.org/a4j"
+ xmlns:rich="http://richfaces.ajax4jsf.org/rich">
+
+ <ui:define name="content">
+
+ <rich:panel id="fileUploadPanel">
+ <f:facet name="header">
+ <h:outputText value="Package File"/>
+ </f:facet>
+
+ <h:panelGrid columns="1" width="100%" rendered="${ResourceUIBean.permissions.content}">
+ <rich:panel>
+ <input type="button"
+ class="buttonmed"
+ value="UPLOAD FILE..."
+ onclick="javascript:open('/rhq/resource/content/file-upload.xhtml', 'uploadwin', 'titlebar=0,toolbar=0,location=0,menubar=0,directories=0,resizable=0,height=160,width=450')"/>
+ <rich:spacer width="5" />
+ <h:outputText rendered="#{UploadNewPackageUIBean.fileUploaded}"
+ value="File Uploaded: #{UploadNewPackageUIBean.fileItem.fileName}"/>
+ </rich:panel>
+ </h:panelGrid>
+
+ <h:outputText rendered="#{!ResourceUIBean.permissions.content}"
+ value="You do not have permissions to upload content"/>
+
+ </rich:panel>
+
+ <h:form id="uploadForm">
+ <input type="hidden" name="id" value="${param.id}"/>
+
+ <rich:panel rendered="#{CreateNewPackageUIBean.needRequestPackageDetails}">
+
+ <f:facet name="header">New Package Details</f:facet>
+
+ <h:panelGrid columns="2">
+
+ <ui:remove><!-- row 1 --></ui:remove>
+ <h:panelGroup style="float: right">
+ <b>Type <span class="required-marker-text">*</span></b>
+ </h:panelGroup>
+ <h:panelGroup style="clear: both">
+ <h:selectOneMenu value="#{CreateNewPackageUIBean.selectedPackageTypeId}">
+ <f:selectItems value="#{CreateNewPackageUIBean.packageTypes}"/>
+ </h:selectOneMenu>
+ </h:panelGroup>
+
+ <ui:remove><!-- row 2 --></ui:remove>
+ <h:panelGroup style="float: right">
+ <b>Name <span class="required-marker-text">*</span></b>
+ </h:panelGroup>
+ <h:panelGroup style="clear: both">
+ <h:inputText id="packageName" value="#{CreateNewPackageUIBean.packageName}" required="true"/>
+ <h:message for="packageName" styleClass="ValidationErrorText"/>
+ </h:panelGroup>
+
+ <ui:remove><!-- row 3 --></ui:remove>
+ <h:panelGroup style="float: right">
+ <b>Version <span class="required-marker-text">*</span></b>
+ </h:panelGroup>
+ <h:panelGroup style="clear: both">
+ <h:inputText id="initialVersion" value="#{CreateNewPackageUIBean.version}" required="true"/>
+ <h:message for="initialVersion" styleClass="ValidationErrorText"/>
+ </h:panelGroup>
+
+ <ui:remove><!-- row 4 --></ui:remove>
+ <h:panelGroup style="float: right">
+ <b>Architecture <span class="required-marker-text">*</span></b>
+ </h:panelGroup>
+ <h:panelGroup style="clear: both">
+ <h:selectOneMenu value="#{CreateNewPackageUIBean.selectedArchitectureId}">
+ <f:selectItems value="#{CreateNewPackageUIBean.architectures}" />
+ </h:selectOneMenu>
+ </h:panelGroup>
+
+ </h:panelGrid>
+
+ </rich:panel>
+
+ <rich:panel rendered="#{not CreateNewPackageUIBean.needRequestPackageDetails}">
+
+ <f:facet name="header">Package Update Details</f:facet>
+
+ <h:panelGrid columns="2">
+
+ <h:panelGroup style="float: right">
+ <b>Version <span class="required-marker-text">*</span></b>
+ </h:panelGroup>
+ <h:panelGroup style="clear: both">
+ <h:inputText id="updateVersion" value="#{CreateNewPackageUIBean.version}" required="true"/>
+ <h:message for="updateVersion" styleClass="ValidationErrorText"/>
+ </h:panelGroup>
+
+ </h:panelGrid>
+
+ </rich:panel>
+
+ <div class="note-panel"><span class="required-marker-text">*</span><span> denotes a required field.</span></div>
+
+ <rich:panel>
+
+ <f:facet name="header">Repository</f:facet>
+
+ <p>Select one of the following options describing in which repository the new package should be created.</p>
+
+ <input type="radio" name="repoOption" value="subscribed">Currently Subscribed Repository</input>
+ <rich:spacer width="5"/>
+ <h:selectOneMenu value="#{CreateNewPackageUIBean.subscribedRepoId}">
+ <f:selectItems value="#{CreateNewPackageUIBean.subscribedRepos}" />
+ </h:selectOneMenu>
+ <br/>
+ <input type="radio" name="repoOption" value="unsubscribed">Existing Repository</input>
+ <rich:spacer width="5"/>
+ <h:selectOneMenu value="#{CreateNewPackageUIBean.unsubscribedRepoId}">
+ <f:selectItems value="#{CreateNewPackageUIBean.unsubscribedRepos}" />
+ </h:selectOneMenu>
+ <br/>
+ <input type="radio" name="repoOption" value="new">New Repository</input>
+ <rich:spacer width="5"/><h:inputText value="#{CreateNewPackageUIBean.newRepoName}"/>
+ <br/>
+ <input type="radio" name="repoOption" value="none" checked="true">None</input>
+ <br/>
+
+ </rich:panel>
+
+ <h:panelGrid id="buttonGrid" columns="2" styleClass="buttons-table" columnClasses="button-cell">
+
+ <h:commandButton style="margin-top: 10px;" value="CONTINUE"
+ action="#{CreateNewPackageUIBean.createPackage}" styleClass="buttonmed"
+ rendered="#{UploadNewPackageUIBean.fileUploaded}"/>
+ <h:commandButton style="margin-top: 10px;" value="CONTINUE"
+ disabled="true" styleClass="buttonmed-disabled"
+ rendered="#{!UploadNewPackageUIBean.fileUploaded}"/>
+
+ <h:commandButton style="margin-top: 10px;" value="CANCEL"
+ action="#{CreateNewPackageUIBean.cancel}" styleClass="buttonmed"/>
+
+ </h:panelGrid>
+
+ </h:form>
+
+ </ui:define>
+
+</ui:composition>
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerBean.java
index eb71dfe..a5209bc 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerBean.java
@@ -1556,32 +1556,42 @@ public class ContentManagerBean implements ContentManagerLocal, ContentManagerRe
@SuppressWarnings("unchecked")
public PackageVersion getUploadedPackageVersion(String packageName, int packageTypeId, String version,
int architectureId, InputStream packageBitStream, Map<String, String> packageUploadDetails,
- int newResourceTypeId) {
+ Integer newResourceTypeId) {
PackageVersion packageVersion = null;
-
+ PackageType packageType = null;
+
//default version to 1.0 if is null, not provided for any reason.
if ((version == null) || (version.trim().length() == 0)) {
version = "1.0";
}
- // See if package version already exists for the resource package
- Query packageVersionQuery = entityManager.createNamedQuery(PackageVersion.QUERY_FIND_BY_PACKAGE_DETAILS_KEY_WITH_NON_NULL_RESOURCE_TYPE);
- packageVersionQuery.setFlushMode(FlushModeType.COMMIT);
- packageVersionQuery.setParameter("packageName", packageName);
- PackageType packageType = contentManager.getResourceCreationPackageType(newResourceTypeId);
- packageVersionQuery.setParameter("packageTypeName", packageType.getName());
- packageVersionQuery.setParameter("resourceTypeId", newResourceTypeId);
-
Architecture architecture = entityManager.find(Architecture.class, architectureId);
- packageVersionQuery.setParameter("architectureName", architecture.getName());
- packageVersionQuery.setParameter("version", version);
- // Result of the query should be either 0 or 1
- List<PackageVersion> existingPackageVersionList = packageVersionQuery.getResultList();
+ // See if package version already exists for the resource package
+ if (newResourceTypeId != null) {
+ Query packageVersionQuery = null;
+
+ packageVersionQuery = entityManager.createNamedQuery(PackageVersion.QUERY_FIND_BY_PACKAGE_DETAILS_KEY_WITH_NON_NULL_RESOURCE_TYPE);
+ packageVersionQuery.setParameter("resourceTypeId", newResourceTypeId);
+
+ packageVersionQuery.setFlushMode(FlushModeType.COMMIT);
+ packageVersionQuery.setParameter("packageName", packageName);
+
+ packageType = contentManager.getResourceCreationPackageType(newResourceTypeId);
+ packageVersionQuery.setParameter("packageTypeName", packageType.getName());
+
+ packageVersionQuery.setParameter("architectureName", architecture.getName());
+ packageVersionQuery.setParameter("version", version);
- if (existingPackageVersionList.size() > 0) {
- packageVersion = existingPackageVersionList.get(0);
+ // Result of the query should be either 0 or 1
+ List<PackageVersion> existingPackageVersionList = packageVersionQuery.getResultList();
+
+ if (existingPackageVersionList.size() > 0) {
+ packageVersion = existingPackageVersionList.get(0);
+ }
+ } else {
+ packageType = entityManager.find(PackageType.class, packageTypeId);
}
Package existingPackage = null;
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerLocal.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerLocal.java
index 6500b32..1840fc6 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerLocal.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerLocal.java
@@ -215,7 +215,7 @@ public interface ContentManagerLocal {
InputStream packageBitStream);
PackageVersion getUploadedPackageVersion(String packageName, int packageTypeId, String version, int architectureId,
- InputStream packageBitStream, Map<String, String> packageUploadDetails, int newResourceTypeId);
+ InputStream packageBitStream, Map<String, String> packageUploadDetails, Integer newResourceTypeId);
/**
* Very simple method that persists the given package version within its own transaction.
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentUIManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentUIManagerBean.java
index a3a377a..0fa58e7 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentUIManagerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentUIManagerBean.java
@@ -87,6 +87,18 @@ public class ContentUIManagerBean implements ContentUIManagerLocal {
return packageType;
}
+ public List<PackageType> getPackageTypes() {
+ OrderingField orderingField = new OrderingField("pt.displayName", PageOrdering.ASC);
+
+ Query query = PersistenceUtility.createQueryWithOrderBy(entityManager,
+ PackageType.QUERY_FIND_ALL, orderingField);
+
+ @SuppressWarnings("unchecked")
+ List<PackageType> packageList = (List<PackageType>) query.getResultList();
+
+ return packageList;
+ }
+
@SuppressWarnings("unchecked")
public List<PackageType> getPackageTypes(int resourceTypeId) {
OrderingField orderingField = new OrderingField("pt.displayName", PageOrdering.ASC);
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentUIManagerLocal.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentUIManagerLocal.java
index 6b9d2f8..3de75e0 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentUIManagerLocal.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentUIManagerLocal.java
@@ -75,6 +75,11 @@ public interface ContentUIManagerLocal {
PackageType getPackageType(int id);
/**
+ * @return all package types
+ */
+ List<PackageType> getPackageTypes();
+
+ /**
* Returns all package types that are available to the specified resource type.
*
* @param resourceTypeId identifies the resource type
commit da7d39986f21e6d7c714128a3a861ef7d1d29abc
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Thu Feb 17 12:34:03 2011 +0100
Running the RHQ server with the security manager turned on, with all permissions. this is to support CLI script sandboxing.
diff --git a/modules/enterprise/server/container/src/main/bin-resources/bin/rhq-server.security-policy b/modules/enterprise/server/container/src/main/bin-resources/bin/rhq-server.security-policy
new file mode 100644
index 0000000..8860b47
--- /dev/null
+++ b/modules/enterprise/server/container/src/main/bin-resources/bin/rhq-server.security-policy
@@ -0,0 +1,10 @@
+// We need the SecurityManager installed to enable sandboxing of CLI scripts
+// but we don't define any other security measures on the RHQ server itself.
+//
+// Granting all permissions allows us to run the RHQ server as if no security
+// manager was in place (which is assumed by default by JBoss AS) but be able
+// to use it when we need it for our own purposes.
+
+grant {
+ permission java.security.AllPermission;
+};
diff --git a/modules/enterprise/server/container/src/main/bin-resources/bin/rhq-server.sh b/modules/enterprise/server/container/src/main/bin-resources/bin/rhq-server.sh
index b08ceaa..b255914 100644
--- a/modules/enterprise/server/container/src/main/bin-resources/bin/rhq-server.sh
+++ b/modules/enterprise/server/container/src/main/bin-resources/bin/rhq-server.sh
@@ -287,7 +287,8 @@ if [ -z "$RHQ_SERVER_JAVA_OPTS" ]; then
RHQ_SERVER_JAVA_OPTS="-Xms1024M -Xmx1024M -XX:PermSize=256M -XX:MaxPermSize=256M -Djava.net.preferIPv4Stack=true -Djboss.server.log.dir=${_LOG_DIR_PATH}"
fi
# Add the JVM opts that we always want to specify, whether or not the user set RHQ_SERVER_JAVA_OPTS.
-RHQ_SERVER_JAVA_OPTS="-Dapp.name=rhq-server $RHQ_SERVER_JAVA_OPTS -Djava.awt.headless=true -Djboss.platform.mbeanserver -Dsun.lang.ClassLoader.allowArraySyntax=true -Djava.util.logging.config.file=$RHQ_SERVER_HOME/jbossas/server/default/conf/logging.properties"
+# Note that the double equals for the policy file specification IS INTENTIONAL
+RHQ_SERVER_JAVA_OPTS="-Dapp.name=rhq-server $RHQ_SERVER_JAVA_OPTS -Djava.awt.headless=true -Djboss.platform.mbeanserver -Dsun.lang.ClassLoader.allowArraySyntax=true -Djava.util.logging.config.file=$RHQ_SERVER_HOME/jbossas/server/default/conf/logging.properties -Djava.security.manager -Djava.security.policy==$RHQ_SERVER_HOME/bin/rhq-server.security-policy"
debug_msg "RHQ_SERVER_JAVA_OPTS: $RHQ_SERVER_JAVA_OPTS"
debug_msg "RHQ_SERVER_ADDITIONAL_JAVA_OPTS: $RHQ_SERVER_ADDITIONAL_JAVA_OPTS"
diff --git a/modules/enterprise/server/container/src/main/bin-resources/bin/wrapper/rhq-server-wrapper.conf b/modules/enterprise/server/container/src/main/bin-resources/bin/wrapper/rhq-server-wrapper.conf
index 01b218c..b4f178b 100644
--- a/modules/enterprise/server/container/src/main/bin-resources/bin/wrapper/rhq-server-wrapper.conf
+++ b/modules/enterprise/server/container/src/main/bin-resources/bin/wrapper/rhq-server-wrapper.conf
@@ -68,6 +68,9 @@ wrapper.java.additional.8="-Djboss.server.log.dir=%RHQ_SERVER_WRAPPER_LOG_DIR_PA
wrapper.java.additional.9="-Djava.util.logging.config.file=%RHQ_SERVER_HOME%/jbossas/server/default/conf/logging.properties"
wrapper.java.additional.10=-Djboss.platform.mbeanserver
wrapper.java.additional.11=-Dsun.lang.ClassLoader.allowArraySyntax=true
+wrapper.java.additional.12=-Djava.security.manager
+# the double equals for the policy file specification IS INTENTIONAL
+wrapper.java.additional.13="-Djava.security.policy==%RHQ_SERVER_HOME%/bin/rhq-server.security-policy"
# We want to make sure the Server starts in the JBossAS bin directory
wrapper.working.dir=%RHQ_SERVER_HOME%/jbossas/bin
commit 858c82d7da03de9cbd0789ee84135fb7be324afd
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Thu Feb 17 12:30:58 2011 +0100
adding ability to delete a package version from a repo manually.
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/content/PackageVersion.java b/modules/core/domain/src/main/java/org/rhq/core/domain/content/PackageVersion.java
index c79dd0a..c42862e 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/content/PackageVersion.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/content/PackageVersion.java
@@ -157,7 +157,11 @@ import org.rhq.core.domain.util.OSGiVersionComparator;
+ " AND pv.repoPackageVersions IS EMPTY " //
+ " AND pv.installedPackages IS EMPTY " //
+ " AND pv.installedPackageHistory IS EMPTY "),
-
+ @NamedQuery(name = PackageVersion.DELETE_MULTIPLE_IF_NO_CONTENT_SOURCES_OR_REPOS, query = "DELETE PackageVersion pv "
+ + " WHERE pv.id IN ( :packageVersionIds )" //
+ + " AND pv.repoPackageVersions IS EMPTY " //
+ + " AND pv.installedPackages IS EMPTY " //
+ + " AND pv.installedPackageHistory IS EMPTY "),
// the bulk delete that removes the PVPV mapping from orphaned package versions
@NamedQuery(name = PackageVersion.DELETE_PVPV_IF_NO_CONTENT_SOURCES_OR_REPOS, query = "DELETE ProductVersionPackageVersion pvpv "
+ " WHERE pvpv.packageVersion.id NOT IN (SELECT pvcs.packageVersion.id "
@@ -250,7 +254,13 @@ import org.rhq.core.domain.util.OSGiVersionComparator;
+ " FROM PackageVersion pv"
+ " JOIN pv.repoPackageVersions rpv"
+ " WHERE pv.generalPackage.id = :packageId"
- + " AND rpv.repo.id = :repoId")
+ + " AND rpv.repo.id = :repoId"),
+ @NamedQuery(name = PackageVersion.QUERY_FIND_DELETEABLE_IDS_IN_REPO, query = "SELECT pv.id FROM PackageVersion pv"
+ + " WHERE (pv.id, 1) IN"
+ + " (SELECT pv2.id, (SELECT COUNT(rpv) FROM RepoPackageVersion rpv WHERE rpv.packageVersion.id = pv2.id)"
+ + " FROM PackageVersion pv2"
+ + " WHERE pv2.id IN ( :packageVersionIds )"
+ + " AND pv2.id IN (SELECT rpv.packageVersion.id FROM RepoPackageVersion rpv WHERE rpv.repo.id = :repoId))")
})
@SequenceGenerator(name = "SEQ", sequenceName = "RHQ_PACKAGE_VERSION_ID_SEQ")
@Table(name = "RHQ_PACKAGE_VERSION")
@@ -278,6 +288,7 @@ public class PackageVersion implements Serializable {
public static final String QUERY_GET_PKG_BITS_LENGTH_BY_PKG_DETAILS_AND_RES_ID = "PackageVersion.getPkgBitsLengthByPkgDetailsAndResId";
public static final String DELETE_IF_NO_CONTENT_SOURCES_OR_REPOS = "PackageVersion.deleteIfNoContentSourcesOrRepos";
public static final String DELETE_SINGLE_IF_NO_CONTENT_SOURCES_OR_REPOS = "PackageVersion.deleteSingleIfNoContentSourcesOrRepos";
+ public static final String DELETE_MULTIPLE_IF_NO_CONTENT_SOURCES_OR_REPOS = "PackageVersion.deleteMultipleIfNoContentSourcesOrRepos";
public static final String DELETE_PVPV_IF_NO_CONTENT_SOURCES_OR_REPOS = "PackageVersion.deletePVPVIfNoContentSourcesOrRepos";
public static final String FIND_EXTRA_PROPS_IF_NO_CONTENT_SOURCES_OR_REPOS = "PackageVersion.findOrphanedExtraProps";
public static final String FIND_FILES_IF_NO_CONTENT_SOURCES_OR_REPOS = "PackageVersion.findOrphanedFiles";
@@ -288,6 +299,7 @@ public class PackageVersion implements Serializable {
public static final String QUERY_FIND_BY_ID = "PackageVersion.findById";
public static final String QUERY_FIND_PACKAGE_BY_FILENAME = "PackageVersion.findPackageByFilename";
public static final String QUERY_FIND_PACKAGEVERSION_BY_FILENAME = "PackageVersion.findPackageVersionByFilename";
+ public static final String QUERY_FIND_DELETEABLE_IDS_IN_REPO = "PackageVersion.findDeleteableVersionIds";
/**
* This is a default {@link Comparator} implementation for package versions.
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/content/RepoPackageVersion.java b/modules/core/domain/src/main/java/org/rhq/core/domain/content/RepoPackageVersion.java
index 90754ac..dc3b48a 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/content/RepoPackageVersion.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/content/RepoPackageVersion.java
@@ -45,19 +45,29 @@ import javax.persistence.Table;
@NamedQueries( {
@NamedQuery(name = RepoPackageVersion.DELETE_BY_REPO_ID,
query = "DELETE RepoPackageVersion cpv WHERE cpv.repo.id = :repoId"),
-
+
+ //TODO this looks suspicious. How can this ever delete a package version
+ //if there are ANY content sources providing ANY packages? I miss a WHERE in this query.
// Deletes the repo <-> package mapping when the package has no providers for this package
@NamedQuery(name = RepoPackageVersion.DELETE_WHEN_NO_PROVIDER, query = "DELETE RepoPackageVersion rpv "
+ "WHERE rpv.repo.id = :repoId " //
+ " AND (SELECT COUNT(pvcs.packageVersion.id) "
+ " FROM PackageVersionContentSource pvcs) = 0"
+ ),
+ @NamedQuery(name = RepoPackageVersion.DELETE_MULTIPLE_WHEN_NO_PROVIDER, query = "DELETE RepoPackageVersion rpv"
+ + " WHERE rpv.repo.id = :repoId"
+ + " AND rpv.packageVersion.id IN ( :packageVersionIds )"
+ + " AND (SELECT COUNT(pvcs.packageVersion.id) "
+ + " FROM PackageVersionContentSource pvcs"
+ + " WHERE pvcs.packageVersion.id = rpv.packageVersion.id) = 0"
)
})
@Table(name = "RHQ_REPO_PKG_VERSION_MAP")
public class RepoPackageVersion implements Serializable {
public static final String DELETE_BY_REPO_ID = "RepoPackageVersion.deleteByRepoId";
public static final String DELETE_WHEN_NO_PROVIDER = "RepoPackageVersion.deleteWhenNoProvider";
-
+ public static final String DELETE_MULTIPLE_WHEN_NO_PROVIDER = "RepoPackageVersion.deleteMultipleWhenNoProvider";
+
private static final long serialVersionUID = 1L;
/*
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/RepoManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/RepoManagerBean.java
index 04d5efe..9dbf92b 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/RepoManagerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/RepoManagerBean.java
@@ -20,6 +20,7 @@ package org.rhq.enterprise.server.content;
import java.text.ParseException;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
@@ -157,6 +158,45 @@ public class RepoManagerBean implements RepoManagerLocal, RepoManagerRemote {
entityManager.remove(deleteMe);
}
+ public boolean deletePackageVersionsFromRepo(Subject subject, int repoId, int[] packageVersionIds) {
+ if (packageVersionIds == null || packageVersionIds.length == 0) {
+ return true;
+ }
+
+ if (!authzManager.canUpdateRepo(subject, repoId)) {
+ throw new PermissionException("User [" + subject + "] cannot update the repo with id " + repoId + " and therefore cannot delete package versions from it.");
+ }
+
+ ArrayList<Integer> ids = new ArrayList<Integer>();
+ for(int id : packageVersionIds) {
+ ids.add(id);
+ }
+
+ Query deleteable = entityManager.createNamedQuery(PackageVersion.QUERY_FIND_DELETEABLE_IDS_IN_REPO);
+ deleteable.setParameter("repoId", repoId);
+ deleteable.setParameter("packageVersionIds", ids);
+
+ @SuppressWarnings("unchecked")
+ List<Integer> deleteableIds = (List<Integer>) deleteable.getResultList();
+
+ if (deleteableIds.isEmpty()) {
+ return false;
+ }
+
+ Query deleteRepoPackageVersions = entityManager.createNamedQuery(RepoPackageVersion.DELETE_MULTIPLE_WHEN_NO_PROVIDER);
+ deleteRepoPackageVersions.setParameter("repoId", repoId);
+ deleteRepoPackageVersions.setParameter("packageVersionIds", deleteableIds);
+
+ deleteRepoPackageVersions.executeUpdate();
+
+ Query deletePackageVersions = entityManager.createNamedQuery(PackageVersion.DELETE_MULTIPLE_IF_NO_CONTENT_SOURCES_OR_REPOS);
+ deletePackageVersions.setParameter("packageVersionIds", deleteableIds);
+
+ int deleted = deletePackageVersions.executeUpdate();
+
+ return deleted == packageVersionIds.length;
+ }
+
@SuppressWarnings("unchecked")
public PageList<Repo> findRepos(Subject subject, PageControl pc) {
pc.initDefaultOrderingField("c.name");
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/RepoManagerLocal.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/RepoManagerLocal.java
index 640bee3..99ab618 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/RepoManagerLocal.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/RepoManagerLocal.java
@@ -110,6 +110,11 @@ public interface RepoManagerLocal {
PageList<PackageVersion> findPackageVersionsInRepo(Subject subject, int repoId, String filter, PageControl pc);
/**
+ * @see RepoManagerRemote#deletePackageVersionsFromRepo(Subject, int, int)
+ */
+ boolean deletePackageVersionsFromRepo(Subject subject, int repoId, int[] packageVersionId);
+
+ /**
* @see RepoManagerRemote#getLatestPackageVersion(Subject, int, int)
*/
PackageVersion getLatestPackageVersion(Subject subject, int packageId, int repoId);
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/RepoManagerRemote.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/RepoManagerRemote.java
index 99c4ca0..54d2732 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/RepoManagerRemote.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/RepoManagerRemote.java
@@ -185,6 +185,24 @@ public interface RepoManagerRemote {
@WebParam(name = "pageControl") PageControl pc);
/**
+ * Deletes package versions from a repo if they are not referenced by
+ * a content source.
+ * <p>
+ * The package versions themselves are not deleted until some content source or repository
+ * is deleted at which point orphans detection is performed.
+ *
+ * @param subject
+ * @param repoId
+ * @param packageVersionIds
+ * @return true if all the package versions were successfully deleted, false if some references exist.
+ */
+ @WebMethod
+ boolean deletePackageVersionsFromRepo(
+ @WebParam(name = "subject") Subject subject,
+ @WebParam(name = "repoId") int repoId,
+ @WebParam(name = "packageVersionIds") int[] packageVersionId);
+
+ /**
* Gets all resources that are subscribed to the given repo.
*
* @param subject The logged in user's subject.
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/webservices/WebservicesManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/webservices/WebservicesManagerBean.java
index 82c9522..60fb16c 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/webservices/WebservicesManagerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/webservices/WebservicesManagerBean.java
@@ -795,6 +795,10 @@ public class WebservicesManagerBean implements WebservicesRemote {
return repoManager.getLatestPackageVersion(subject, packageId, repoId);
}
+ public boolean deletePackageVersionsFromRepo(Subject subject, int repoId, int[] packageVersionIds) {
+ return repoManager.deletePackageVersionsFromRepo(subject, repoId, packageVersionIds);
+ }
+
public PageList<Resource> findSubscribedResources(Subject subject, int repoId, PageControl pc) {
return repoManager.findSubscribedResources(subject, repoId, pc);
}
commit d4457a3760a832963fe3fd22d5b6ba21fc877f97
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Thu Feb 17 12:29:09 2011 +0100
CLI alert sender runs the script in a sandbox with a timeout.
diff --git a/modules/enterprise/server/plugins/alert-cli/src/main/java/org/rhq/enterprise/server/plugins/alertCli/CliComponent.java b/modules/enterprise/server/plugins/alert-cli/src/main/java/org/rhq/enterprise/server/plugins/alertCli/CliComponent.java
index d11dd3d..93c5fee 100644
--- a/modules/enterprise/server/plugins/alert-cli/src/main/java/org/rhq/enterprise/server/plugins/alertCli/CliComponent.java
+++ b/modules/enterprise/server/plugins/alert-cli/src/main/java/org/rhq/enterprise/server/plugins/alertCli/CliComponent.java
@@ -78,9 +78,11 @@ public class CliComponent implements ServerPluginComponent, ControlFacet {
private static final String PROP_ALERT_DEFINITION_ID = "alertDefinitionId";
private static final String PROP_USER_NAME = "userName";
private static final String PROP_ALERT_DEF_IDS = "alertDefIds";
+ private static final String PROP_SCRIPT_TIMEOUT = "scriptTimeout";
private String pluginName;
private PackageType packageType;
+ private int scriptTimeout;
private SubjectManagerLocal subjectManager;
@@ -105,12 +107,20 @@ public class CliComponent implements ServerPluginComponent, ControlFacet {
packageType = cm.persistServersidePackageType(packageType);
}
+
+ String timeoutValue = context.getPluginConfiguration() == null ? "60" : context.getPluginConfiguration().getSimpleValue(PROP_SCRIPT_TIMEOUT, "60");
+
+ scriptTimeout = Integer.parseInt(timeoutValue);
}
public PackageType getScriptPackageType() {
return packageType;
}
+ public int getScriptTimeout() {
+ return scriptTimeout;
+ }
+
public void start() {
}
diff --git a/modules/enterprise/server/plugins/alert-cli/src/main/java/org/rhq/enterprise/server/plugins/alertCli/CliSender.java b/modules/enterprise/server/plugins/alert-cli/src/main/java/org/rhq/enterprise/server/plugins/alertCli/CliSender.java
index c9a39e0..ce5579b 100644
--- a/modules/enterprise/server/plugins/alert-cli/src/main/java/org/rhq/enterprise/server/plugins/alertCli/CliSender.java
+++ b/modules/enterprise/server/plugins/alert-cli/src/main/java/org/rhq/enterprise/server/plugins/alertCli/CliSender.java
@@ -39,8 +39,10 @@ import javax.script.ScriptException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.rhq.bindings.SandboxedScriptEngine;
import org.rhq.bindings.ScriptEngineFactory;
import org.rhq.bindings.StandardBindings;
+import org.rhq.bindings.StandardScriptPermissions;
import org.rhq.bindings.util.PackageFinder;
import org.rhq.core.domain.alert.Alert;
import org.rhq.core.domain.alert.notification.SenderResult;
@@ -64,12 +66,12 @@ import org.rhq.enterprise.server.util.LookupUtil;
*
* @author Lukas Krejci
*/
-public class CliSender extends AlertSender<ServerPluginComponent> {
+public class CliSender extends AlertSender<CliComponent> {
public static final String PROP_PACKAGE_ID = "packageId";
public static final String PROP_REPO_ID = "repoId";
public static final String PROP_USER_ID = "userId";
-
+
private static final Log LOG = LogFactory.getLog(CliSender.class);
private static final String SUMMARY_TEMPLATE = "Ran script $packageName in version $packageVersion from repo $repoName as user $userName.";
@@ -83,6 +85,10 @@ public class CliSender extends AlertSender<ServerPluginComponent> {
int packageId;
int repoId;
}
+
+ private static class ExceptionHolder {
+ public Throwable throwable;
+ }
public SenderResult send(Alert alert) {
SenderResult result = new SenderResult();
@@ -94,13 +100,41 @@ public class CliSender extends AlertSender<ServerPluginComponent> {
ByteArrayOutputStream scriptOutputStream = new ByteArrayOutputStream();
ScriptEngine engine = getScriptEngine(alert, scriptOutputStream, config);
-
+
+ final SandboxedScriptEngine sandbox = new SandboxedScriptEngine(engine, new StandardScriptPermissions());
+
InputStream packageBits = getPackageBits(config.packageId, config.repoId);
reader = new BufferedReader(new InputStreamReader(packageBits));
- engine.eval(reader);
+ final BufferedReader rdr = reader;
+
+ final ExceptionHolder exceptionHolder = new ExceptionHolder();
+
+ Thread scriptRunner = new Thread(new Runnable() {
+ public void run() {
+ try {
+ sandbox.eval(rdr);
+ } catch (ScriptException e) {
+ exceptionHolder.throwable = e;
+ }
+ }
+ }, "Script Runner for alert " + alert);
+ scriptRunner.setDaemon(true);
+ scriptRunner.start();
+
+ if (pluginComponent.getScriptTimeout() <= 0) {
+ scriptRunner.join();
+ } else {
+ scriptRunner.join(pluginComponent.getScriptTimeout() * 1000);
+ }
+
+ scriptRunner.interrupt();
+ if (exceptionHolder.throwable != null) {
+ throw new Exception("Script failed with an exception.", exceptionHolder.throwable);
+ }
+
String scriptOutput = scriptOutputStream.toString(Charset.defaultCharset().name());
if (scriptOutput.length() == 0) {
diff --git a/modules/enterprise/server/plugins/alert-cli/src/main/resources/META-INF/rhq-serverplugin.xml b/modules/enterprise/server/plugins/alert-cli/src/main/resources/META-INF/rhq-serverplugin.xml
index d893471..4f60e6f 100644
--- a/modules/enterprise/server/plugins/alert-cli/src/main/resources/META-INF/rhq-serverplugin.xml
+++ b/modules/enterprise/server/plugins/alert-cli/src/main/resources/META-INF/rhq-serverplugin.xml
@@ -48,6 +48,11 @@
</serverplugin:control>
</serverplugin:plugin-component>
+ <serverplugin:plugin-configuration>
+ <c:simple-property name="scriptTimeout" type="integer" required="true" default="60"
+ description="The maximum number of seconds a CLI script is allowed run while handling an alert."/>
+ </serverplugin:plugin-configuration>
+
<!-- How does this sender show up in drop downs etc -->
<short-name>CLI Script</short-name>
@@ -58,5 +63,7 @@
<c:simple-property name="packageId" type="integer" required="true" description="The id of the package containing the script to execute."/>
<c:simple-property name="repoId" type="integer" required="true" description="The id of the repo to download the package from."/>
<c:simple-property name="userId" type="integer" required="true" description="The user the script will be run as."/>
+ <c:simple-property name="userName" type="string" required="true" description="The name of the user. This is used while creating/updating the notification to check the authentization. It is only required if the userId is different than the currently logged in user." />
+ <c:simple-property name="userPassword" type="string" required="false" description="The password of the user. This is used while creating/updating the notification to check the authentization. It is only required if the userId is different than the currently logged in user." />
</alert-configuration>
</alert-plugin>
\ No newline at end of file
commit 9a43ba1f5733df211f0fcdb2feef994608bc1a45
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Thu Feb 17 12:27:32 2011 +0100
adding the binding and client-api modules into the server build.
diff --git a/modules/enterprise/pom.xml b/modules/enterprise/pom.xml
index bfd912f..b50dada 100644
--- a/modules/enterprise/pom.xml
+++ b/modules/enterprise/pom.xml
@@ -53,6 +53,8 @@
<module>gui</module>
<module>server/plugins</module>
<module>server/ear</module>
+ <module>binding</module>
+ <module>server/client-api</module>
</modules>
</profile>
@@ -78,6 +80,7 @@
<module>server/ear</module>
<module>server/container-lib</module>
<module>server/container</module>
+ <module>server/client-api</module>
</modules>
</profile>
diff --git a/modules/enterprise/server/ear/pom.xml b/modules/enterprise/server/ear/pom.xml
index 878484d..78c882d 100644
--- a/modules/enterprise/server/ear/pom.xml
+++ b/modules/enterprise/server/ear/pom.xml
@@ -78,6 +78,20 @@
<version>${project.version}</version> <type>sar</type> </dependency>
-->
+ <!-- ** JARs -->
+
+ <dependency>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-script-bindings</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-server-client-api</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
<!-- 3rd Party Deps -->
<!-- ** WARs -->
@@ -182,7 +196,6 @@
<jarModule> <groupId>jboss</groupId> <artifactId>jboss-seam</artifactId> <bundleDir>lib</bundleDir>
<includeInApplicationXml>true</includeInApplicationXml> </jarModule>
-->
-
</modules>
</configuration>
</plugin>
diff --git a/modules/enterprise/server/pom.xml b/modules/enterprise/server/pom.xml
index b2df029..701ed39 100644
--- a/modules/enterprise/server/pom.xml
+++ b/modules/enterprise/server/pom.xml
@@ -39,6 +39,7 @@
<module>plugins</module>
<module>ear</module>
<module>safe-invoker</module>
+ <module>client-api</module>
</modules>
</profile>
commit c08197d8c681214370fc4c284d2a5175142c9dd8
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Thu Feb 17 08:33:31 2011 +0100
adding the capability to put a ScriptEngine in a security sandbox.
diff --git a/modules/enterprise/binding/pom.xml b/modules/enterprise/binding/pom.xml
index 7e6b120..54e2250 100644
--- a/modules/enterprise/binding/pom.xml
+++ b/modules/enterprise/binding/pom.xml
@@ -207,6 +207,7 @@
<excludedGroups>${rhq.testng.excludedGroups}</excludedGroups>
<!-- <argLine>-Xdebug -Xnoagent -Djava.compiler=NONE
-Xrunjdwp:transport=dt_socket,address=8787,server=y,suspend=y</argLine> -->
+ <argLine>-Djava.security.manager -Djava.security.policy==${project.build.testOutputDirectory}/allow-all.policy</argLine>
</configuration>
</plugin>
diff --git a/modules/enterprise/binding/src/main/java/org/rhq/bindings/SandboxedScriptEngine.java b/modules/enterprise/binding/src/main/java/org/rhq/bindings/SandboxedScriptEngine.java
new file mode 100644
index 0000000..faf3e15
--- /dev/null
+++ b/modules/enterprise/binding/src/main/java/org/rhq/bindings/SandboxedScriptEngine.java
@@ -0,0 +1,194 @@
+/*
+ * 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 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.bindings;
+
+import java.io.Reader;
+import java.security.AccessControlContext;
+import java.security.AccessController;
+import java.security.CodeSource;
+import java.security.Permission;
+import java.security.PermissionCollection;
+import java.security.Permissions;
+import java.security.Principal;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+import java.security.ProtectionDomain;
+import java.security.cert.Certificate;
+import java.util.Arrays;
+import java.util.Collection;
+
+import javax.script.Bindings;
+import javax.script.ScriptContext;
+import javax.script.ScriptEngine;
+import javax.script.ScriptEngineFactory;
+import javax.script.ScriptException;
+
+/**
+ * This is a decorator class for any other {@link ScriptEngine} implementation
+ * that runs any of the eval methods with the defined set of {@link Permission}s.
+ * <p>
+ * For the permissions to have any effect, a SecurityManager has to be installed
+ * in the current VM.
+ *
+ * @author Lukas Krejci
+ */
+public class SandboxedScriptEngine implements ScriptEngine {
+
+ private ScriptEngine engine;
+ private AccessControlContext accessControlContext;
+
+ public SandboxedScriptEngine(ScriptEngine engine) {
+ this.engine = engine;
+ }
+
+ public SandboxedScriptEngine(ScriptEngine engine, PermissionCollection permissions) {
+ this(engine);
+ setPermissions(permissions);
+ }
+
+ public SandboxedScriptEngine(ScriptEngine engine, Collection<? extends Permission> permissions) {
+ this(engine);
+ setPermissions(permissions);
+ }
+
+ public void setPermissions(Permission... permissions) {
+ setPermissions(Arrays.asList(permissions));
+ }
+
+ public void setPermissions(Collection<? extends Permission> permissions) {
+ Permissions ps = new Permissions();
+ for(Permission p : permissions) {
+ ps.add(p);
+ }
+
+ setPermissions(ps);
+ }
+
+ public void setPermissions(PermissionCollection permissions) {
+ CodeSource cs = new CodeSource(null, (Certificate[]) null);
+
+ ProtectionDomain domain = new ProtectionDomain(cs, permissions);
+ accessControlContext = new AccessControlContext(new ProtectionDomain[] { domain });
+ }
+
+ public Object eval(final String script, final ScriptContext context) throws ScriptException {
+ try {
+ return AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
+ public Object run() throws Exception {
+ return engine.eval(script, context);
+ }
+ }, accessControlContext);
+ } catch (PrivilegedActionException e) {
+ throw new ScriptException(e);
+ }
+ }
+
+ public Object eval(final Reader reader, final ScriptContext context) throws ScriptException {
+ try {
+ return AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
+ public Object run() throws Exception {
+ return engine.eval(reader, context);
+ }
+ }, accessControlContext);
+ } catch (PrivilegedActionException e) {
+ throw new ScriptException(e);
+ }
+ }
+
+ public Object eval(final String script) throws ScriptException {
+ try {
+ return AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
+ public Object run() throws Exception {
+ return engine.eval(script);
+ }
+ }, accessControlContext);
+ } catch (PrivilegedActionException e) {
+ throw new ScriptException(e);
+ }
+ }
+
+ public Object eval(final Reader reader) throws ScriptException {
+ try {
+ return AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
+ public Object run() throws Exception {
+ return engine.eval(reader);
+ }
+ }, accessControlContext);
+ } catch (PrivilegedActionException e) {
+ throw new ScriptException(e);
+ }
+ }
+
+ public Object eval(final String script, final Bindings n) throws ScriptException {
+ try {
+ return AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
+ public Object run() throws Exception {
+ return engine.eval(script, n);
+ }
+ }, accessControlContext);
+ } catch (PrivilegedActionException e) {
+ throw new ScriptException(e);
+ }
+ }
+
+ public Object eval(final Reader reader, final Bindings n) throws ScriptException {
+ try {
+ return AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
+ public Object run() throws Exception {
+ return engine.eval(reader, n);
+ }
+ }, accessControlContext);
+ } catch (PrivilegedActionException e) {
+ throw new ScriptException(e);
+ }
+ }
+
+ public void put(String key, Object value) {
+ engine.put(key, value);
+ }
+
+ public Object get(String key) {
+ return engine.get(key);
+ }
+
+ public Bindings getBindings(int scope) {
+ return engine.getBindings(scope);
+ }
+
+ public void setBindings(Bindings bindings, int scope) {
+ engine.setBindings(bindings, scope);
+ }
+
+ public Bindings createBindings() {
+ return engine.createBindings();
+ }
+
+ public ScriptContext getContext() {
+ return engine.getContext();
+ }
+
+ public void setContext(ScriptContext context) {
+ engine.setContext(context);
+ }
+
+ public ScriptEngineFactory getFactory() {
+ return engine.getFactory();
+ }
+}
diff --git a/modules/enterprise/binding/src/main/java/org/rhq/bindings/StandardScriptPermissions.java b/modules/enterprise/binding/src/main/java/org/rhq/bindings/StandardScriptPermissions.java
new file mode 100644
index 0000000..01f7222
--- /dev/null
+++ b/modules/enterprise/binding/src/main/java/org/rhq/bindings/StandardScriptPermissions.java
@@ -0,0 +1,95 @@
+/*
+ * 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 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.bindings;
+
+import java.io.FilePermission;
+import java.lang.reflect.ReflectPermission;
+import java.net.SocketPermission;
+import java.security.Permission;
+import java.security.PermissionCollection;
+import java.security.Permissions;
+import java.util.Enumeration;
+import java.util.PropertyPermission;
+
+/**
+ * @author Lukas Krejci
+ */
+public class StandardScriptPermissions extends PermissionCollection {
+
+ private static final long serialVersionUID = 1L;
+
+ private Permissions perms = new Permissions();
+
+ /**
+ * Creates a new instance with the default set of permissions
+ * already added.
+ */
+ public StandardScriptPermissions() {
+ //the JBoss specific perms that must be set
+ add(new RuntimePermission("org.jboss.security.SecurityAssociation.getPrincipalInfo"));
+ add(new RuntimePermission("org.jboss.security.SecurityAssociation.setPrincipalInfo "));
+ add(new RuntimePermission("org.jboss.security.SecurityAssociation.setServer"));
+ add(new RuntimePermission("org.jboss.security.SecurityAssociation.setRunAsRole"));
+
+ //JVM defined runtime perms
+ add(new RuntimePermission("getenv.*"));
+ add(new RuntimePermission("getProtectionDomain"));
+ add(new RuntimePermission("getFileSystemAttributes"));
+ add(new RuntimePermission("readFileDescriptor"));
+ add(new RuntimePermission("writeFileDescriptor"));
+ add(new RuntimePermission("accessDeclaredMembers"));
+ add(new RuntimePermission("queuePrintJob"));
+ add(new RuntimePermission("getStackTrace"));
+ add(new RuntimePermission("preferences"));
+
+ //allow the scripts to connect via sockets
+ add(new SocketPermission("*", "connect,accept"));
+
+ //allow access to the server's file system. let the file perms
+ //guard what is writeable and what is not.
+ add(new FilePermission("<<ALL FILES>>", "read,write,execute,delete"));
+
+ //we don't suppose the serverside scripts to be malevolent, so let's
+ //give them the read access to the system properties.
+ add(new PropertyPermission("*", "read"));
+
+ add(new ReflectPermission("suppressAccessChecks"));
+ }
+
+ public void add(Permission permission) {
+ perms.add(permission);
+ }
+
+ public boolean implies(Permission permission) {
+ return perms.implies(permission);
+ }
+
+ public Enumeration<Permission> elements() {
+ return perms.elements();
+ }
+
+ public boolean isReadOnly() {
+ return perms.isReadOnly();
+ }
+
+ public void setReadOnly() {
+ perms.setReadOnly();
+ }
+}
diff --git a/modules/enterprise/binding/src/test/java/org/rhq/bindings/FakeRhqFacade.java b/modules/enterprise/binding/src/test/java/org/rhq/bindings/FakeRhqFacade.java
new file mode 100644
index 0000000..6420c23
--- /dev/null
+++ b/modules/enterprise/binding/src/test/java/org/rhq/bindings/FakeRhqFacade.java
@@ -0,0 +1,185 @@
+/*
+ * 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 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.bindings;
+
+import java.util.Collections;
+import java.util.Map;
+
+import org.rhq.bindings.client.RhqFacade;
+import org.rhq.core.domain.auth.Subject;
+import org.rhq.enterprise.server.alert.AlertDefinitionManagerRemote;
+import org.rhq.enterprise.server.alert.AlertManagerRemote;
+import org.rhq.enterprise.server.auth.SubjectManagerRemote;
+import org.rhq.enterprise.server.authz.RoleManagerRemote;
+import org.rhq.enterprise.server.bundle.BundleManagerRemote;
+import org.rhq.enterprise.server.configuration.ConfigurationManagerRemote;
+import org.rhq.enterprise.server.content.ContentManagerRemote;
+import org.rhq.enterprise.server.content.RepoManagerRemote;
+import org.rhq.enterprise.server.discovery.DiscoveryBossRemote;
+import org.rhq.enterprise.server.event.EventManagerRemote;
+import org.rhq.enterprise.server.install.remote.RemoteInstallManagerRemote;
+import org.rhq.enterprise.server.measurement.AvailabilityManagerRemote;
+import org.rhq.enterprise.server.measurement.CallTimeDataManagerRemote;
+import org.rhq.enterprise.server.measurement.MeasurementBaselineManagerRemote;
+import org.rhq.enterprise.server.measurement.MeasurementDataManagerRemote;
+import org.rhq.enterprise.server.measurement.MeasurementDefinitionManagerRemote;
+import org.rhq.enterprise.server.measurement.MeasurementScheduleManagerRemote;
+import org.rhq.enterprise.server.operation.OperationManagerRemote;
+import org.rhq.enterprise.server.report.DataAccessManagerRemote;
+import org.rhq.enterprise.server.resource.ResourceFactoryManagerRemote;
+import org.rhq.enterprise.server.resource.ResourceManagerRemote;
+import org.rhq.enterprise.server.resource.ResourceTypeManagerRemote;
+import org.rhq.enterprise.server.resource.group.ResourceGroupManagerRemote;
+import org.rhq.enterprise.server.search.SavedSearchManagerRemote;
+import org.rhq.enterprise.server.support.SupportManagerRemote;
+import org.rhq.enterprise.server.system.SystemManagerRemote;
+import org.rhq.enterprise.server.tagging.TagManagerRemote;
+
+public class FakeRhqFacade implements RhqFacade {
+
+ public Subject getSubject() {
+ return null;
+ }
+
+ public Subject login(String user, String password) throws Exception {
+ return null;
+ }
+
+ public void logout() {
+
+ }
+
+ public boolean isLoggedIn() {
+ return false;
+ }
+
+ public AlertManagerRemote getAlertManager() {
+ return null;
+ }
+
+ public AlertDefinitionManagerRemote getAlertDefinitionManager() {
+ return null;
+ }
+
+ public AvailabilityManagerRemote getAvailabilityManager() {
+ return null;
+ }
+
+ public BundleManagerRemote getBundleManager() {
+ return null;
+ }
+
+ public CallTimeDataManagerRemote getCallTimeDataManager() {
+ return null;
+ }
+
+ public RepoManagerRemote getRepoManager() {
+ return null;
+ }
+
+ public ConfigurationManagerRemote getConfigurationManager() {
+ return null;
+ }
+
+ public ContentManagerRemote getContentManager() {
+ return null;
+ }
+
+ public DataAccessManagerRemote getDataAccessManager() {
+ return null;
+ }
+
+ public DiscoveryBossRemote getDiscoveryBoss() {
+ return null;
+ }
+
+ public EventManagerRemote getEventManager() {
+ return null;
+ }
+
+ public MeasurementBaselineManagerRemote getMeasurementBaselineManager() {
+ return null;
+ }
+
+ public MeasurementDataManagerRemote getMeasurementDataManager() {
+ return null;
+ }
+
+ public MeasurementDefinitionManagerRemote getMeasurementDefinitionManager() {
+ return null;
+ }
+
+ public MeasurementScheduleManagerRemote getMeasurementScheduleManager() {
+ return null;
+ }
+
+ public OperationManagerRemote getOperationManager() {
+ return null;
+ }
+
+ public ResourceManagerRemote getResourceManager() {
+ return null;
+ }
+
+ public ResourceFactoryManagerRemote getResourceFactoryManager() {
+ return null;
+ }
+
+ public ResourceGroupManagerRemote getResourceGroupManager() {
+ return null;
+ }
+
+ public ResourceTypeManagerRemote getResourceTypeManager() {
+ return null;
+ }
+
+ public RoleManagerRemote getRoleManager() {
+ return null;
+ }
+
+ public SavedSearchManagerRemote getSavedSearchManager() {
+ return null;
+ }
+
+ public SubjectManagerRemote getSubjectManager() {
+ return null;
+ }
+
+ public SupportManagerRemote getSupportManager() {
+ return null;
+ }
+
+ public SystemManagerRemote getSystemManager() {
+ return null;
+ }
+
+ public RemoteInstallManagerRemote getRemoteInstallManager() {
+ return null;
+ }
+
+ public TagManagerRemote getTagManager() {
+ return null;
+ }
+
+ public Map<String, Object> getManagers() {
+ return Collections.emptyMap();
+ }
+
+}
diff --git a/modules/enterprise/binding/src/test/java/org/rhq/bindings/ScriptEngineTest.java b/modules/enterprise/binding/src/test/java/org/rhq/bindings/ScriptEngineTest.java
new file mode 100644
index 0000000..8dd0844
--- /dev/null
+++ b/modules/enterprise/binding/src/test/java/org/rhq/bindings/ScriptEngineTest.java
@@ -0,0 +1,101 @@
+/*
+ * 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 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.bindings;
+
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertTrue;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.lang.reflect.Array;
+import java.util.Collections;
+
+import javax.script.ScriptEngine;
+import javax.script.ScriptException;
+
+import org.testng.annotations.Test;
+
+import org.rhq.bindings.util.PackageFinder;
+
+/**
+ *
+ *
+ * @author Lukas Krejci
+ */
+public class ScriptEngineTest {
+
+ private static StandardBindings EMPTY_BINDINGS = new StandardBindings(new PrintWriter(System.out), new FakeRhqFacade());
+
+ @Test
+ public void testFactory() throws ScriptException, IOException {
+ ScriptEngine engine = getScriptEngine();
+ assertNotNull(engine);
+ }
+
+ @Test
+ public void testSandbox() throws ScriptException, IOException {
+ ScriptEngine engine = getScriptEngine();
+
+ SandboxedScriptEngine sandbox = new SandboxedScriptEngine(engine, new StandardScriptPermissions());
+
+ try {
+ sandbox.eval("java.lang.System.exit(1);");
+ } catch (Exception e) {
+ assertSecurityExceptionPresent(e);
+ }
+
+ try {
+ //try hard to get to the System.exit()
+ sandbox.eval(
+ "cls = java.lang.Class.forName('java.lang.System');" +
+ "params = java.lang.reflect.Array.newInstance(java.lang.Object, 1);" +
+ "params[0] = java.lang.Integer.valueOf('1');" +
+ "st = new java.beans.Statement(cls, 'exit', params);" +
+ "st.execute()");
+
+ } catch (Exception e) {
+ assertSecurityExceptionPresent(e);
+ }
+ }
+
+ private ScriptEngine getScriptEngine() throws ScriptException, IOException {
+ return ScriptEngineFactory.getScriptEngine("JavaScript", new PackageFinder(Collections.<File>emptyList()), EMPTY_BINDINGS);
+ }
+
+ private void assertSecurityExceptionPresent(Throwable t) {
+ boolean ok = false;
+ while (t != null) {
+ if (t instanceof SecurityException) {
+ ok = true;
+ break;
+ } else if ((t instanceof ScriptException) &&
+ (t.getMessage().contains("java.security.AccessControlException")
+ || t.getMessage().contains("java.lang.SecurityException"))) {
+ ok = true;
+ break;
+ }
+
+ t = t.getCause();
+ }
+
+ assertTrue(ok, "Didn't find a SecurityException, which should have occured.");
+ }
+}
diff --git a/modules/enterprise/binding/src/test/resources/allow-all.policy b/modules/enterprise/binding/src/test/resources/allow-all.policy
new file mode 100644
index 0000000..cb9dbed
--- /dev/null
+++ b/modules/enterprise/binding/src/test/resources/allow-all.policy
@@ -0,0 +1,3 @@
+grant {
+ permission java.security.AllPermission;
+};
commit db53fa0595013302e789f5be5308bdb0eed30eee
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Thu Feb 10 12:09:31 2011 +0100
UI work on repo details page.
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/AdministrationView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/AdministrationView.java
index 57bcb1c..2136724 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/AdministrationView.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/AdministrationView.java
@@ -25,7 +25,9 @@ import com.smartgwt.client.widgets.Canvas;
import com.smartgwt.client.widgets.Label;
import com.smartgwt.client.widgets.layout.VLayout;
+import org.rhq.core.domain.authz.Permission;
import org.rhq.enterprise.gui.coregui.client.ImageManager;
+import org.rhq.enterprise.gui.coregui.client.UserSessionManager;
import org.rhq.enterprise.gui.coregui.client.admin.agent.install.RemoteAgentInstallView;
import org.rhq.enterprise.gui.coregui.client.admin.roles.RolesView;
import org.rhq.enterprise.gui.coregui.client.admin.templates.ResourceTypeTreeView;
@@ -37,6 +39,7 @@ import org.rhq.enterprise.gui.coregui.client.components.view.NavigationItem;
import org.rhq.enterprise.gui.coregui.client.components.view.NavigationSection;
import org.rhq.enterprise.gui.coregui.client.components.view.ViewFactory;
import org.rhq.enterprise.gui.coregui.client.components.view.ViewName;
+import org.rhq.enterprise.gui.coregui.client.gwt.GWTServiceLookup;
import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableVLayout;
/**
@@ -215,15 +218,15 @@ public class AdministrationView extends AbstractSectionedLeftNavigationView {
"subsystems/content/Content_16.png", new ViewFactory() {
public Canvas createView() {
return new FullHTMLPane(extendLocatorId(PAGE_CONTENT_SOURCES_VIEW_ID.getName()),
- "/rhq/content/listContentProviders.xhtml");
+ "/rhq/content/listContentProviders.xhtml?nomenu=true");
}
- });
+ }, getGlobalPermissions().contains(Permission.MANAGE_REPOSITORIES));
NavigationItem reposItem = new NavigationItem(PAGE_REPOS_VIEW_ID, "subsystems/content/Content_16.png",
new ViewFactory() {
public Canvas createView() {
return new FullHTMLPane(extendLocatorId(PAGE_REPOS_VIEW_ID.getName()),
- "/rhq/content/listRepos.xhtml");
+ "/rhq/content/listRepos.xhtml?nomenu=true");
}
});
diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/content/RepoDetailsUIBean.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/content/RepoDetailsUIBean.java
index d77b5fc..d1dd640 100644
--- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/content/RepoDetailsUIBean.java
+++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/content/RepoDetailsUIBean.java
@@ -22,8 +22,10 @@ import javax.faces.application.FacesMessage;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.richfaces.event.UploadEvent;
import org.rhq.core.domain.auth.Subject;
+import org.rhq.core.domain.authz.Permission;
import org.rhq.core.domain.content.ContentSyncStatus;
import org.rhq.core.domain.content.Repo;
import org.rhq.core.domain.content.RepoSyncResults;
@@ -87,6 +89,25 @@ public class RepoDetailsUIBean {
return retval;
}
+ public boolean isRepositoryManager() {
+ Subject subject = EnterpriseFacesContextUtility.getSubject();
+ return LookupUtil.getAuthorizationManager().hasGlobalPermission(subject, Permission.MANAGE_REPOSITORIES);
+ }
+
+ public boolean isEditable() {
+ Subject subject = EnterpriseFacesContextUtility.getSubject();
+ return LookupUtil.getAuthorizationManager().canUpdateRepo(subject, getRepo().getId());
+ }
+
+ public boolean isInventoryManager() {
+ Subject subject = EnterpriseFacesContextUtility.getSubject();
+ return LookupUtil.getAuthorizationManager().isInventoryManager(subject);
+ }
+
+ public boolean getHasContentSources() {
+ return getRepo().getContentSources().size() > 0;
+ }
+
public String sync() {
Subject subject = EnterpriseFacesContextUtility.getSubject();
int[] repoIds = { FacesContextUtility.getRequiredRequestParameter("id", Integer.class) };
@@ -140,6 +161,12 @@ public class RepoDetailsUIBean {
return "success";
}
+ public void packageUploadListener(UploadEvent event) {
+ if (!isEditable()) {
+ return;
+ }
+ }
+
private void loadRepo() {
if (this.repo == null) {
Subject subject = EnterpriseFacesContextUtility.getSubject();
diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/content/createRepo.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/content/createRepo.xhtml
index d12fba1..393b688 100644
--- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/content/createRepo.xhtml
+++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/content/createRepo.xhtml
@@ -57,6 +57,10 @@
<h:inputTextarea id="description" rows="3" cols="20" value="#{CreateRepoUIBean.repo.description}"/>
</td>
</tr>
+ <tr>
+ <td align="right">Private:</td>
+ <td align="left"><h:selectBooleanCheckbox id="isPrivate" value="#{CreateRepoUIBean.repo.private}"/></td>
+ </tr>
</table>
</rich:panel>
diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/content/repo.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/content/repo.xhtml
index a636bae..5e63d51 100644
--- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/content/repo.xhtml
+++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/content/repo.xhtml
@@ -64,13 +64,13 @@
value="#{RepoDetailsUIBean.repo.description}" /> <h:outputText
rendered="${mode ne 'edit'}"
value="#{RepoDetailsUIBean.repo.description}" /></td>
- </tr>
+ </tr>
<tr>
<td align="right"><b>Sync Schedule:</b></td>
<td align="left"><h:inputText
- rendered="${mode eq 'edit'}"
+ rendered="${RepoDetailsUIBean.repositoryManager and mode eq 'edit'}"
value="#{RepoDetailsUIBean.repo.syncSchedule}" /> <h:outputText
- rendered="${mode ne 'edit'}"
+ rendered="${mode ne 'edit' or not RepoDetailsUIBean.repositoryManager}"
value="#{RepoDetailsUIBean.repo.syncSchedule}" /></td>
</tr>
<tr>
@@ -190,13 +190,13 @@
<h:panelGrid columns="3" styleClass="buttons-table"
columnClasses="button-cell">
- <h:commandButton rendered="${mode ne 'edit'}" value="EDIT"
+ <h:commandButton rendered="${mode ne 'edit' and RepoDetailsUIBean.editable}" value="EDIT"
action="#{RepoDetailsUIBean.edit}" alt="Edit"
styleClass="buttonmed" id="editButton" />
- <h:commandButton rendered="${mode ne 'edit' and not RepoDetailsUIBean.currentlySyncing}"
+ <h:commandButton rendered="${mode ne 'edit' and not RepoDetailsUIBean.currentlySyncing and RepoDetailsUIBean.repositoryManager}"
value="SYNCHRONIZE" action="#{RepoDetailsUIBean.sync}"
alt="Synchronize" styleClass="buttonmed" id="syncButton" />
- <h:commandButton rendered="#{RepoDetailsUIBean.currentlySyncing}"
+ <h:commandButton rendered="#{RepoDetailsUIBean.repositoryManager and RepoDetailsUIBean.currentlySyncing}"
value="CANCEL SYNCH" action="#{RepoDetailsUIBean.cancelSync}"
alt="Cancel Synch" styleClass="buttonmed" id="cancelSyncButton" />
<h:commandButton rendered="${mode eq 'edit'}" value="SAVE"
@@ -211,7 +211,7 @@
<!-- CONTENT SOURCE LIST -->
- <h:form id="repoContentProvidersListForm">
+ <h:form id="repoContentProvidersListForm" rendered="#{RepoDetailsUIBean.repositoryManager}">
<input type="hidden" name="id" value="${param.id}" />
<input type="hidden" name="mode" value="${param.mode}" />
@@ -364,7 +364,7 @@
<!-- SUBSCRIBER RESOURCE LIST -->
- <h:form id="repoResourcesListForm">
+ <h:form id="repoResourcesListForm" rendered="#{RepoDetailsUIBean.repositoryManager}">
<input type="hidden" name="id" value="${param.id}" />
<input type="hidden" name="mode" value="${param.mode}" />
@@ -617,8 +617,9 @@
action="#{RepoPackageVersionsUIBean.installSelectedPackages}"
value="INSTALL PACKAGES" target="selectedPackages"
onclick="if (!confirm('#{confirmInstallMessage}')) return false"
- styleClass="on-pager-button buttonsmall" />
-
+ styleClass="on-pager-button buttonsmall"
+ rendered="#{RepoDetailsUIBean.inventoryManager}" />
+
<ui:param name="paginationDataTableName"
value="repoPackageVersionsDataTable" />
<ui:param name="paginationDataModel"
@@ -632,14 +633,42 @@
</f:facet>
</rich:dataTable>
-
+
</h:panelGrid>
</rich:panel>
+
+ <rich:panel rendered="#{not RepoDetailsUIBean.hasContentSources}">
+ <f:facet name="header">
+ <h:outputText value="Upload New Package"/>
+ </f:facet>
+
+ <h:messages id="uploadmessages"
+ showSummary="true"
+ showDetail="true"
+ infoClass="InfoBlock"
+ warnClass="WarnBlock"
+ errorClass="ErrorBlock"
+ fatalClass="FatalBlock"
+ globalOnly="true"
+ layout="table"
+ width="100%"/>
+
+ <rich:fileUpload
+ id="upload"
+ fileUploadListener="#{RepoDetailsUIBean.packageUploadListener}"
+ acceptedTypes="*"
+ noDuplicate="true"
+ immediateUpload="true"
+ autoclear="false"
+ allowFlash="false">
+ <a4j:support event="onuploadcomplete" reRender="uploadmessages" />
+ </rich:fileUpload>
+ </rich:panel>
</a4j:region>
</h:form>
- <h:form id="repoDistributionListForm" rendered="#{RepoDistributionUIBean.dataModel.rowCount gt 0}">
+ <h:form id="repoDistributionListForm" rendered="#{RepoDetailsUIBean.repositoryManager and RepoDistributionUIBean.dataModel.rowCount gt 0}">
<a4j:region id="distributionList">
<input type="hidden" name="id" value="${param.id}" />
<input type="hidden" name="mode" value="${param.mode}" />
@@ -734,7 +763,7 @@
</a4j:region>
</h:form>
- <h:form id="repoAdvisoryListForm" rendered="#{RepoAdvisoryUIBean.dataModel.rowCount gt 0}">
+ <h:form id="repoAdvisoryListForm" rendered="#{RepoDetailsUIBean.repositoryManager and RepoAdvisoryUIBean.dataModel.rowCount gt 0}">
<a4j:region id="advisoryList">
<input type="hidden" name="id" value="${param.id}" />
<input type="hidden" name="mode" value="${param.mode}" />
commit cc6599d5131d519f3476be1162d372318280c177
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Thu Feb 10 12:08:56 2011 +0100
dbsetup now correctly sets up the rhqadmin user to have MANAGE_REPOSITORIES,
bumping the schema version,
JSF UI assumes the Repo be aliased as "c" in the named queries.
diff --git a/modules/core/dbutils/src/main/scripts/dbsetup/authz-data.xml b/modules/core/dbutils/src/main/scripts/dbsetup/authz-data.xml
index 8a92b54..99d0c00 100644
--- a/modules/core/dbutils/src/main/scripts/dbsetup/authz-data.xml
+++ b/modules/core/dbutils/src/main/scripts/dbsetup/authz-data.xml
@@ -47,6 +47,7 @@
<data ROLE_ID="1" OPERATION="1"/> <!-- Permission.MANAGE_INVENTORY -->
<data ROLE_ID="1" OPERATION="2"/> <!-- Permission.MANAGE_SETTINGS -->
<data ROLE_ID="1" OPERATION="12"/> <!-- Permission.MANAGE_BUNDLE -->
+ <data ROLE_ID="1" OPERATION="15"/> <!-- Permission.MANAGE_REPOSITORIES -->
<!-- resource permissions start here-->
<data ROLE_ID="1" OPERATION="3"/> <!-- Permission.VIEW_RESOURCE -->
<data ROLE_ID="1" OPERATION="4"/> <!-- Permission.MODIFY_RESOURCE -->
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/content/Repo.java b/modules/core/domain/src/main/java/org/rhq/core/domain/content/Repo.java
index a684cc7..c1014e2 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/content/Repo.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/content/Repo.java
@@ -67,8 +67,8 @@ import org.rhq.core.domain.resource.Resource;
@Entity
@NamedQueries( {
@NamedQuery(name = Repo.QUERY_FIND_ALL_IMPORTED_REPOS_ADMIN, query = "SELECT c FROM Repo c WHERE c.candidate = false"),
- @NamedQuery(name = Repo.QUERY_FIND_ALL_IMPORTED_REPOS, query = "SELECT r FROM Repo r" //
- + " WHERE r.isPrivate = false OR r.owner = :subject"),
+ @NamedQuery(name = Repo.QUERY_FIND_ALL_IMPORTED_REPOS, query = "SELECT c FROM Repo c" //
+ + " WHERE c.isPrivate = false OR c.owner = :subject"),
@NamedQuery(name = Repo.QUERY_FIND_BY_IDS, query = "SELECT c FROM Repo c WHERE c.id IN ( :ids )"),
@NamedQuery(name = Repo.QUERY_FIND_BY_NAME, query = "SELECT c FROM Repo c WHERE c.name = :name"),
@NamedQuery(name = Repo.QUERY_FIND_IMPORTED_BY_CONTENT_SOURCE_ID_FETCH_CCS, query = "SELECT c FROM Repo c LEFT JOIN FETCH c.repoContentSources ccs WHERE ccs.contentSource.id = :id AND c.candidate = false"),
commit be1c0464b5e4c9c3c0eede66ce20acb9d636b297
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Thu Feb 10 12:06:18 2011 +0100
force the owner of a repo if the creator/updater is not repo manager.
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/RepoManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/RepoManagerBean.java
index 2a82baa..04d5efe 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/RepoManagerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/RepoManagerBean.java
@@ -445,9 +445,15 @@ public class RepoManagerBean implements RepoManagerLocal, RepoManagerRemote {
public Repo updateRepo(Subject subject, Repo repo) throws RepoException {
validateFields(repo);
-
- if (!authzManager.canUpdateRepo(subject, repo.getId())) {
- throw new PermissionException("User [" + subject + "] can't update repo with id " + repo.getId());
+
+ if (!authzManager.hasGlobalPermission(subject, Permission.MANAGE_REPOSITORIES)) {
+ if (!authzManager.canUpdateRepo(subject, repo.getId())) {
+ throw new PermissionException("User [" + subject + "] can't update repo with id " + repo.getId());
+ }
+
+ //only the repo manager can update the owner of a repo.
+ //make sure that's the case.
+ repo.setOwner(subject);
}
// HHH-2864 - Leave this in until we move to hibernate > 3.2.r14201-2
@@ -471,7 +477,13 @@ public class RepoManagerBean implements RepoManagerLocal, RepoManagerRemote {
public Repo createRepo(Subject subject, Repo repo) throws RepoException {
validateRepo(repo);
-
+
+ if (!authzManager.hasGlobalPermission(subject, Permission.MANAGE_REPOSITORIES)) {
+ //only the repo manager can update the owner of a repo.
+ //make sure that's the case.
+ repo.setOwner(subject);
+ }
+
log.debug("User [" + subject + "] is creating [" + repo + "]...");
entityManager.persist(repo);
log.info("User [" + subject + "] created [" + repo + "].");
commit d5e2cb25bad1deaa1f2121464340a96deed299a8
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Mon Feb 7 19:13:52 2011 +0100
First round of changes to implement public/private repos. UI and actual tests coming.
diff --git a/modules/core/dbutils/pom.xml b/modules/core/dbutils/pom.xml
index 76b00e9..caf66c8 100644
--- a/modules/core/dbutils/pom.xml
+++ b/modules/core/dbutils/pom.xml
@@ -22,7 +22,7 @@
<properties>
<scm.module.path>modules/core/dbutils/</scm.module.path>
- <db.schema.version>2.103</db.schema.version>
+ <db.schema.version>2.104</db.schema.version>
</properties>
<dependencies>
diff --git a/modules/core/dbutils/src/main/scripts/dbsetup/content-schema.xml b/modules/core/dbutils/src/main/scripts/dbsetup/content-schema.xml
index f262087..8cd2711 100644
--- a/modules/core/dbutils/src/main/scripts/dbsetup/content-schema.xml
+++ b/modules/core/dbutils/src/main/scripts/dbsetup/content-schema.xml
@@ -80,7 +80,9 @@
<column name="LAST_MODIFIED_TIME" type="LONG" required="true"/>
<column name="IS_CANDIDATE" type="BOOLEAN" required="true"/>
<column name="SYNC_SCHEDULE" size="64" type="VARCHAR2" required="false"/>
-
+ <column name="OWNER_ID" type="INTEGER" required="false" references="RHQ_SUBJECT" />
+ <column name="IS_PRIVATE" type="BOOLEAN" required="true" />
+
<index name="RHQ_REPO_IDX" unique="true">
<field ref="NAME"/>
</index>
diff --git a/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml b/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml
index a5ef90a..88b53c2 100644
--- a/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml
+++ b/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml
@@ -3296,10 +3296,33 @@
</schema-directSQL>
</schemaSpec>
- <schemaSpec version="2.103">
- <!-- package types no longer require to be coupled with a resource type. They can exist on their own. -->
- <schema-alterColumn table="RHQ_PACKAGE_TYPE" column="RESOURCE_TYPE_ID" nullable="true"/>
- </schemaSpec>
+ <schemaSpec version="2.103">
+ <!-- package types no longer require to be coupled with a resource type. They can exist on their own. -->
+ <schema-alterColumn table="RHQ_PACKAGE_TYPE" column="RESOURCE_TYPE_ID" nullable="true"/>
+ </schemaSpec>
+
+ <schemaSpec version="2.104">
+ <schema-addColumn table="RHQ_REPO" column="OWNER_ID" columnType="INTEGER" />
+ <schema-addColumn table="RHQ_REPO" column="IS_PRIVATE" columnType="BOOLEAN" />
+ <schema-alterColumn table="RHQ_REPO" column="IS_PRIVATE" nullable="FALSE" default="TRUE"/>
+ <schema-directSQL>
+ <statement desc="Creating OWNER_ID foreign key relation on RHQ_REPO">
+ ALTER TABLE RHQ_REPO
+ ADD CONSTRAINT RHQ_REPO_OWNER_ID_FK
+ FOREIGN KEY (OWNER_ID)
+ REFERENCES RHQ_SUBJECT (ID)
+ </statement>
+ </schema-directSQL>
+
+ <!-- Now add modify the permissions to give all the roles with MANAGE_INVENTORY
+ the new MANAGE_REPOSITORIES privilege so that people's privs remain unchanged. -->
+ <schema-directSQL>
+ <statement>
+ INSERT INTO RHQ_PERMISSION (role_id, operation)
+ SELECT role_id, 15 FROM RHQ_PERMISSION WHERE operation = 1
+ </statement>
+ </schema-directSQL>
+ </schemaSpec>
</dbupgrade>
</target>
</project>
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/auth/Subject.java b/modules/core/domain/src/main/java/org/rhq/core/domain/auth/Subject.java
index 182b74b..e9b9e58 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/auth/Subject.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/auth/Subject.java
@@ -50,6 +50,7 @@ import org.jetbrains.annotations.NotNull;
import org.rhq.core.domain.authz.Role;
import org.rhq.core.domain.configuration.Configuration;
+import org.rhq.core.domain.content.Repo;
import org.rhq.core.domain.resource.group.ResourceGroup;
/**
@@ -309,6 +310,9 @@ public class Subject implements Serializable {
@OneToMany(mappedBy = "subject", fetch = FetchType.LAZY)
private List<ResourceGroup> ownedGroups = null;
+ @OneToMany(mappedBy = "owner", fetch = FetchType.LAZY)
+ private Set<Repo> ownedRepos;
+
@Transient
private Integer sessionId = null;
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/authz/Permission.java b/modules/core/domain/src/main/java/org/rhq/core/domain/authz/Permission.java
index 4ccaa80..3b15d0f 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/authz/Permission.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/authz/Permission.java
@@ -120,8 +120,14 @@ public enum Permission {
* can C/U/D events
* (in the future, will also C/U/D event definitions)
*/
- MANAGE_EVENTS(Target.RESOURCE) // 14
+ MANAGE_EVENTS(Target.RESOURCE), // 14
+ /**
+ * Can C/U/D repositories and content sources
+ */
+ // NOTE: This is a GLOBAL permission but defined here to maintain the ordinal indexes
+ MANAGE_REPOSITORIES(Target.GLOBAL) // 15
+
;
/**
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/content/Repo.java b/modules/core/domain/src/main/java/org/rhq/core/domain/content/Repo.java
index 3cd52f8..a684cc7 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/content/Repo.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/content/Repo.java
@@ -37,6 +37,8 @@ import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;
@@ -50,6 +52,7 @@ import javax.xml.bind.annotation.XmlTransient;
import org.jetbrains.annotations.NotNull;
+import org.rhq.core.domain.auth.Subject;
import org.rhq.core.domain.resource.Resource;
/**
@@ -59,10 +62,13 @@ import org.rhq.core.domain.resource.Resource;
*
* @author Jason Dobies
* @author John Mazzitelli
+ * @author Lukas Krejci
*/
@Entity
@NamedQueries( {
- @NamedQuery(name = Repo.QUERY_FIND_ALL_IMPORTED_REPOS, query = "SELECT c FROM Repo c WHERE c.candidate = false"),
+ @NamedQuery(name = Repo.QUERY_FIND_ALL_IMPORTED_REPOS_ADMIN, query = "SELECT c FROM Repo c WHERE c.candidate = false"),
+ @NamedQuery(name = Repo.QUERY_FIND_ALL_IMPORTED_REPOS, query = "SELECT r FROM Repo r" //
+ + " WHERE r.isPrivate = false OR r.owner = :subject"),
@NamedQuery(name = Repo.QUERY_FIND_BY_IDS, query = "SELECT c FROM Repo c WHERE c.id IN ( :ids )"),
@NamedQuery(name = Repo.QUERY_FIND_BY_NAME, query = "SELECT c FROM Repo c WHERE c.name = :name"),
@NamedQuery(name = Repo.QUERY_FIND_IMPORTED_BY_CONTENT_SOURCE_ID_FETCH_CCS, query = "SELECT c FROM Repo c LEFT JOIN FETCH c.repoContentSources ccs WHERE ccs.contentSource.id = :id AND c.candidate = false"),
@@ -82,31 +88,54 @@ import org.rhq.core.domain.resource.Resource;
@NamedQuery(name = Repo.QUERY_FIND_REPO_COMPOSITES_BY_RESOURCE_ID_COUNT, query = "SELECT COUNT( rc.repo ) "
+ "FROM ResourceRepo rc WHERE rc.resource.id = :resourceId "),
+ @NamedQuery(name = Repo.QUERY_FIND_AVAILABLE_REPO_COMPOSITES_BY_RESOURCE_ID_ADMIN, query = "SELECT new org.rhq.core.domain.content.composite.RepoComposite( "
+ + "c, "
+ + "(SELECT COUNT(cpv.packageVersion) FROM RepoPackageVersion cpv WHERE cpv.repo.id = c.id) "
+ + ") "
+ + "FROM Repo AS c "
+ + "WHERE c.id NOT IN ( SELECT rc.repo.id FROM ResourceRepo rc WHERE rc.resource.id = :resourceId ) "
+ + "AND c.candidate = false "
+ + "GROUP BY c, c.name, c.description, c.creationDate, c.lastModifiedDate"),
+ @NamedQuery(name = Repo.QUERY_FIND_AVAILABLE_REPO_COMPOSITES_BY_RESOURCE_ID_ADMIN_COUNT, query = "SELECT COUNT( c ) "
+ + "FROM Repo AS c "
+ + "WHERE c.id NOT IN ( SELECT rc.repo.id FROM ResourceRepo rc WHERE rc.resource.id = :resourceId ) "
+ + "AND c.candidate = false "),
@NamedQuery(name = Repo.QUERY_FIND_AVAILABLE_REPO_COMPOSITES_BY_RESOURCE_ID, query = "SELECT new org.rhq.core.domain.content.composite.RepoComposite( "
+ "c, "
+ "(SELECT COUNT(cpv.packageVersion) FROM RepoPackageVersion cpv WHERE cpv.repo.id = c.id) "
+ ") "
+ "FROM Repo AS c "
+ "WHERE c.id NOT IN ( SELECT rc.repo.id FROM ResourceRepo rc WHERE rc.resource.id = :resourceId ) "
- + "AND c.candidate = false " + "GROUP BY c, c.name, c.description, c.creationDate, c.lastModifiedDate"),
+ + "AND c.candidate = false "
+ + "AND c.owner = :subject "
+ + "GROUP BY c, c.name, c.description, c.creationDate, c.lastModifiedDate"),
@NamedQuery(name = Repo.QUERY_FIND_AVAILABLE_REPO_COMPOSITES_BY_RESOURCE_ID_COUNT, query = "SELECT COUNT( c ) "
+ "FROM Repo AS c "
+ "WHERE c.id NOT IN ( SELECT rc.repo.id FROM ResourceRepo rc WHERE rc.resource.id = :resourceId ) "
- + "AND c.candidate = false "),
+ + "AND c.candidate = false AND c.owner = :subject"),
@NamedQuery(name = Repo.QUERY_FIND_CANDIDATES_WITH_ONLY_CONTENT_SOURCE, query = "SELECT r FROM Repo r " //
+ "WHERE r.candidate = true " //
+ "AND 1 = (SELECT COUNT(rcs.repo) FROM RepoContentSource rcs " //
+ " WHERE rcs.repo.id = r.id " //
+ " AND rcs.contentSource.id = :contentSourceId) " //
+ "AND 1 = (SELECT COUNT(rcs.repo) FROM RepoContentSource rcs" //
- + " WHERE rcs.repo.id = r.id) ") })
+ + " WHERE rcs.repo.id = r.id) "),
+ @NamedQuery(name = Repo.QUERY_CHECK_REPO_VISIBLE_BY_SUBJECT_ID, query = "SELECT COUNT(r) FROM Repo r" //
+ + " WHERE r.id = :repoId"
+ + " AND r.isPrivate = false OR r.owner.id = :subjectId"),
+
+ @NamedQuery(name = Repo.QUERY_CHECK_REPO_OWNED_BY_SUBJECT_ID, query = "SELECT COUNT(r) FROM Repo r" //
+ + " WHERE r.id = :repoId"
+ + " AND r.owner.id = :subjectId")
+ })
@SequenceGenerator(name = "SEQ", sequenceName = "RHQ_REPO_ID_SEQ")
@Table(name = "RHQ_REPO")
public class Repo implements Serializable {
// Constants --------------------------------------------
- public static final String QUERY_FIND_ALL_IMPORTED_REPOS = "Repo.findAll";
+ public static final String QUERY_FIND_ALL_IMPORTED_REPOS_ADMIN = "Repo.findAllImportedReposAdmin";
+ public static final String QUERY_FIND_ALL_IMPORTED_REPOS = "Repo.findAllImportedRepos";
public static final String QUERY_FIND_BY_IDS = "Repo.findByIds";
public static final String QUERY_FIND_BY_NAME = "Repo.findByName";
public static final String QUERY_FIND_IMPORTED_BY_CONTENT_SOURCE_ID_FETCH_CCS = "Repo.findByContentSourceIdFetchCCS";
@@ -116,10 +145,14 @@ public class Repo implements Serializable {
public static final String QUERY_FIND_REPOS_BY_RESOURCE_ID = "Repo.findReposByResourceId";
public static final String QUERY_FIND_REPO_COMPOSITES_BY_RESOURCE_ID = "Repo.findRepoCompositesByResourceId";
public static final String QUERY_FIND_REPO_COMPOSITES_BY_RESOURCE_ID_COUNT = "Repo.findRepoCompositesByResourceId_count";
+ public static final String QUERY_FIND_AVAILABLE_REPO_COMPOSITES_BY_RESOURCE_ID_ADMIN = "Repo.findAvailableRepoCompositesByResourceIdAdmin";
+ public static final String QUERY_FIND_AVAILABLE_REPO_COMPOSITES_BY_RESOURCE_ID_ADMIN_COUNT = "Repo.findAvailableRepoCompositesByResourceIdAdmin_count";
public static final String QUERY_FIND_AVAILABLE_REPO_COMPOSITES_BY_RESOURCE_ID = "Repo.findAvailableRepoCompositesByResourceId";
public static final String QUERY_FIND_AVAILABLE_REPO_COMPOSITES_BY_RESOURCE_ID_COUNT = "Repo.findAvailableRepoCompositesByResourceId_count";
public static final String QUERY_FIND_CANDIDATES_WITH_ONLY_CONTENT_SOURCE = "Repo.findCandidatesWithOnlyContentSource";
-
+ public static final String QUERY_CHECK_REPO_VISIBLE_BY_SUBJECT_ID = "Repo.findVisibleReposBySubjectId";
+ public static final String QUERY_CHECK_REPO_OWNED_BY_SUBJECT_ID = "Repo.isRepoOwnedBySubjectId";
+
private static final long serialVersionUID = 1L;
// Attributes --------------------------------------------
@@ -179,10 +212,17 @@ public class Repo implements Serializable {
@XmlTransient
@OneToMany(mappedBy = "repo", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
private Set<RepoAdvisory> repoAdvisories;
-
+
@Transient
private String syncStatus;
+ @ManyToOne
+ @JoinColumn(name = "OWNER_ID", referencedColumnName = "ID", nullable = true)
+ private Subject owner;
+
+ @Column(name = "IS_PRIVATE", nullable = false)
+ private boolean isPrivate = true;
+
// Constructor ----------------------------------------
public Repo() {
@@ -793,4 +833,37 @@ public class Repo implements Serializable {
return syncResults;
}
+ /**
+ * @return the owner
+ */
+ public Subject getOwner() {
+ return owner;
+ }
+
+ /**
+ * @param owner the owner to set
+ */
+ public void setOwner(Subject owner) {
+ this.owner = owner;
+ }
+
+ /**
+ * Private repositories are only accessible by their owners or
+ * {@link org.rhq.core.domain.authz.Permission#MANAGE_REPOSITORIES RepositoryManagers}.
+ * Private repositories without an owner are only accessible by the RepositoryManagers.
+ * <p>
+ * A public repository (whether owned by a specific user or not) is accessible by anyone.
+ *
+ * @return whether this repository is private
+ */
+ public boolean isPrivate() {
+ return isPrivate;
+ }
+
+ /**
+ * @see #isPrivate()
+ */
+ public void setPrivate(boolean priv) {
+ this.isPrivate = priv;
+ }
}
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/RepoCriteria.java b/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/RepoCriteria.java
index 60d23da..f6912b0 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/RepoCriteria.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/RepoCriteria.java
@@ -45,7 +45,9 @@ public class RepoCriteria extends Criteria {
private List<Integer> filterResourceIds; // needs overrides
private Boolean filterCandidate;
private List<Integer> filterContentSourceIds; // needs overrides
-
+ private Integer filterOwnerId;
+ private Boolean filterIsPrivate;
+
private boolean fetchResourceRepos;
private boolean fetchRepoContentSources;
private boolean fetchRepoPackageVersions;
@@ -61,6 +63,7 @@ public class RepoCriteria extends Criteria {
+ " FROM Repo innerRepo " //
+ " JOIN innerRepo.repoContentSources rcs " //
+ " WHERE rcs.contentSource.id IN ( ? ))");
+ filterOverrides.put("ownerId", "owner.id = ?");
}
@Override
@@ -92,6 +95,14 @@ public class RepoCriteria extends Criteria {
this.filterContentSourceIds = Arrays.asList(filterContentSourceIds);
}
+ public void addFilterOwnerId(Integer ownerId) {
+ this.filterOwnerId = ownerId;
+ }
+
+ public void addFilterIsPrivate(Boolean isPrivate) {
+ this.filterIsPrivate = isPrivate;
+ }
+
public void fetchResourceRepos(boolean fetchResourceRepos) {
this.fetchResourceRepos = fetchResourceRepos;
}
diff --git a/modules/core/domain/src/test/java/org/rhq/core/domain/test/QueriesTest.java b/modules/core/domain/src/test/java/org/rhq/core/domain/test/QueriesTest.java
index 634d684..91c66d1 100644
--- a/modules/core/domain/src/test/java/org/rhq/core/domain/test/QueriesTest.java
+++ b/modules/core/domain/src/test/java/org/rhq/core/domain/test/QueriesTest.java
@@ -79,7 +79,7 @@ public class QueriesTest extends AbstractEJB3Test {
add(PackageVersion.QUERY_FIND_BY_REPO_ID_WITH_PACKAGE, new Object[] { "repoId", 1 });
add(MeasurementOOB.COUNT_FOR_DATE, new Object[] { "timestamp", 1L });
- add(Repo.QUERY_FIND_AVAILABLE_REPO_COMPOSITES_BY_RESOURCE_ID, new Object[] { "resourceId", 1 });
+ add(Repo.QUERY_FIND_AVAILABLE_REPO_COMPOSITES_BY_RESOURCE_ID_ADMIN, new Object[] { "resourceId", 1 });
add(PackageBits.QUERY_PACKAGE_BITS_LOADED_STATUS_PACKAGE_VERSION_ID, new Object[] { "id", 1 });
add(CreateResourceHistory.QUERY_FIND_BY_PARENT_RESOURCE_ID, new Object[] { "id", 1, "startTime", null,
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/authz/AuthorizationManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/authz/AuthorizationManagerBean.java
index d7eb82f..d3530de 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/authz/AuthorizationManagerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/authz/AuthorizationManagerBean.java
@@ -32,6 +32,7 @@ import javax.persistence.Query;
import org.rhq.core.domain.auth.Subject;
import org.rhq.core.domain.authz.Permission;
import org.rhq.core.domain.authz.Permission.Target;
+import org.rhq.core.domain.content.Repo;
import org.rhq.core.domain.resource.group.ResourceGroup;
import org.rhq.enterprise.server.RHQConstants;
@@ -302,4 +303,28 @@ public class AuthorizationManagerBean implements AuthorizationManagerLocal {
return (subject.getId() == SUBJECT_ID_OVERLORD);
}
+ public boolean canUpdateRepo(Subject subject, int repoId) {
+ if (hasGlobalPermission(subject, Permission.MANAGE_REPOSITORIES)) {
+ return true;
+ }
+ Query q = entityManager.createNamedQuery(Repo.QUERY_CHECK_REPO_OWNED_BY_SUBJECT_ID);
+ q.setParameter("repoId", repoId);
+ q.setParameter("subjectId", subject.getId());
+
+ Long num = (Long) q.getSingleResult();
+ return num > 0;
+ }
+
+ public boolean canViewRepo(Subject subject, int repoId) {
+ if (hasGlobalPermission(subject, Permission.MANAGE_REPOSITORIES)) {
+ return true;
+ }
+
+ Query q = entityManager.createNamedQuery(Repo.QUERY_CHECK_REPO_VISIBLE_BY_SUBJECT_ID);
+ q.setParameter("repoId", repoId);
+ q.setParameter("subjectId", subject.getId());
+
+ Long num = (Long) q.getSingleResult();
+ return num > 0;
+ }
}
\ No newline at end of file
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/authz/AuthorizationManagerLocal.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/authz/AuthorizationManagerLocal.java
index efd7541..80c47ef 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/authz/AuthorizationManagerLocal.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/authz/AuthorizationManagerLocal.java
@@ -220,4 +220,26 @@ public interface AuthorizationManagerLocal {
* @return <code>true</code> if the given subject is considered the overlord subject
*/
boolean isOverlord(Subject subject);
+
+ /**
+ * Returns true if given subject is able to view given repo.
+ * The subject is able to view a repo if it is public or if the subject is the owner of the repo
+ * or if the subject is a member of a role with {@link Permission#MANAGE_REPOSITORIES}.
+ *
+ * @param subject
+ * @param repoId
+ * @return true if subject is able to view the repo, false otherwise
+ */
+ boolean canViewRepo(Subject subject, int repoId);
+
+ /**
+ * Returns true if given subject is able to update given repo.
+ * The subject is able to update a repo if it is owned by the subject
+ * or if the subject is a member of a role with {@link Permission#MANAGE_REPOSITORIES}.
+ *
+ * @param subject
+ * @param repoId
+ * @return true if subject is able to update the repo, false otherwise
+ */
+ boolean canUpdateRepo(Subject subject, int repoId);
}
\ No newline at end of file
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentSourceManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentSourceManagerBean.java
index 5ab74f1..7aa3419 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentSourceManagerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentSourceManagerBean.java
@@ -161,7 +161,7 @@ public class ContentSourceManagerBean implements ContentSourceManagerLocal {
private RepoManagerLocal repoManager;
@SuppressWarnings("unchecked")
- @RequiredPermission(Permission.MANAGE_INVENTORY)
+ @RequiredPermission(Permission.MANAGE_REPOSITORIES)
public void purgeOrphanedPackageVersions(Subject subject) {
// get all orphaned package versions that have extra props, we need to delete the configs
// separately. We do this using em.remove so we can get hibernate to perform the cascading for us.
@@ -217,7 +217,7 @@ public class ContentSourceManagerBean implements ContentSourceManagerLocal {
log.info("User [" + subject + "] purged [" + count + "] orphaned package versions");
}
- @RequiredPermission(Permission.MANAGE_INVENTORY)
+ @RequiredPermission(Permission.MANAGE_REPOSITORIES)
public void deleteContentSource(Subject subject, int contentSourceId) {
log.debug("User [" + subject + "] is deleting content source [" + contentSourceId + "]");
@@ -279,7 +279,7 @@ public class ContentSourceManagerBean implements ContentSourceManagerLocal {
}
@SuppressWarnings("unchecked")
- @RequiredPermission(Permission.MANAGE_INVENTORY)
+ @RequiredPermission(Permission.MANAGE_REPOSITORIES)
public PageList<ContentSource> getAllContentSources(Subject subject, PageControl pc) {
pc.initDefaultOrderingField("cs.name");
@@ -294,7 +294,7 @@ public class ContentSourceManagerBean implements ContentSourceManagerLocal {
}
@SuppressWarnings("unchecked")
- @RequiredPermission(Permission.MANAGE_INVENTORY)
+ @RequiredPermission(Permission.MANAGE_REPOSITORIES)
public PageList<ContentSource> getAvailableContentSourcesForRepo(Subject subject, Integer repoId, PageControl pc) {
pc.initDefaultOrderingField("cs.name");
@@ -324,7 +324,7 @@ public class ContentSourceManagerBean implements ContentSourceManagerLocal {
return type;
}
- @RequiredPermission(Permission.MANAGE_INVENTORY)
+ @RequiredPermission(Permission.MANAGE_REPOSITORIES)
public ContentSource getContentSource(Subject subject, int contentSourceId) {
Query q = entityManager.createNamedQuery(ContentSource.QUERY_FIND_BY_ID_WITH_CONFIG);
q.setParameter("id", contentSourceId);
@@ -339,7 +339,7 @@ public class ContentSourceManagerBean implements ContentSourceManagerLocal {
return contentSource;
}
- @RequiredPermission(Permission.MANAGE_INVENTORY)
+ @RequiredPermission(Permission.MANAGE_REPOSITORIES)
public ContentSource getContentSourceByNameAndType(Subject subject, String name, String typeName) {
Query q = entityManager.createNamedQuery(ContentSource.QUERY_FIND_BY_NAME_AND_TYPENAME);
q.setParameter("name", name);
@@ -356,7 +356,7 @@ public class ContentSourceManagerBean implements ContentSourceManagerLocal {
}
@SuppressWarnings("unchecked")
- @RequiredPermission(Permission.MANAGE_INVENTORY)
+ @RequiredPermission(Permission.MANAGE_REPOSITORIES)
public PageList<Repo> getAssociatedRepos(Subject subject, int contentSourceId, PageControl pc) {
pc.initDefaultOrderingField("c.id");
@@ -374,6 +374,7 @@ public class ContentSourceManagerBean implements ContentSourceManagerLocal {
return new PageList<Repo>(results, (int) count, pc);
}
+ @RequiredPermission(Permission.MANAGE_REPOSITORIES)
public PageList<Repo> getCandidateRepos(Subject subject, int contentSourceId, PageControl pc) {
pc.initDefaultOrderingField("c.name");
@@ -393,7 +394,7 @@ public class ContentSourceManagerBean implements ContentSourceManagerLocal {
}
@SuppressWarnings("unchecked")
- @RequiredPermission(Permission.MANAGE_INVENTORY)
+ @RequiredPermission(Permission.MANAGE_REPOSITORIES)
public PageList<ContentSourceSyncResults> getContentSourceSyncResults(Subject subject, int contentSourceId,
PageControl pc) {
pc.initDefaultOrderingField("cssr.startTime", PageOrdering.DESC);
@@ -412,7 +413,7 @@ public class ContentSourceManagerBean implements ContentSourceManagerLocal {
return new PageList<ContentSourceSyncResults>(results, (int) count, pc);
}
- @RequiredPermission(Permission.MANAGE_INVENTORY)
+ @RequiredPermission(Permission.MANAGE_REPOSITORIES)
public void mergeRepoImportResults(List<RepoDetails> repos) {
Subject overlord = subjectManager.getOverlord();
@@ -440,7 +441,7 @@ public class ContentSourceManagerBean implements ContentSourceManagerLocal {
}
- @RequiredPermission(Permission.MANAGE_INVENTORY)
+ @RequiredPermission(Permission.MANAGE_REPOSITORIES)
public void deleteContentSourceSyncResults(Subject subject, int[] ids) {
if (ids != null) {
for (int id : ids) {
@@ -452,7 +453,7 @@ public class ContentSourceManagerBean implements ContentSourceManagerLocal {
return;
}
- @RequiredPermission(Permission.MANAGE_INVENTORY)
+ @RequiredPermission(Permission.MANAGE_REPOSITORIES)
public ContentSource createContentSource(Subject subject, ContentSource contentSource)
throws ContentSourceException {
@@ -485,7 +486,7 @@ public class ContentSourceManagerBean implements ContentSourceManagerLocal {
return contentSource; // now has the ID set
}
- @RequiredPermission(Permission.MANAGE_INVENTORY)
+ @RequiredPermission(Permission.MANAGE_REPOSITORIES)
public ContentSource simpleCreateContentSource(Subject subject, ContentSource contentSource)
throws ContentSourceException {
validateContentSource(contentSource);
@@ -494,7 +495,7 @@ public class ContentSourceManagerBean implements ContentSourceManagerLocal {
return contentSource;
}
- @RequiredPermission(Permission.MANAGE_INVENTORY)
+ @RequiredPermission(Permission.MANAGE_REPOSITORIES)
public ContentSource updateContentSource(Subject subject, ContentSource contentSource, boolean syncNow)
throws ContentSourceException {
@@ -579,7 +580,7 @@ public class ContentSourceManagerBean implements ContentSourceManagerLocal {
}
}
- @RequiredPermission(Permission.MANAGE_INVENTORY)
+ @RequiredPermission(Permission.MANAGE_REPOSITORIES)
public void synchronizeAndLoadContentSource(Subject subject, int contentSourceId) {
try {
ContentServerPluginContainer pc = ContentManagerHelper.getPluginContainer();
@@ -596,7 +597,7 @@ public class ContentSourceManagerBean implements ContentSourceManagerLocal {
}
@SuppressWarnings("unchecked")
- @RequiredPermission(Permission.MANAGE_INVENTORY)
+ @RequiredPermission(Permission.MANAGE_REPOSITORIES)
public PageList<PackageVersionContentSource> getPackageVersionsFromContentSource(Subject subject,
int contentSourceId, PageControl pc) {
pc.initDefaultOrderingField("pvcs.contentSource.id");
@@ -612,7 +613,7 @@ public class ContentSourceManagerBean implements ContentSourceManagerLocal {
}
@SuppressWarnings("unchecked")
- @RequiredPermission(Permission.MANAGE_INVENTORY)
+ @RequiredPermission(Permission.MANAGE_REPOSITORIES)
public List<PackageVersionContentSource> getPackageVersionsFromContentSourceForRepo(Subject subject,
int contentSourceId, int repoId) {
@@ -626,7 +627,7 @@ public class ContentSourceManagerBean implements ContentSourceManagerLocal {
return results;
}
- @RequiredPermission(Permission.MANAGE_INVENTORY)
+ @RequiredPermission(Permission.MANAGE_REPOSITORIES)
public long getPackageVersionCountFromContentSource(Subject subject, int contentSourceId) {
Query countQuery = PersistenceUtility.createCountQuery(entityManager,
PackageVersionContentSource.QUERY_FIND_BY_CONTENT_SOURCE_ID_COUNT);
@@ -652,7 +653,7 @@ public class ContentSourceManagerBean implements ContentSourceManagerLocal {
// The methods below probably should not be exposed to remote clients
@SuppressWarnings("unchecked")
- @RequiredPermission(Permission.MANAGE_INVENTORY)
+ @RequiredPermission(Permission.MANAGE_REPOSITORIES)
public PageList<PackageVersionContentSource> getPackageVersionsFromContentSources(Subject subject,
int[] contentSourceIds, PageControl pc) {
pc.initDefaultOrderingField("pvcs.contentSource.id");
@@ -677,7 +678,7 @@ public class ContentSourceManagerBean implements ContentSourceManagerLocal {
}
@SuppressWarnings("unchecked")
- @RequiredPermission(Permission.MANAGE_INVENTORY)
+ @RequiredPermission(Permission.MANAGE_REPOSITORIES)
public PageList<PackageVersionContentSource> getUnloadedPackageVersionsFromContentSourceInRepo(Subject subject,
int contentSourceId, int repoId, PageControl pc) {
pc.initDefaultOrderingField("pvcs.contentSource.id");
@@ -719,7 +720,7 @@ public class ContentSourceManagerBean implements ContentSourceManagerLocal {
return new PageList<PackageVersionContentSource>(uniquePVs, pc);
}
- @RequiredPermission(Permission.MANAGE_INVENTORY)
+ @RequiredPermission(Permission.MANAGE_REPOSITORIES)
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
@TransactionTimeout(45 * 60)
public void downloadDistributionBits(Subject subject, ContentSource contentSource) {
@@ -796,7 +797,7 @@ public class ContentSourceManagerBean implements ContentSourceManagerLocal {
}
}
- @RequiredPermission(Permission.MANAGE_INVENTORY)
+ @RequiredPermission(Permission.MANAGE_REPOSITORIES)
@TransactionAttribute(TransactionAttributeType.REQUIRED)
@TransactionTimeout(90 * 60)
public PackageBits downloadPackageBits(Subject subject, PackageVersionContentSource pvcs) {
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/RepoManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/RepoManagerBean.java
index 852c472..2a82baa 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/RepoManagerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/RepoManagerBean.java
@@ -118,9 +118,13 @@ public class RepoManagerBean implements RepoManagerLocal, RepoManagerRemote {
@EJB
private RepoManagerLocal repoManager;
- @RequiredPermission(Permission.MANAGE_INVENTORY)
public void deleteRepo(Subject subject, int repoId) {
- log.debug("User [" + subject + "] is deleting repository with id [" + repoId + "]...");
+
+ if (!authzManager.canUpdateRepo(subject, repoId)) {
+ throw new PermissionException("User [" + subject + "] cannot delete repository with id " + repoId);
+ }
+
+ log.info("User [" + subject + "] is deleting repository with id [" + repoId + "]...");
// bulk delete m-2-m mappings to the doomed repo
// get ready for bulk delete by clearing entity manager
@@ -147,28 +151,41 @@ public class RepoManagerBean implements RepoManagerLocal, RepoManagerRemote {
contentSourceManager.purgeOrphanedPackageVersions(subject);
}
- @RequiredPermission(Permission.MANAGE_INVENTORY)
+ @RequiredPermission(Permission.MANAGE_REPOSITORIES)
public void deleteRepoGroup(Subject subject, int repoGroupId) {
RepoGroup deleteMe = getRepoGroup(subject, repoGroupId);
entityManager.remove(deleteMe);
}
@SuppressWarnings("unchecked")
- @RequiredPermission(Permission.MANAGE_INVENTORY)
public PageList<Repo> findRepos(Subject subject, PageControl pc) {
pc.initDefaultOrderingField("c.name");
- Query query = PersistenceUtility.createQueryWithOrderBy(entityManager, Repo.QUERY_FIND_ALL_IMPORTED_REPOS, pc);
- Query countQuery = PersistenceUtility.createCountQuery(entityManager, Repo.QUERY_FIND_ALL_IMPORTED_REPOS);
-
+ Query query = null;
+ Query countQuery = null;
+
+ if (authzManager.hasGlobalPermission(subject, Permission.MANAGE_REPOSITORIES)) {
+ query = PersistenceUtility.createQueryWithOrderBy(entityManager, Repo.QUERY_FIND_ALL_IMPORTED_REPOS_ADMIN, pc);
+ countQuery = PersistenceUtility.createCountQuery(entityManager, Repo.QUERY_FIND_ALL_IMPORTED_REPOS_ADMIN);
+ } else {
+ query = PersistenceUtility.createQueryWithOrderBy(entityManager, Repo.QUERY_FIND_ALL_IMPORTED_REPOS, pc);
+ countQuery = PersistenceUtility.createCountQuery(entityManager, Repo.QUERY_FIND_ALL_IMPORTED_REPOS);
+
+ query.setParameter("subject", subject);
+ countQuery.setParameter("subject", subject);
+ }
+
List<Repo> results = query.getResultList();
long count = (Long) countQuery.getSingleResult();
return new PageList<Repo>(results, (int) count, pc);
}
- @RequiredPermission(Permission.MANAGE_INVENTORY)
public Repo getRepo(Subject subject, int repoId) {
+ if (!authzManager.canViewRepo(subject, repoId)) {
+ throw new PermissionException("User [" + subject + "] cannot access the repo with id " + repoId);
+ }
+
Repo repo = entityManager.find(Repo.class, repoId);
if ((repo != null) && (repo.getRepoContentSources() != null)) {
@@ -180,14 +197,14 @@ public class RepoManagerBean implements RepoManagerLocal, RepoManagerRemote {
return repo;
}
- @RequiredPermission(Permission.MANAGE_INVENTORY)
+ @RequiredPermission(Permission.MANAGE_REPOSITORIES)
public RepoGroup getRepoGroup(Subject subject, int repoGroupId) {
RepoGroup repoGroup = entityManager.find(RepoGroup.class, repoGroupId);
return repoGroup;
}
@SuppressWarnings("unchecked")
- @RequiredPermission(Permission.MANAGE_INVENTORY)
+ @RequiredPermission(Permission.MANAGE_REPOSITORIES)
public PageList<ContentSource> findAssociatedContentSources(Subject subject, int repoId, PageControl pc) {
pc.initDefaultOrderingField("cs.id");
@@ -208,6 +225,10 @@ public class RepoManagerBean implements RepoManagerLocal, RepoManagerRemote {
public PageList<Resource> findSubscribedResources(Subject subject, int repoId, PageControl pc) {
pc.initDefaultOrderingField("rc.resource.id");
+ if (!authzManager.canViewRepo(subject, repoId)) {
+ throw new PermissionException("User [" + subject + "] can't access repository with id " + repoId);
+ }
+
Query query = PersistenceUtility
.createQueryWithOrderBy(entityManager, Repo.QUERY_FIND_SUBSCRIBER_RESOURCES, pc);
Query countQuery = PersistenceUtility.createCountQuery(entityManager, Repo.QUERY_FIND_SUBSCRIBER_RESOURCES);
@@ -224,6 +245,10 @@ public class RepoManagerBean implements RepoManagerLocal, RepoManagerRemote {
@SuppressWarnings("unchecked")
// current resource subscriptions should be viewing, but perhaps available ones shouldn't
public PageList<RepoComposite> findResourceSubscriptions(Subject subject, int resourceId, PageControl pc) {
+ if (!authzManager.canViewResource(subject, resourceId)) {
+ throw new PermissionException("User [" + subject + "] can't view resource with id " + resourceId);
+ }
+
pc.initDefaultOrderingField("c.id");
Query query = PersistenceUtility.createQueryWithOrderBy(entityManager,
@@ -239,8 +264,11 @@ public class RepoManagerBean implements RepoManagerLocal, RepoManagerRemote {
return new PageList<RepoComposite>(results, (int) count, pc);
}
- @RequiredPermission(Permission.MANAGE_INVENTORY)
public List<SubscribedRepo> findSubscriptions(Subject subject, int resourceId) {
+ if (!authzManager.canViewResource(subject, resourceId)) {
+ throw new PermissionException("User [" + subject + "] can't view resource with id " + resourceId);
+ }
+
List<SubscribedRepo> list = new ArrayList<SubscribedRepo>();
PageControl pc = new PageControl();
for (RepoComposite repoComposite : findResourceSubscriptions(subject, resourceId, pc)) {
@@ -256,11 +284,24 @@ public class RepoManagerBean implements RepoManagerLocal, RepoManagerRemote {
public PageList<RepoComposite> findAvailableResourceSubscriptions(Subject subject, int resourceId, PageControl pc) {
pc.initDefaultOrderingField("c.id");
- Query query = PersistenceUtility.createQueryWithOrderBy(entityManager,
- Repo.QUERY_FIND_AVAILABLE_REPO_COMPOSITES_BY_RESOURCE_ID, pc);
- Query countQuery = entityManager
- .createNamedQuery(Repo.QUERY_FIND_AVAILABLE_REPO_COMPOSITES_BY_RESOURCE_ID_COUNT);
-
+ Query query = null;
+ Query countQuery = null;
+
+ if (authzManager.hasGlobalPermission(subject, Permission.MANAGE_REPOSITORIES)) {
+ query = PersistenceUtility.createQueryWithOrderBy(entityManager,
+ Repo.QUERY_FIND_AVAILABLE_REPO_COMPOSITES_BY_RESOURCE_ID_ADMIN, pc);
+ countQuery = entityManager
+ .createNamedQuery(Repo.QUERY_FIND_AVAILABLE_REPO_COMPOSITES_BY_RESOURCE_ID_ADMIN_COUNT);
+ } else {
+ query = PersistenceUtility.createQueryWithOrderBy(entityManager,
+ Repo.QUERY_FIND_AVAILABLE_REPO_COMPOSITES_BY_RESOURCE_ID, pc);
+ countQuery = entityManager
+ .createNamedQuery(Repo.QUERY_FIND_AVAILABLE_REPO_COMPOSITES_BY_RESOURCE_ID_COUNT);
+
+ query.setParameter("subject", subject);
+ countQuery.setParameter("subject", subject);
+ }
+
query.setParameter("resourceId", resourceId);
countQuery.setParameter("resourceId", resourceId);
@@ -282,7 +323,7 @@ public class RepoManagerBean implements RepoManagerLocal, RepoManagerRemote {
@SuppressWarnings("unchecked")
public List<RepoComposite> findAvailableResourceSubscriptions(int resourceId) {
- Query query = entityManager.createNamedQuery(Repo.QUERY_FIND_AVAILABLE_REPO_COMPOSITES_BY_RESOURCE_ID);
+ Query query = entityManager.createNamedQuery(Repo.QUERY_FIND_AVAILABLE_REPO_COMPOSITES_BY_RESOURCE_ID_ADMIN);
query.setParameter("resourceId", resourceId);
@@ -291,8 +332,11 @@ public class RepoManagerBean implements RepoManagerLocal, RepoManagerRemote {
}
@SuppressWarnings("unchecked")
- @RequiredPermission(Permission.MANAGE_INVENTORY)
public PageList<PackageVersion> findPackageVersionsInRepo(Subject subject, int repoId, PageControl pc) {
+ if (!authzManager.canViewRepo(subject, repoId)) {
+ throw new PermissionException("User [" + subject + "] can't access repo with id " + repoId);
+ }
+
pc.initDefaultOrderingField("pv.generalPackage.name, pv.version");
Query query = PersistenceUtility.createQueryWithOrderBy(entityManager,
@@ -307,8 +351,11 @@ public class RepoManagerBean implements RepoManagerLocal, RepoManagerRemote {
}
@SuppressWarnings("unchecked")
- @RequiredPermission(Permission.MANAGE_INVENTORY)
public PageList<PackageVersion> findPackageVersionsInRepo(Subject subject, int repoId, String filter, PageControl pc) {
+ if (!authzManager.canViewRepo(subject, repoId)) {
+ throw new PermissionException("User [" + subject + "] can't access repo with id " + repoId);
+ }
+
pc.initDefaultOrderingField("pv.generalPackage.name, pv.version");
Query query = PersistenceUtility.createQueryWithOrderBy(entityManager,
@@ -324,13 +371,15 @@ public class RepoManagerBean implements RepoManagerLocal, RepoManagerRemote {
return new PageList<PackageVersion>(results, (int) count, pc);
}
- @RequiredPermission(Permission.MANAGE_INVENTORY)
public PackageVersion getLatestPackageVersion(Subject subject, int packageId, int repoId) {
return getLatestPackageVersion(subject, packageId, repoId, null);
}
- @RequiredPermission(Permission.MANAGE_INVENTORY)
public PackageVersion getLatestPackageVersion(Subject subject, int packageId, int repoId, Comparator<PackageVersion> versionComparator) {
+ if (!authzManager.canViewRepo(subject, repoId)) {
+ throw new PermissionException("User [" + subject + "] cannot access the repo with id " + repoId);
+ }
+
if (versionComparator == null) {
Query pvcsQ = entityManager.createNamedQuery(PackageVersionContentSource.QUERY_FIND_BY_PACKAGE_AND_REPO_ID_NO_FETCH);
pvcsQ.setParameter("package_id", packageId);
@@ -394,9 +443,13 @@ public class RepoManagerBean implements RepoManagerLocal, RepoManagerRemote {
return latest;
}
- @RequiredPermission(Permission.MANAGE_INVENTORY)
public Repo updateRepo(Subject subject, Repo repo) throws RepoException {
validateFields(repo);
+
+ if (!authzManager.canUpdateRepo(subject, repo.getId())) {
+ throw new PermissionException("User [" + subject + "] can't update repo with id " + repo.getId());
+ }
+
// HHH-2864 - Leave this in until we move to hibernate > 3.2.r14201-2
getRepo(subject, repo.getId());
@@ -416,13 +469,12 @@ public class RepoManagerBean implements RepoManagerLocal, RepoManagerRemote {
return repo;
}
- @RequiredPermission(Permission.MANAGE_INVENTORY)
public Repo createRepo(Subject subject, Repo repo) throws RepoException {
validateRepo(repo);
log.debug("User [" + subject + "] is creating [" + repo + "]...");
entityManager.persist(repo);
- log.debug("User [" + subject + "] created [" + repo + "].");
+ log.info("User [" + subject + "] created [" + repo + "].");
// If this repo is imported, schedule the repo sync job.
if (!repo.isCandidate()) {
@@ -439,7 +491,7 @@ public class RepoManagerBean implements RepoManagerLocal, RepoManagerRemote {
}
@SuppressWarnings("unchecked")
- @RequiredPermission(Permission.MANAGE_INVENTORY)
+ @RequiredPermission(Permission.MANAGE_REPOSITORIES)
public void deleteCandidatesWithOnlyContentSource(Subject subject, int contentSourceId) {
Query query = entityManager.createNamedQuery(Repo.QUERY_FIND_CANDIDATES_WITH_ONLY_CONTENT_SOURCE);
@@ -452,7 +504,7 @@ public class RepoManagerBean implements RepoManagerLocal, RepoManagerRemote {
}
}
- @RequiredPermission(Permission.MANAGE_INVENTORY)
+ @RequiredPermission(Permission.MANAGE_REPOSITORIES)
public void processRepoImportReport(Subject subject, RepoImportReport report, int contentSourceId,
StringBuilder result) {
@@ -572,7 +624,7 @@ public class RepoManagerBean implements RepoManagerLocal, RepoManagerRemote {
}
}
- @RequiredPermission(Permission.MANAGE_INVENTORY)
+ @RequiredPermission(Permission.MANAGE_REPOSITORIES)
public void importCandidateRepo(Subject subject, List<Integer> repoIds) throws RepoException {
for (Integer repoId : repoIds) {
Repo repo = entityManager.find(Repo.class, repoId);
@@ -590,7 +642,7 @@ public class RepoManagerBean implements RepoManagerLocal, RepoManagerRemote {
}
}
- @RequiredPermission(Permission.MANAGE_INVENTORY)
+ @RequiredPermission(Permission.MANAGE_REPOSITORIES)
public RepoGroup createRepoGroup(Subject subject, RepoGroup repoGroup) throws RepoException {
validateRepoGroup(repoGroup);
@@ -638,7 +690,7 @@ public class RepoManagerBean implements RepoManagerLocal, RepoManagerRemote {
}
@SuppressWarnings("unchecked")
- @RequiredPermission(Permission.MANAGE_INVENTORY)
+ @RequiredPermission(Permission.MANAGE_REPOSITORIES)
public void addContentSourcesToRepo(Subject subject, int repoId, int[] contentSourceIds) throws Exception {
Repo repo = entityManager.find(Repo.class, repoId);
if (repo == null) {
@@ -702,8 +754,11 @@ public class RepoManagerBean implements RepoManagerLocal, RepoManagerRemote {
}
}
- @RequiredPermission(Permission.MANAGE_INVENTORY)
public void addPackageVersionsToRepo(Subject subject, int repoId, int[] packageVersionIds) {
+ if (!authzManager.canUpdateRepo(subject, repoId)) {
+ throw new PermissionException("User [" + subject + "] can't update repo with id " + repoId);
+ }
+
Repo repo = entityManager.find(Repo.class, repoId);
for (int packageVersionId : packageVersionIds) {
@@ -714,7 +769,7 @@ public class RepoManagerBean implements RepoManagerLocal, RepoManagerRemote {
}
}
- @RequiredPermission(Permission.MANAGE_INVENTORY)
+ @RequiredPermission(Permission.MANAGE_REPOSITORIES)
public void removeContentSourcesFromRepo(Subject subject, int repoId, int[] contentSourceIds) throws RepoException {
Repo repo = getRepo(subject, repoId);
@@ -778,6 +833,13 @@ public class RepoManagerBean implements RepoManagerLocal, RepoManagerRemote {
throw new RuntimeException("One or more of the repos do not exist [" + idList + "]->[" + repos + "]");
}
+ //authz check
+ for(Repo repo : repos) {
+ if (!authzManager.canViewRepo(subject, repo.getId())) {
+ throw new PermissionException("User [" + subject + "] cannot access a repo with id " + repo.getId());
+ }
+ }
+
for (Repo repo : repos) {
ResourceRepo mapping = repo.addResource(resource);
entityManager.persist(mapping);
@@ -824,8 +886,11 @@ public class RepoManagerBean implements RepoManagerLocal, RepoManagerRemote {
}
}
- @RequiredPermission(Permission.MANAGE_INVENTORY)
public long getPackageVersionCountFromRepo(Subject subject, String filter, int repoId) {
+ if (!authzManager.canViewRepo(subject, repoId)) {
+ throw new PermissionException("User [" + subject + "] can't access repo with id " + repoId);
+ }
+
Query countQuery = PersistenceUtility.createCountQuery(entityManager,
PackageVersion.QUERY_FIND_BY_REPO_ID_FILTERED);
@@ -835,23 +900,22 @@ public class RepoManagerBean implements RepoManagerLocal, RepoManagerRemote {
return ((Long) countQuery.getSingleResult()).longValue();
}
- @RequiredPermission(Permission.MANAGE_INVENTORY)
public long getPackageVersionCountFromRepo(Subject subject, int repoId) {
return getPackageVersionCountFromRepo(subject, null, repoId);
}
@SuppressWarnings("unchecked")
- @RequiredPermission(Permission.MANAGE_INVENTORY)
public PageList<Repo> findReposByCriteria(Subject subject, RepoCriteria criteria) {
CriteriaQueryGenerator generator = new CriteriaQueryGenerator(subject, criteria);
;
-
+
+ //TODO this needs the authz applied somehow
+
CriteriaQueryRunner<Repo> queryRunner = new CriteriaQueryRunner(criteria, generator, entityManager);
return queryRunner.execute();
}
@SuppressWarnings("unchecked")
- @RequiredPermission(Permission.MANAGE_INVENTORY)
public PageList<PackageVersion> findPackageVersionsInRepoByCriteria(Subject subject, PackageVersionCriteria criteria) {
Integer repoId = criteria.getFilterRepoId();
@@ -859,6 +923,11 @@ public class RepoManagerBean implements RepoManagerLocal, RepoManagerRemote {
throw new IllegalArgumentException("Illegal filterResourceId: " + repoId);
}
+ if (!authzManager.canViewRepo(subject, repoId)) {
+ throw new PermissionException("User [" + subject + "] can't access repo with id " + repoId);
+ }
+
+
CriteriaQueryGenerator generator = new CriteriaQueryGenerator(subject, criteria);
;
@@ -867,7 +936,7 @@ public class RepoManagerBean implements RepoManagerLocal, RepoManagerRemote {
return queryRunner.execute();
}
- @RequiredPermission(Permission.MANAGE_INVENTORY)
+ @RequiredPermission(Permission.MANAGE_REPOSITORIES)
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public void addRepoRelationship(Subject subject, int repoId, int relatedRepoId, String relationshipTypeName) {
@@ -1018,7 +1087,7 @@ public class RepoManagerBean implements RepoManagerLocal, RepoManagerRemote {
}
}
- @RequiredPermission(Permission.MANAGE_INVENTORY)
+ @RequiredPermission(Permission.MANAGE_REPOSITORIES)
public long getDistributionCountFromRepo(Subject subject, int repoId) {
Query countQuery = PersistenceUtility.createCountQuery(entityManager, RepoDistribution.QUERY_FIND_BY_REPO_ID);
@@ -1027,7 +1096,7 @@ public class RepoManagerBean implements RepoManagerLocal, RepoManagerRemote {
return (Long) countQuery.getSingleResult();
}
- @RequiredPermission(Permission.MANAGE_INVENTORY)
+ @RequiredPermission(Permission.MANAGE_REPOSITORIES)
@SuppressWarnings("unchecked")
public PageList<Distribution> findAssociatedDistributions(Subject subject, int repoid, PageControl pc) {
pc.setPrimarySort("rkt.id", PageOrdering.ASC);
@@ -1049,7 +1118,7 @@ public class RepoManagerBean implements RepoManagerLocal, RepoManagerRemote {
}
- @RequiredPermission(Permission.MANAGE_INVENTORY)
+ @RequiredPermission(Permission.MANAGE_REPOSITORIES)
@SuppressWarnings("unchecked")
public PageList<Advisory> findAssociatedAdvisory(Subject subject, int repoid, PageControl pc) {
pc.setPrimarySort("rkt.id", PageOrdering.ASC);
@@ -1070,7 +1139,7 @@ public class RepoManagerBean implements RepoManagerLocal, RepoManagerRemote {
}
- @RequiredPermission(Permission.MANAGE_INVENTORY)
+ @RequiredPermission(Permission.MANAGE_REPOSITORIES)
public long getAdvisoryCountFromRepo(Subject subject, int repoId) {
Query countQuery = PersistenceUtility.createCountQuery(entityManager, RepoAdvisory.QUERY_FIND_BY_REPO_ID);
@@ -1105,7 +1174,7 @@ public class RepoManagerBean implements RepoManagerLocal, RepoManagerRemote {
}
}
- @RequiredPermission(Permission.MANAGE_INVENTORY)
+ @RequiredPermission(Permission.MANAGE_REPOSITORIES)
public int synchronizeRepos(Subject subject, int[] repoIds) throws Exception {
int syncCount = 0;
@@ -1148,6 +1217,7 @@ public class RepoManagerBean implements RepoManagerLocal, RepoManagerRemote {
return syncCount;
}
+ @RequiredPermission(Permission.MANAGE_REPOSITORIES)
public void cancelSync(Subject subject, int repoId) throws ContentException {
ContentServerPluginContainer pc;
try {
@@ -1181,7 +1251,7 @@ public class RepoManagerBean implements RepoManagerLocal, RepoManagerRemote {
}
@SuppressWarnings("unchecked")
- @RequiredPermission(Permission.MANAGE_INVENTORY)
+ @RequiredPermission(Permission.MANAGE_REPOSITORIES)
public PageList<RepoSyncResults> getRepoSyncResults(Subject subject, int repoId, PageControl pc) {
pc.initDefaultOrderingField("cssr.startTime", PageOrdering.DESC);
commit a0702518a157d910c7f965b33a99862aa8813614
Merge: 287e19b... ec5b64e...
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Wed Feb 9 14:59:45 2011 +0100
Merge remote branch 'origin/master' into cli-alert-notifs
diff --cc modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/form/RadioGroupWithComponentsItem.java
index d37721e,e75ee44..54435ce
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/form/RadioGroupWithComponentsItem.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/form/RadioGroupWithComponentsItem.java
@@@ -37,9 -36,10 +37,11 @@@ import com.smartgwt.client.widgets.form
import com.smartgwt.client.widgets.form.fields.events.ChangedHandler;
import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableDynamicForm;
+import org.rhq.enterprise.gui.coregui.client.util.selenium.SeleniumUtility;
/**
+ * TODO
+ *
* @author Greg Hinkle
*/
public class RadioGroupWithComponentsItem extends CanvasItem {
diff --cc modules/enterprise/server/plugins/pom.xml
index 86d8cfe,738ec95..7da7c3b
--- a/modules/enterprise/server/plugins/pom.xml
+++ b/modules/enterprise/server/plugins/pom.xml
@@@ -80,7 -80,7 +80,8 @@@
-->
<module>alert-snmp</module>
<module>alert-subject</module>
+ <module>alert-cli</module>
+ <module>alert-log4j</module>
<module>cobbler</module>
<module>filetemplate-bundle</module>
<module>ant-bundle</module>
commit 287e19bd69853a11d38e6a8c901e84e2b19ebb51
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Wed Feb 9 14:58:03 2011 +0100
small i18n
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/CliNotificationSenderForm.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/CliNotificationSenderForm.java
index 085af1d..8ca863e 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/CliNotificationSenderForm.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/CliNotificationSenderForm.java
@@ -24,8 +24,6 @@ import java.util.LinkedHashMap;
import java.util.List;
import com.google.gwt.user.client.rpc.AsyncCallback;
-import com.smartgwt.client.data.Criteria;
-import com.smartgwt.client.widgets.Label;
import com.smartgwt.client.widgets.form.DynamicForm;
import com.smartgwt.client.widgets.form.fields.ButtonItem;
import com.smartgwt.client.widgets.form.fields.PasswordItem;
@@ -34,8 +32,6 @@ import com.smartgwt.client.widgets.form.fields.TextItem;
import com.smartgwt.client.widgets.form.fields.events.ChangedEvent;
import com.smartgwt.client.widgets.form.fields.events.ChangedHandler;
-import org.apache.tools.ant.taskdefs.LoadProperties;
-
import org.rhq.core.domain.alert.notification.AlertNotification;
import org.rhq.core.domain.auth.Subject;
import org.rhq.core.domain.content.Package;
@@ -48,14 +44,8 @@ import org.rhq.core.domain.util.PageList;
import org.rhq.enterprise.gui.coregui.client.CoreGUI;
import org.rhq.enterprise.gui.coregui.client.UserSessionManager;
import org.rhq.enterprise.gui.coregui.client.components.form.RadioGroupWithComponentsItem;
-import org.rhq.enterprise.gui.coregui.client.components.selector.AbstractSelector;
import org.rhq.enterprise.gui.coregui.client.gwt.GWTServiceLookup;
-import org.rhq.enterprise.gui.coregui.client.util.RPCDataSource;
import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableDynamicForm;
-import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableVLayout;
-import org.rhq.enterprise.server.alert.AlertManagerLocal;
-import org.rhq.enterprise.server.plugin.pc.alert.AlertSender;
-import org.rhq.enterprise.server.util.LookupUtil;
/**
* A form to configure the CLI script alert notification.
@@ -134,7 +124,7 @@ public class CliNotificationSenderForm extends AbstractNotificationSenderForm {
if (!formBuilt) {
LocatableDynamicForm form = new LocatableDynamicForm(extendLocatorId("form"));
- repoSelector = new SelectItem("repoSelector", "Repository:"); //TODO i18n
+ repoSelector = new SelectItem("repoSelector", MSG.view_alert_definition_notification_cliScript_editor_repository());
repoSelector.setDefaultToFirstOption(false);
repoSelector.setWrapTitle(false);
repoSelector.setRedrawOnChange(true);
@@ -142,7 +132,7 @@ public class CliNotificationSenderForm extends AbstractNotificationSenderForm {
repoSelector.setValueMap(MSG.common_msg_loading());
repoSelector.setDisabled(true);
- packageSelector = new SelectItem("packageSelector", "Script:"); //TODO i18n
+ packageSelector = new SelectItem("packageSelector", MSG.view_alert_definition_notification_cliScript_editor_script());
packageSelector.setDefaultToFirstOption(false);
packageSelector.setWrapTitle(false);
packageSelector.setRedrawOnChange(true);
@@ -150,6 +140,7 @@ public class CliNotificationSenderForm extends AbstractNotificationSenderForm {
packageSelector.setValueMap(MSG.common_msg_loading());
packageSelector.setDisabled(true);
+
DynamicForm anotherUserForm = createAnotherUserForm();
LinkedHashMap<String, DynamicForm> userSelectItems = new LinkedHashMap<String, DynamicForm>();
@@ -196,6 +187,7 @@ public class CliNotificationSenderForm extends AbstractNotificationSenderForm {
if (config.selectedSubject != null && !UserSessionManager.getSessionSubject().equals(config.selectedSubject)) {
//TODO select the second radio and put it the user name..
}
+ markForRedraw();
}
private void setupPackageSelector(Config config) {
@@ -212,6 +204,8 @@ public class CliNotificationSenderForm extends AbstractNotificationSenderForm {
}
packageSelector.setDisabled(false);
+
+ markForRedraw();
}
private void setupRepoSelector(final Config config) {
@@ -255,6 +249,8 @@ public class CliNotificationSenderForm extends AbstractNotificationSenderForm {
});
repoSelector.setDisabled(false);
+
+ markForRedraw();
}
public boolean validate() {
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 dc0368f..06dc417 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
@@ -797,6 +797,8 @@ view_alert_definition_notification_role_editor_saveFailed = Cannot save the sele
view_alert_definition_notification_user_editor_loadFailed = Cannot determine current users - starting empty
view_alert_definition_notification_user_editor_restoreFailed = Cannot use current users - starting empty
view_alert_definition_notification_user_editor_saveFailed = Cannot save the selected users
+view_alert_definition_notification_cliScript_editor_repository = Repository
+view_alert_definition_notification_cliScript_editor_script = Script
view_alert_definition_notification_cliScript_editor_whichUser = User to run the script as
view_alert_definition_notification_cliScript_editor_thisUser = Myself
view_alert_definition_notification_cliScript_editor_anotherUser = Another user
commit 2a97c4caf7f577810a21138f90a99d2a339d1af6
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Wed Feb 9 14:24:01 2011 +0100
Rewriting the queries for package types with possibly null resource type. ...resourceType.id = ? wouldn't work if the parameter was null.
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/content/PackageType.java b/modules/core/domain/src/main/java/org/rhq/core/domain/content/PackageType.java
index c400bc6..d9e3ea3 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/content/PackageType.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/content/PackageType.java
@@ -67,6 +67,7 @@ import org.rhq.core.domain.resource.ResourceType;
@NamedQuery(name = PackageType.QUERY_FIND_ALL, query = "SELECT pt FROM PackageType pt"),
@NamedQuery(name = PackageType.QUERY_FIND_BY_RESOURCE_TYPE_ID, query = "SELECT pt FROM PackageType pt WHERE pt.resourceType.id = :typeId"),
@NamedQuery(name = PackageType.QUERY_FIND_BY_RESOURCE_TYPE_ID_AND_NAME, query = "SELECT pt FROM PackageType pt WHERE pt.resourceType.id = :typeId AND pt.name = :name"),
+ @NamedQuery(name = PackageType.QUERY_FIND_BY_NAME_AND_NULL_RESOURCE_TYPE, query = "SELECT pt FROM PackageType pt WHERE pt.resourceType = null AND pt.name = :name"),
@NamedQuery(name = PackageType.QUERY_FIND_BY_RESOURCE_TYPE_ID_AND_CREATION_FLAG, query = "SELECT pt FROM PackageType pt "
+ "JOIN pt.resourceType rt "
+ "LEFT JOIN FETCH pt.deploymentConfigurationDefinition cd "
@@ -85,6 +86,7 @@ public class PackageType implements Serializable {
public static final String QUERY_FIND_BY_RESOURCE_TYPE_ID = "PackageType.findByResourceTypeId";
public static final String QUERY_FIND_BY_RESOURCE_TYPE_ID_AND_NAME = "PackageType.findByResourceTypeIdAndName";
+ public static final String QUERY_FIND_BY_NAME_AND_NULL_RESOURCE_TYPE = "PackageType.findByNameAndNullResourceType";
public static final String QUERY_FIND_BY_RESOURCE_TYPE_ID_AND_CREATION_FLAG = "PackageType.findByResourceTypeIdAndCreationFlag";
public static final String QUERY_DYNAMIC_CONFIG_VALUES = "PackageType.dynamicConfigValues";
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/content/PackageVersion.java b/modules/core/domain/src/main/java/org/rhq/core/domain/content/PackageVersion.java
index ba30f9a..c79dd0a 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/content/PackageVersion.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/content/PackageVersion.java
@@ -69,11 +69,16 @@ import org.rhq.core.domain.util.OSGiVersionComparator;
@NamedQuery(name = PackageVersion.QUERY_FIND_BY_PACKAGE_VER_ARCH, query = "SELECT pv FROM PackageVersion AS pv "
+ " WHERE pv.generalPackage.name = :name " + " AND pv.generalPackage.packageType.id = :packageTypeId "
+ " AND pv.architecture.id = :architectureId " + " AND pv.version = :version "),
- @NamedQuery(name = PackageVersion.QUERY_FIND_BY_PACKAGE_DETAILS_KEY, query = "SELECT pv FROM PackageVersion AS pv "
+ @NamedQuery(name = PackageVersion.QUERY_FIND_BY_PACKAGE_DETAILS_KEY_WITH_NON_NULL_RESOURCE_TYPE, query = "SELECT pv FROM PackageVersion AS pv "
+ " WHERE pv.generalPackage.name = :packageName "
+ " AND pv.generalPackage.packageType.name = :packageTypeName "
+ " AND pv.generalPackage.packageType.resourceType.id = :resourceTypeId "
+ " AND pv.architecture.name = :architectureName " + " AND pv.version = :version "),
+ @NamedQuery(name = PackageVersion.QUERY_FIND_BY_PACKAGE_DETAILS_KEY, query = "SELECT pv FROM PackageVersion AS pv "
+ + " WHERE pv.generalPackage.name = :packageName "
+ + " AND pv.generalPackage.packageType.name = :packageTypeName "
+ + " AND pv.generalPackage.packageType.resourceType = :resourceType "
+ + " AND pv.architecture.name = :architectureName " + " AND pv.version = :version "),
@NamedQuery(name = PackageVersion.QUERY_FIND_ID_BY_PACKAGE_DETAILS_KEY_AND_RES_ID, query = "SELECT pv.id "
+ " FROM PackageVersion AS pv " + " JOIN pv.generalPackage.packageType.resourceType.resources r "
+ " WHERE pv.generalPackage.name = :packageName "
@@ -258,6 +263,7 @@ public class PackageVersion implements Serializable {
public static final String QUERY_FIND_BY_PACKAGE_VER_ARCH = "PackageVersion.findByPackageVerArch";
public static final String QUERY_FIND_BY_PACKAGE_SHA = "PackageVersion.findByPackageSha";
public static final String QUERY_FIND_BY_PACKAGE_SHA_RES_TYPE = "PackageVersion.findByPackageShaResType";
+ public static final String QUERY_FIND_BY_PACKAGE_DETAILS_KEY_WITH_NON_NULL_RESOURCE_TYPE = "PackageVersion.findByPackageDetailsKeyWithNonNullResourceType";
public static final String QUERY_FIND_BY_PACKAGE_DETAILS_KEY = "PackageVersion.findByPackageDetailsKey";
public static final String QUERY_FIND_BY_PACKAGE_DETAILS_SHA = "PackageVersion.findByPackageDetailsSha";
public static final String QUERY_FIND_ID_BY_PACKAGE_DETAILS_KEY_AND_RES_ID = "PackageVersion.findIdByPackageDetailsKeyAndResId";
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerBean.java
index fe9c08f..eb71dfe 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerBean.java
@@ -424,7 +424,7 @@ public class ContentManagerBean implements ContentManagerLocal, ContentManagerRe
// Load the package version for the relationship
PackageDetailsKey key = packageDetails.getKey();
Query packageVersionQuery = entityManager
- .createNamedQuery(PackageVersion.QUERY_FIND_BY_PACKAGE_DETAILS_KEY);
+ .createNamedQuery(PackageVersion.QUERY_FIND_BY_PACKAGE_DETAILS_KEY_WITH_NON_NULL_RESOURCE_TYPE);
packageVersionQuery.setParameter("packageName", key.getName());
packageVersionQuery.setParameter("packageTypeName", key.getPackageTypeName());
packageVersionQuery.setParameter("architectureName", key.getArchitectureName());
@@ -489,7 +489,7 @@ public class ContentManagerBean implements ContentManagerLocal, ContentManagerRe
// Load the package version for the relationship
PackageDetailsKey key = singleResponse.getKey();
Query packageVersionQuery = entityManager
- .createNamedQuery(PackageVersion.QUERY_FIND_BY_PACKAGE_DETAILS_KEY);
+ .createNamedQuery(PackageVersion.QUERY_FIND_BY_PACKAGE_DETAILS_KEY_WITH_NON_NULL_RESOURCE_TYPE);
packageVersionQuery.setParameter("packageName", key.getName());
packageVersionQuery.setParameter("packageTypeName", key.getPackageTypeName());
packageVersionQuery.setParameter("architectureName", key.getArchitectureName());
@@ -712,7 +712,7 @@ public class ContentManagerBean implements ContentManagerLocal, ContentManagerRe
// Load the package version for the relationship
PackageDetailsKey key = singleResponse.getKey();
Query packageVersionQuery = entityManager
- .createNamedQuery(PackageVersion.QUERY_FIND_BY_PACKAGE_DETAILS_KEY);
+ .createNamedQuery(PackageVersion.QUERY_FIND_BY_PACKAGE_DETAILS_KEY_WITH_NON_NULL_RESOURCE_TYPE);
packageVersionQuery.setParameter("packageName", key.getName());
packageVersionQuery.setParameter("packageTypeName", key.getPackageTypeName());
packageVersionQuery.setParameter("architectureName", key.getArchitectureName());
@@ -1022,7 +1022,7 @@ public class ContentManagerBean implements ContentManagerLocal, ContentManagerRe
long installationDate = System.currentTimeMillis();
for (PackageDetailsKey key : keys) {
- Query packageQuery = entityManager.createNamedQuery(PackageVersion.QUERY_FIND_BY_PACKAGE_DETAILS_KEY);
+ Query packageQuery = entityManager.createNamedQuery(PackageVersion.QUERY_FIND_BY_PACKAGE_DETAILS_KEY_WITH_NON_NULL_RESOURCE_TYPE);
packageQuery.setParameter("packageName", key.getName());
packageQuery.setParameter("packageTypeName", key.getPackageTypeName());
packageQuery.setParameter("architectureName", key.getArchitectureName());
@@ -1123,8 +1123,13 @@ public class ContentManagerBean implements ContentManagerLocal, ContentManagerRe
}
public PackageType findPackageType(Subject subject, Integer resourceTypeId, String packageTypeName) {
- Query q = entityManager.createNamedQuery(PackageType.QUERY_FIND_BY_RESOURCE_TYPE_ID_AND_NAME);
- q.setParameter("typeId", resourceTypeId);
+ Query q = entityManager
+ .createNamedQuery(resourceTypeId == null ? PackageType.QUERY_FIND_BY_NAME_AND_NULL_RESOURCE_TYPE
+ : PackageType.QUERY_FIND_BY_RESOURCE_TYPE_ID_AND_NAME);
+
+ if (resourceTypeId != null) {
+ q.setParameter("typeId", resourceTypeId);
+ }
q.setParameter("name", packageTypeName);
@SuppressWarnings("unchecked")
@@ -1323,7 +1328,7 @@ public class ContentManagerBean implements ContentManagerLocal, ContentManagerRe
q.setParameter("version", pv.getVersion());
ResourceType rt = pv.getGeneralPackage().getPackageType().getResourceType();
- q.setParameter("resourceTypeId", rt != null ? rt.getId() : null);
+ q.setParameter("resourceType", rt);
List<PackageVersion> found = q.getResultList();
if (error != null && found.size() == 0) {
@@ -1561,7 +1566,7 @@ public class ContentManagerBean implements ContentManagerLocal, ContentManagerRe
}
// See if package version already exists for the resource package
- Query packageVersionQuery = entityManager.createNamedQuery(PackageVersion.QUERY_FIND_BY_PACKAGE_DETAILS_KEY);
+ Query packageVersionQuery = entityManager.createNamedQuery(PackageVersion.QUERY_FIND_BY_PACKAGE_DETAILS_KEY_WITH_NON_NULL_RESOURCE_TYPE);
packageVersionQuery.setFlushMode(FlushModeType.COMMIT);
packageVersionQuery.setParameter("packageName", packageName);
PackageType packageType = contentManager.getResourceCreationPackageType(newResourceTypeId);
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentSourceManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentSourceManagerBean.java
index 225d562..5ab74f1 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentSourceManagerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentSourceManagerBean.java
@@ -1600,8 +1600,13 @@ public class ContentSourceManagerBean implements ContentSourceManagerLocal {
PackageType pt = new PackageType(key.getPackageTypeName(), rt);
if (!knownPackageTypes.containsKey(pt)) {
- q = entityManager.createNamedQuery(PackageType.QUERY_FIND_BY_RESOURCE_TYPE_ID_AND_NAME);
- q.setParameter("typeId", rt != null ? rt.getId() : null);
+ if (rt != null) {
+ q = entityManager.createNamedQuery(PackageType.QUERY_FIND_BY_RESOURCE_TYPE_ID_AND_NAME);
+ q.setParameter("typeId", rt.getId());
+ } else {
+ q = entityManager.createNamedQuery(PackageType.QUERY_FIND_BY_NAME_AND_NULL_RESOURCE_TYPE);
+ }
+
q.setParameter("name", pt.getName());
try {
@@ -1677,7 +1682,7 @@ public class ContentSourceManagerBean implements ContentSourceManagerLocal {
q = entityManager.createNamedQuery(PackageVersion.QUERY_FIND_BY_PACKAGE_DETAILS_KEY);
q.setParameter("packageName", newDetails.getName());
q.setParameter("packageTypeName", pt.getName());
- q.setParameter("resourceTypeId", rt.getId());
+ q.setParameter("resourceType", rt);
q.setParameter("architectureName", arch.getName());
q.setParameter("version", newDetails.getVersion());
@@ -1965,7 +1970,7 @@ public class ContentSourceManagerBean implements ContentSourceManagerLocal {
ResourceType childResourceType = (ResourceType) query.getSingleResult();
- query = entityManager.createNamedQuery(PackageVersion.QUERY_FIND_BY_PACKAGE_DETAILS_KEY);
+ query = entityManager.createNamedQuery(PackageVersion.QUERY_FIND_BY_PACKAGE_DETAILS_KEY_WITH_NON_NULL_RESOURCE_TYPE);
query.setParameter("packageName", packageDetailsKey.getName());
query.setParameter("packageTypeName", packageDetailsKey.getPackageTypeName());
query.setParameter("architectureName", packageDetailsKey.getArchitectureName());
commit 3b66ce7f12171b3e8079d62ee7254eccf34eb389
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Wed Feb 9 12:24:33 2011 +0100
More CLI script alert GUI work.
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/PackageCriteria.java b/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/PackageCriteria.java
index 47bc804..d358cb1 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/PackageCriteria.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/PackageCriteria.java
@@ -40,13 +40,17 @@ public class PackageCriteria extends Criteria {
private String filterName;
private String filterClassification;
private Integer filterPackageTypeId;
+ private Integer filterRepoId;
private boolean fetchVersions;
private PageOrdering sortName;
public PackageCriteria() {
- filterOverrides.put("packageTypeId", "packageType.id = ? ");
+ filterOverrides.put("packageTypeId", "packageType.id = ? ");
+ filterOverrides.put("repoId", "id IN (" +
+ "SELECT rpv.packageVersion.generalPackage.id FROM RepoPackageVersion rpv WHERE rpv.repo.id = ?" +
+ ")");
}
public Class<?> getPersistentClass() {
@@ -69,6 +73,10 @@ public class PackageCriteria extends Criteria {
this.filterPackageTypeId = packageTypeId;
}
+ public void addFilterRepoId(Integer repoId) {
+ this.filterRepoId = repoId;
+ }
+
public void fetchVersions(boolean fetchVersions) {
this.fetchVersions = fetchVersions;
}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/CliNotificationSenderForm.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/CliNotificationSenderForm.java
index c7b7972..085af1d 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/CliNotificationSenderForm.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/CliNotificationSenderForm.java
@@ -19,6 +19,7 @@
package org.rhq.enterprise.gui.coregui.client.alert.definitions;
+import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
@@ -26,22 +27,35 @@ import com.google.gwt.user.client.rpc.AsyncCallback;
import com.smartgwt.client.data.Criteria;
import com.smartgwt.client.widgets.Label;
import com.smartgwt.client.widgets.form.DynamicForm;
+import com.smartgwt.client.widgets.form.fields.ButtonItem;
+import com.smartgwt.client.widgets.form.fields.PasswordItem;
import com.smartgwt.client.widgets.form.fields.SelectItem;
+import com.smartgwt.client.widgets.form.fields.TextItem;
+import com.smartgwt.client.widgets.form.fields.events.ChangedEvent;
+import com.smartgwt.client.widgets.form.fields.events.ChangedHandler;
+
+import org.apache.tools.ant.taskdefs.LoadProperties;
import org.rhq.core.domain.alert.notification.AlertNotification;
import org.rhq.core.domain.auth.Subject;
import org.rhq.core.domain.content.Package;
+import org.rhq.core.domain.content.PackageType;
import org.rhq.core.domain.content.Repo;
import org.rhq.core.domain.criteria.PackageCriteria;
import org.rhq.core.domain.criteria.RepoCriteria;
import org.rhq.core.domain.criteria.SubjectCriteria;
import org.rhq.core.domain.util.PageList;
+import org.rhq.enterprise.gui.coregui.client.CoreGUI;
+import org.rhq.enterprise.gui.coregui.client.UserSessionManager;
import org.rhq.enterprise.gui.coregui.client.components.form.RadioGroupWithComponentsItem;
import org.rhq.enterprise.gui.coregui.client.components.selector.AbstractSelector;
import org.rhq.enterprise.gui.coregui.client.gwt.GWTServiceLookup;
import org.rhq.enterprise.gui.coregui.client.util.RPCDataSource;
import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableDynamicForm;
import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableVLayout;
+import org.rhq.enterprise.server.alert.AlertManagerLocal;
+import org.rhq.enterprise.server.plugin.pc.alert.AlertSender;
+import org.rhq.enterprise.server.util.LookupUtil;
/**
* A form to configure the CLI script alert notification.
@@ -56,6 +70,13 @@ public class CliNotificationSenderForm extends AbstractNotificationSenderForm {
boolean formBuilt;
+ private SelectItem repoSelector;
+ private SelectItem packageSelector;
+ private RadioGroupWithComponentsItem userSelector;
+
+ private PackageType cliScriptPackageType;
+ private static final String PACKAGE_TYPE_NAME = "__SERVER_SIDE_CLI_SCRIPT";
+
private static class Config {
List<Repo> allRepos;
Repo selectedRepo;
@@ -64,6 +85,42 @@ public class CliNotificationSenderForm extends AbstractNotificationSenderForm {
Package selectedPackage;
Subject selectedSubject;
+
+ /*
+ * This is a counter to keep track if all the async
+ * loading of the above data has finished.
+ *
+ * In principle, this should be AtomicInteger but GWT didn't like it.
+ *
+ * The reason why it still works as a normal integer even though it
+ * is being updated from within the AsyncCallbacks is that the javascript
+ * engines in the browsers are single threaded and therefore, even though
+ * the data is loaded in the background, it is processed (and this variable
+ * updated) only in that single thread.
+ */
+ int __handlerCounter = 3;
+
+ public void setSelectedRepo(int repoId) {
+ if (allRepos != null) {
+ for(Repo r : allRepos) {
+ if (r.getId() == repoId) {
+ selectedRepo = r;
+ break;
+ }
+ }
+ }
+ }
+
+ public void setSelectedPackage(int packageId) {
+ if (allPackages != null) {
+ for(Package p : allPackages) {
+ if (p.getId() == packageId) {
+ selectedPackage = p;
+ break;
+ }
+ }
+ }
+ }
}
public CliNotificationSenderForm(String locatorId, AlertNotification notif, String sender) {
@@ -77,7 +134,7 @@ public class CliNotificationSenderForm extends AbstractNotificationSenderForm {
if (!formBuilt) {
LocatableDynamicForm form = new LocatableDynamicForm(extendLocatorId("form"));
- SelectItem repoSelector = new SelectItem("repoSelector", "Repository:"); //TODO i18n
+ repoSelector = new SelectItem("repoSelector", "Repository:"); //TODO i18n
repoSelector.setDefaultToFirstOption(false);
repoSelector.setWrapTitle(false);
repoSelector.setRedrawOnChange(true);
@@ -85,7 +142,7 @@ public class CliNotificationSenderForm extends AbstractNotificationSenderForm {
repoSelector.setValueMap(MSG.common_msg_loading());
repoSelector.setDisabled(true);
- SelectItem packageSelector = new SelectItem("packageSelector", "Script:"); //TODO i18n
+ packageSelector = new SelectItem("packageSelector", "Script:"); //TODO i18n
packageSelector.setDefaultToFirstOption(false);
packageSelector.setWrapTitle(false);
packageSelector.setRedrawOnChange(true);
@@ -100,68 +157,165 @@ public class CliNotificationSenderForm extends AbstractNotificationSenderForm {
userSelectItems.put(MSG.view_alert_definition_notification_cliScript_editor_thisUser(), null);
userSelectItems.put(MSG.view_alert_definition_notification_cliScript_editor_anotherUser(), anotherUserForm);
- RadioGroupWithComponentsItem userSelector = new RadioGroupWithComponentsItem(
+ userSelector = new RadioGroupWithComponentsItem(
extendLocatorId("userSelector"),
MSG.view_alert_definition_notification_cliScript_editor_whichUser(), userSelectItems, form);
form.setFields(repoSelector, packageSelector, userSelector);
addMember(form);
- Config config = loadConfig();
-
- if (config.selectedRepo != null) {
+ loadPackageType(new AsyncCallback<PackageType>() {
+ public void onFailure(Throwable t) {
+ CoreGUI.getErrorHandler().handleError(MSG.view_alert_definition_notification_cliScript_editor_loadFailed(),
+ t);
+ }
- }
+ public void onSuccess(PackageType result) {
+ cliScriptPackageType = result;
+
+ loadConfig(new AsyncCallback<Config>() {
+ public void onFailure(Throwable t) {
+ CoreGUI.getErrorHandler().handleError(MSG.view_alert_definition_notification_cliScript_editor_loadFailed(),
+ t);
+ }
+
+ public void onSuccess(Config config) {
+ setupRepoSelector(config);
+ setupPackageSelector(config);
+ setupUserSelector(config);
+ }
+ });
+ }
+ });
formBuilt = true;
}
}
+ private void setupUserSelector(Config config) {
+ if (config.selectedSubject != null && !UserSessionManager.getSessionSubject().equals(config.selectedSubject)) {
+ //TODO select the second radio and put it the user name..
+ }
+ }
+
+ private void setupPackageSelector(Config config) {
+ LinkedHashMap<String, String> map = new LinkedHashMap<String, String>();
+ for(Package p : config.allPackages) {
+ map.put(String.valueOf(p.getId()), p.getName());
+ }
+
+ packageSelector.setValueMap(map);
+ if (config.selectedPackage != null) {
+ packageSelector.setValue(config.selectedPackage.getId());
+ } else {
+ packageSelector.setValue("");
+ }
+
+ packageSelector.setDisabled(false);
+ }
+
+ private void setupRepoSelector(final Config config) {
+ LinkedHashMap<String, String> map = new LinkedHashMap<String, String>();
+ for(Repo r : config.allRepos) {
+ map.put(String.valueOf(r.getId()), r.getName());
+ }
+
+ repoSelector.setValueMap(map);
+ if (config.selectedRepo != null) {
+ repoSelector.setValue(config.selectedRepo.getId());
+ } else {
+ repoSelector.setValue("");
+ }
+
+ repoSelector.addChangedHandler(new ChangedHandler() {
+ public void onChanged(ChangedEvent event) {
+ Integer repoId = Integer.valueOf(event.getItem().getValue().toString());
+ config.setSelectedRepo(repoId);
+
+ PackageCriteria pc = new PackageCriteria();
+ pc.addFilterRepoId(repoId);
+ pc.addFilterPackageTypeId(cliScriptPackageType.getId());
+
+ packageSelector.setDisabled(true);
+ packageSelector.setValueMap(MSG.common_msg_loading());
+
+ GWTServiceLookup.getContentService().findPackagesByCriteria(pc, new AsyncCallback<PageList<Package>>() {
+ public void onSuccess(PageList<Package> result) {
+ config.allPackages = result;
+ config.selectedPackage = null;
+ setupPackageSelector(config);
+ }
+
+ public void onFailure(Throwable caught) {
+ CoreGUI.getErrorHandler().handleError(MSG.view_alert_definition_notification_cliScript_editor_loadFailed(),
+ caught);
+ }
+ });
+ }
+ });
+
+ repoSelector.setDisabled(false);
+ }
+
public boolean validate() {
// TODO implement
- return false;
+ return true;
}
- private Config loadConfig() {
- String repoId = getConfiguration().getSimpleValue(PROP_REPO_ID, null);
- String packageId = getConfiguration().getSimpleValue(PROP_PACKAGE_ID, null);
- String subjectId = getConfiguration().getSimpleValue(PROP_USER_ID, null);
+ private void loadConfig(final AsyncCallback<Config> handler) {
+ final String repoId = getConfiguration().getSimpleValue(PROP_REPO_ID, null);
+ final String packageId = getConfiguration().getSimpleValue(PROP_PACKAGE_ID, null);
+ final String subjectId = getConfiguration().getSimpleValue(PROP_USER_ID, null);
final Config config = new Config();
- if (repoId != null && repoId.trim().length() > 0) {
- int rid = Integer.parseInt(repoId);
- RepoCriteria c = new RepoCriteria();
- c.addFilterId(rid);
- GWTServiceLookup.getRepoService().findReposByCriteria(c, new AsyncCallback<PageList<Repo>>() {
- public void onSuccess(PageList<Repo> result) {
- if (result.size() > 0) {
- config.selectedRepo = result.get(0);
- }
+ RepoCriteria rc = new RepoCriteria();
+
+ GWTServiceLookup.getRepoService().findReposByCriteria(rc, new AsyncCallback<PageList<Repo>>() {
+ public void onSuccess(PageList<Repo> result) {
+ config.allRepos = result;
+
+ if (repoId != null && repoId.trim().length() > 0) {
+ final int rid = Integer.parseInt(repoId);
+ config.setSelectedRepo(rid);
}
-
- public void onFailure(Throwable caught) {
- //TODO
+
+ if (--config.__handlerCounter == 0) {
+ handler.onSuccess(config);
}
- });
- }
+ }
+
+ public void onFailure(Throwable caught) {
+ handler.onFailure(caught);
+ }
+ });
- if (packageId != null && packageId.trim().length() > 0) {
- int pid = Integer.parseInt(packageId);
- PackageCriteria c = new PackageCriteria();
- c.addFilterId(pid);
+ if (repoId != null && repoId.trim().length() > 0) {
+ PackageCriteria pc = new PackageCriteria();
+ pc.addFilterRepoId(Integer.parseInt(repoId));
+ pc.addFilterPackageTypeId(cliScriptPackageType.getId());
- GWTServiceLookup.getContentService().findPackagesByCriteria(c, new AsyncCallback<PageList<Package>>() {
+ GWTServiceLookup.getContentService().findPackagesByCriteria(pc, new AsyncCallback<PageList<Package>>() {
public void onSuccess(PageList<Package> result) {
- if (result.size() > 0) {
- config.selectedPackage = result.get(0);
+ config.allPackages = result;
+
+ if (packageId != null && packageId.trim().length() > 0) {
+ int pid = Integer.parseInt(packageId);
+ config.setSelectedPackage(pid);
+ }
+
+ if (--config.__handlerCounter == 0) {
+ handler.onSuccess(config);
}
}
public void onFailure(Throwable caught) {
- //TODO
+ handler.onFailure(caught);
}
});
+ } else {
+ config.allPackages = Collections.emptyList();
+ --config.__handlerCounter;
}
if (subjectId != null && subjectId.trim().length() > 0) {
@@ -174,20 +328,35 @@ public class CliNotificationSenderForm extends AbstractNotificationSenderForm {
if (result.size() > 0) {
config.selectedSubject = result.get(0);
}
+
+ if (--config.__handlerCounter == 0) {
+ handler.onSuccess(config);
+ }
}
public void onFailure(Throwable caught) {
- //TODO
+ handler.onFailure(caught);
}
});
+ } else {
+ --config.__handlerCounter;
}
-
- return config;
}
DynamicForm createAnotherUserForm() {
LocatableDynamicForm form = new LocatableDynamicForm(extendLocatorId("anotherUserForm"));
+ TextItem userNameItem = new TextItem("userName", MSG.dataSource_users_field_name());
+ PasswordItem passwordItem = new PasswordItem("password", MSG.dataSource_users_field_password());
+ ButtonItem verifyItem = new ButtonItem("verify", MSG.view_alert_definition_notification_cliScript_editor_verifyAuthentication());
+ form.setFields(userNameItem, passwordItem, verifyItem);
+
return form;
}
+
+ private void loadPackageType(AsyncCallback<PackageType> handler) {
+ GWTServiceLookup.getContentService().findPackageType(null, PACKAGE_TYPE_NAME, handler);
+ }
+
+
}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/ContentGWTService.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/ContentGWTService.java
index b4acc31..cf80f48 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/ContentGWTService.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/ContentGWTService.java
@@ -51,4 +51,7 @@ public interface ContentGWTService extends RemoteService {
List<Architecture> getArchitectures() throws RuntimeException;
PackageType getResourceCreationPackageType(int resourceTypeId) throws RuntimeException;
+
+ PackageType findPackageType(Integer resourceTypeId, String packageTypeName) throws RuntimeException;
+
}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/ContentGWTServiceImpl.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/ContentGWTServiceImpl.java
index 82f4e85..ed9baa3 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/ContentGWTServiceImpl.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/ContentGWTServiceImpl.java
@@ -107,4 +107,14 @@ public class ContentGWTServiceImpl extends AbstractGWTServiceImpl implements Con
throw new RuntimeException(ThrowableUtil.getAllMessages(t));
}
}
+
+ @Override
+ public PackageType findPackageType(Integer resourceTypeId, String packageTypeName) throws RuntimeException {
+ try {
+ return SerialUtility.prepare(contentManager.findPackageType(getSessionSubject(), resourceTypeId, packageTypeName),
+ "ContentService.findPackageType");
+ } catch (Throwable t) {
+ throw new RuntimeException(ThrowableUtil.getAllMessages(t));
+ }
+ }
}
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 104636d..dc0368f 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
@@ -800,6 +800,9 @@ view_alert_definition_notification_user_editor_saveFailed = Cannot save the sele
view_alert_definition_notification_cliScript_editor_whichUser = User to run the script as
view_alert_definition_notification_cliScript_editor_thisUser = Myself
view_alert_definition_notification_cliScript_editor_anotherUser = Another user
+view_alert_definition_notification_cliScript_editor_verifyAuthentication = Verify
+view_alert_definition_notification_cliScript_editor_loadFailed = Loading the CLI notification editor failed.
+view_alert_definition_notification_cliScript_editor_selectRepoFirst = Select a repo first.
view_alert_definition_recovery_editor_disable_when_fired = Disable When Fired
view_alert_definition_recovery_editor_disable_when_fired_tooltip = Indicates if this alert will be disabled after it fires. Once disabled, the alert can be manually re-enabled or a recovery alert can be set up to automatically re-enable it. If this alert is a recovery alert itself, this setting cannot be turned on.
view_alert_definition_recovery_editor_recovery_alert = Recover Alert
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/webservices/WebservicesManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/webservices/WebservicesManagerBean.java
index 3988901..82c9522 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/webservices/WebservicesManagerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/webservices/WebservicesManagerBean.java
@@ -512,6 +512,10 @@ public class WebservicesManagerBean implements WebservicesRemote {
return contentManager.findPackageTypes(subject, resourceTypeName, pluginName);
}
+ public PackageType findPackageType(Subject subject, Integer resourceTypeId, String packageTypeName) {
+ return contentManager.findPackageType(subject, resourceTypeId, packageTypeName);
+ }
+
public InstalledPackage getBackingPackageForResource(Subject subject, int resourceId) {
return contentManager.getBackingPackageForResource(subject, resourceId);
}
commit b34b5c2a2bbb53f7e501ba3af04739ed24a9dabb
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Wed Feb 9 12:17:01 2011 +0100
Make sure no spaces end up in the names of the form items. SmartGWT doesn't like it.
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/NewNotificationEditor.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/NewNotificationEditor.java
index 6e4b043..e1c4b44 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/NewNotificationEditor.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/NewNotificationEditor.java
@@ -220,7 +220,7 @@ public class NewNotificationEditor extends LocatableDynamicForm {
}
private AbstractNotificationSenderForm createNotificationSenderForm(String sender) {
- String newLocatorId = extendLocatorId(sender);
+ String newLocatorId = extendLocatorId(SeleniumUtility.getSafeId(sender));
AbstractNotificationSenderForm newCanvas;
// NOTE: today there is no way for an alert server plugin developer
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/form/RadioGroupWithComponentsItem.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/form/RadioGroupWithComponentsItem.java
index 9412237..d37721e 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/form/RadioGroupWithComponentsItem.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/form/RadioGroupWithComponentsItem.java
@@ -25,6 +25,7 @@ package org.rhq.enterprise.gui.coregui.client.components.form;
import java.util.ArrayList;
import java.util.LinkedHashMap;
+import java.util.Map;
import com.smartgwt.client.widgets.Canvas;
import com.smartgwt.client.widgets.form.DynamicForm;
@@ -36,13 +37,14 @@ import com.smartgwt.client.widgets.form.fields.events.ChangedEvent;
import com.smartgwt.client.widgets.form.fields.events.ChangedHandler;
import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableDynamicForm;
+import org.rhq.enterprise.gui.coregui.client.util.selenium.SeleniumUtility;
/**
* @author Greg Hinkle
*/
public class RadioGroupWithComponentsItem extends CanvasItem {
- private final LinkedHashMap<String, ? extends Canvas> valueMap;
+ private final LinkedHashMap<NameAndTitle, Canvas> valueMap;
private final RGWCCanvas canvas;
private final DynamicForm form;
private String selected;
@@ -51,7 +53,12 @@ public class RadioGroupWithComponentsItem extends CanvasItem {
DynamicForm form) {
super(name, title);
- this.valueMap = valueMap;
+
+ this.valueMap = new LinkedHashMap<NameAndTitle, Canvas>();
+ for(Map.Entry<String, ? extends Canvas> entry : valueMap.entrySet()) {
+ this.valueMap.put(new NameAndTitle(entry.getKey()), entry.getValue());
+ }
+
this.form = form;
// since the name is an internal identifier I think it can be used as the locatorId
this.canvas = new RGWCCanvas(name);
@@ -71,6 +78,44 @@ public class RadioGroupWithComponentsItem extends CanvasItem {
return valueMap.get(this.selected);
}
+ private static class NameAndTitle {
+ private String name;
+ private String title;
+
+ public NameAndTitle(String title) {
+ name = SeleniumUtility.getSafeId(title);
+ this.title = title;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public String getTitle() {
+ return title;
+ }
+
+ @Override
+ public int hashCode() {
+ return name.hashCode();
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (other == this) {
+ return true;
+ }
+
+ if (!(other instanceof NameAndTitle)) {
+ return false;
+ }
+
+ NameAndTitle o = (NameAndTitle) other;
+
+ return name.equals(o.name);
+ }
+ }
+
public class RGWCCanvas extends LocatableDynamicForm {
public RGWCCanvas(String locatorId) {
@@ -84,11 +129,11 @@ public class RadioGroupWithComponentsItem extends CanvasItem {
ArrayList<FormItem> items = new ArrayList<FormItem>();
- for (final String label : valueMap.keySet()) {
- RadioGroupItem button = new RadioGroupItem(label, label);
+ for (final NameAndTitle label : valueMap.keySet()) {
+ RadioGroupItem button = new RadioGroupItem(label.getName(), label.getTitle());
button.setShowTitle(false);
button.setStartRow(true);
- button.setValueMap(label);
+ button.setValueMap(label.getTitle());
items.add(button);
Canvas value = valueMap.get(label);
@@ -113,12 +158,12 @@ public class RadioGroupWithComponentsItem extends CanvasItem {
public void updateEnablement() {
- for (String key : valueMap.keySet()) {
+ for (NameAndTitle key : valueMap.keySet()) {
Canvas value = valueMap.get(key);
- Boolean disabled = !selected.equals(key);
+ Boolean disabled = !selected.equals(key.getName());
if (disabled) {
- canvas.getItem(key).clearValue();
- canvas.getItem(key).redraw();
+ canvas.getItem(key.getName()).clearValue();
+ canvas.getItem(key.getName()).redraw();
}
disableAllFormFields(value, disabled);
}
commit de3e8efceabbdd4cd6ddae8ab9dce77aa1689cc8
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Wed Feb 9 11:58:22 2011 +0100
The validateAndFinalizeConfiguration() method on the AlertSender now has a Subject argument, so that it has the complete picture of who's requesting the configuration update and what it actually is.
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertDefinitionManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertDefinitionManagerBean.java
index 5537c48..ef3d733 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertDefinitionManagerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertDefinitionManagerBean.java
@@ -199,7 +199,7 @@ public class AlertDefinitionManagerBean implements AlertDefinitionManagerLocal,
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
public int createAlertDefinition(Subject subject, AlertDefinition alertDefinition, Integer resourceId)
throws InvalidAlertDefinitionException {
- checkAlertDefinition(alertDefinition, resourceId);
+ checkAlertDefinition(subject, alertDefinition, resourceId);
// if this is an alert definition, set up the link to a resource
if (resourceId != null) {
@@ -484,7 +484,7 @@ public class AlertDefinitionManagerBean implements AlertDefinitionManagerLocal,
* is not currently deleted
*/
boolean isResourceLevel = (oldAlertDefinition.getResource() != null);
- checkAlertDefinition(alertDefinition, isResourceLevel ? oldAlertDefinition.getResource().getId() : null);
+ checkAlertDefinition(subject, alertDefinition, isResourceLevel ? oldAlertDefinition.getResource().getId() : null);
/*
* Should not be able to update an alert definition if the old alert definition is in an invalid state
@@ -596,7 +596,7 @@ public class AlertDefinitionManagerBean implements AlertDefinitionManagerLocal,
}
}
- private void checkAlertDefinition(AlertDefinition alertDefinition, Integer resourceId)
+ private void checkAlertDefinition(Subject subject, AlertDefinition alertDefinition, Integer resourceId)
throws InvalidAlertDefinitionException {
for (AlertCondition alertCondition : alertDefinition.getConditions()) {
AlertConditionCategory alertConditionCategory = alertCondition.getCategory();
@@ -619,7 +619,7 @@ public class AlertDefinitionManagerBean implements AlertDefinitionManagerLocal,
}
}
- alertNotificationManager.finalizeNotifications(alertDefinition.getAlertNotifications());
+ alertNotificationManager.finalizeNotifications(subject, alertDefinition.getAlertNotifications());
}
private void notifyAlertConditionCacheManager(Subject subject, String methodName, AlertDefinition alertDefinition,
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertNotificationManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertNotificationManagerBean.java
index 13f356b..91cfe5a 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertNotificationManagerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertNotificationManagerBean.java
@@ -305,7 +305,7 @@ public class AlertNotificationManagerBean implements AlertNotificationManagerLoc
return notification;
}
- public boolean finalizeNotifications(List<AlertNotification> notifications) {
+ public boolean finalizeNotifications(Subject subject, List<AlertNotification> notifications) {
boolean hasErrors = false;
AlertSenderPluginManager pluginManager = alertManager.getAlertPluginManager();
@@ -313,7 +313,7 @@ public class AlertNotificationManagerBean implements AlertNotificationManagerLoc
for(AlertNotification notification : notifications) {
AlertSender<?> sender = pluginManager.getAlertSenderForNotification(notification);
- AlertSenderValidationResults validation = sender.validateAndFinalizeConfiguration();
+ AlertSenderValidationResults validation = sender.validateAndFinalizeConfiguration(subject);
notification.setConfiguration(validation.getAlertParameters());
notification.setExtraConfiguration(validation.getExtraParameters());
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertNotificationManagerLocal.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertNotificationManagerLocal.java
index 43a8215..56f8eab 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertNotificationManagerLocal.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertNotificationManagerLocal.java
@@ -72,12 +72,13 @@ public interface AlertNotificationManagerLocal {
* <p>
* The notifications can be modified during this call. New properties can be added to their configurations, etc.
*
+ * @param subject the subject that is requesting the changes
* @param notifications the notifications to process
* @return true if everything went ok, false if the validation fails. In this case one or more properties
* in the configuration or extra configuration of one or more of the notifications contains an error message
* describing the error.
*/
- boolean finalizeNotifications(List<AlertNotification> notifications);
+ boolean finalizeNotifications(Subject subject, List<AlertNotification> notifications);
int purgeOrphanedAlertNotifications();
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/AlertSender.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/AlertSender.java
index f204106..88c140f 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/AlertSender.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/AlertSender.java
@@ -25,6 +25,7 @@ import java.util.Map;
import org.rhq.core.domain.alert.Alert;
import org.rhq.core.domain.alert.notification.SenderResult;
+import org.rhq.core.domain.auth.Subject;
import org.rhq.core.domain.configuration.Configuration;
import org.rhq.core.domain.configuration.Property;
import org.rhq.core.domain.configuration.PropertyMap;
@@ -111,9 +112,10 @@ public abstract class AlertSender<T extends ServerPluginComponent> {
* <p>
* The default implementation makes no changes to the configurations.
*
+ * @param subject the subject requesting the changes in the configuration
* @return the validation results
*/
- public AlertSenderValidationResults validateAndFinalizeConfiguration() {
+ public AlertSenderValidationResults validateAndFinalizeConfiguration(Subject subject) {
return new AlertSenderValidationResults(alertParameters, extraParameters);
}
diff --git a/modules/enterprise/server/plugins/alert-cli/src/main/java/org/rhq/enterprise/server/plugins/alertCli/CliSender.java b/modules/enterprise/server/plugins/alert-cli/src/main/java/org/rhq/enterprise/server/plugins/alertCli/CliSender.java
index c6577ae..c9a39e0 100644
--- a/modules/enterprise/server/plugins/alert-cli/src/main/java/org/rhq/enterprise/server/plugins/alertCli/CliSender.java
+++ b/modules/enterprise/server/plugins/alert-cli/src/main/java/org/rhq/enterprise/server/plugins/alertCli/CliSender.java
@@ -46,6 +46,7 @@ import org.rhq.core.domain.alert.Alert;
import org.rhq.core.domain.alert.notification.SenderResult;
import org.rhq.core.domain.auth.Subject;
import org.rhq.core.domain.configuration.PropertySimple;
+import org.rhq.core.domain.content.PackageType;
import org.rhq.core.domain.content.PackageVersion;
import org.rhq.core.domain.content.Repo;
import org.rhq.core.domain.criteria.RepoCriteria;
@@ -55,6 +56,7 @@ import org.rhq.enterprise.server.content.ContentSourceManagerLocal;
import org.rhq.enterprise.server.content.RepoManagerLocal;
import org.rhq.enterprise.server.plugin.pc.ServerPluginComponent;
import org.rhq.enterprise.server.plugin.pc.alert.AlertSender;
+import org.rhq.enterprise.server.plugin.pc.alert.AlertSenderValidationResults;
import org.rhq.enterprise.server.util.LookupUtil;
/**
@@ -135,6 +137,12 @@ public class CliSender extends AlertSender<ServerPluginComponent> {
}
}
+ @Override
+ public AlertSenderValidationResults validateAndFinalizeConfiguration(Subject subject) {
+ // TODO Auto-generated method stub
+ return super.validateAndFinalizeConfiguration(subject);
+ }
+
private static ScriptEngine getScriptEngine(Alert alert, OutputStream scriptOutput, Config config) throws ScriptException,
IOException {
Subject user = config.subject;
commit 3d36341882346ebd89631a1bb953b1d74765018b
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Tue Feb 8 12:52:57 2011 +0100
Hardcode the package type used by CLI alert sender and init it on the plugin load. The repos will be uploaded to any repo user will have access to, so no need for the "uploadRepoName" config.
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerBean.java
index ada868c..fe9c08f 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerBean.java
@@ -1122,6 +1122,25 @@ public class ContentManagerBean implements ContentManagerLocal, ContentManagerRe
return result;
}
+ public PackageType findPackageType(Subject subject, Integer resourceTypeId, String packageTypeName) {
+ Query q = entityManager.createNamedQuery(PackageType.QUERY_FIND_BY_RESOURCE_TYPE_ID_AND_NAME);
+ q.setParameter("typeId", resourceTypeId);
+ q.setParameter("name", packageTypeName);
+
+ @SuppressWarnings("unchecked")
+ List<PackageType> results = (List<PackageType>) q.getResultList();
+
+ if (results.size() == 0) {
+ return null;
+ } else if (results.size() == 1) {
+ return results.get(0);
+ } else {
+ String message = "2 or more package types with name '" + packageTypeName + "' found on the resource type with id " + resourceTypeId + ". This is a bug in the database.";
+ log.error(message);
+ throw new IllegalStateException(message);
+ }
+ }
+
@SuppressWarnings("unchecked")
public void checkForTimedOutRequests(Subject subject) {
if (!authorizationManager.isOverlord(subject)) {
@@ -1604,6 +1623,16 @@ public class ContentManagerBean implements ContentManagerLocal, ContentManagerRe
}
+ public PackageType persistServersidePackageType(PackageType packageType) {
+ if (packageType.getResourceType() != null) {
+ throw new IllegalArgumentException("Server-side package types can't be associated with a resource type.");
+ }
+
+ entityManager.persist(packageType);
+
+ return packageType;
+ }
+
/** Pulls in package bits from the stream. Currently inefficient.
*
* @param packageBitStream
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerLocal.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerLocal.java
index 79cc072..6500b32 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerLocal.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerLocal.java
@@ -337,6 +337,11 @@ public interface ContentManagerLocal {
throws ResourceTypeNotFoundException;
/**
+ * @see {@link ContentManagerRemote#findPackageType(Subject, Integer, String)}
+ */
+ PackageType findPackageType(Subject subject, Integer resourceTypeId, String packageTypeName);
+
+ /**
* @see {@link ContentManagerRemote#findInstalledPackagesByCriteria(Subject, InstalledPackageCriteria)}
*/
PageList<InstalledPackage> findInstalledPackagesByCriteria(Subject subject, InstalledPackageCriteria criteria);
@@ -361,6 +366,20 @@ public interface ContentManagerLocal {
*/
byte[] getPackageBytes(Subject user, int resourceId, int installedPackageId);
+ /**
+ * This method is used to persist new package types that are defined on the server-side
+ * by some kind of plugin.
+ * <p>
+ * Server-side package types are used to identify data stored in the content subsystem
+ * which don't have any agent-side counter-part. Such package types are required to have
+ * the {@link PackageType#getResourceType() resource type} set to null.
+ *
+ * @param packageType the package type to persist
+ * @return the persisted package type
+ * @throws IllegalArgumentException if the supplied package type has non-null resource type
+ */
+ PackageType persistServersidePackageType(PackageType packageType);
+
void writeBlobOutToStream(OutputStream stream, PackageBits bits, boolean closeStreams);
void updateBlobStream(InputStream stream, PackageBits bits, Map<String, String> contentDetails);
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerRemote.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerRemote.java
index b41f434..0a5614a 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerRemote.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerRemote.java
@@ -138,6 +138,25 @@ public interface ContentManagerRemote {
@WebParam(name = "pluginName") String pluginName) throws ResourceTypeNotFoundException;
/**
+ * This re tries to find a package type of given name defined by the resource type
+ * provided.
+ * <p>
+ * The resource type id can be null, in which case only the serverside defined package types
+ * are searched for.
+ *
+ * @param subject the authenticated user
+ * @param resourceTypeId the id of the resource type associated with the package type or null if only server-side package types should be searched for
+ * @param packageTypeName the name of the package type to find
+ * @return
+ */
+ @WebMethod
+ PackageType findPackageType(
+ @WebParam(name = "subject") Subject subject,
+ @WebParam(name = "resourceTypeId") Integer resourceTypeId,
+ @WebParam(name = "packageTypeName") String packageTypeName
+ );
+
+ /**
* @param subject
* @param criteria {@link InstalledPackageCriteria}
* @return InstalledPackages for the criteria
diff --git a/modules/enterprise/server/plugins/alert-cli/src/main/java/org/rhq/enterprise/server/plugins/alertCli/CliComponent.java b/modules/enterprise/server/plugins/alert-cli/src/main/java/org/rhq/enterprise/server/plugins/alertCli/CliComponent.java
index 87cefa2..d11dd3d 100644
--- a/modules/enterprise/server/plugins/alert-cli/src/main/java/org/rhq/enterprise/server/plugins/alertCli/CliComponent.java
+++ b/modules/enterprise/server/plugins/alert-cli/src/main/java/org/rhq/enterprise/server/plugins/alertCli/CliComponent.java
@@ -22,10 +22,8 @@ package org.rhq.enterprise.server.plugins.alertCli;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
-import java.util.HashSet;
import java.util.List;
import java.util.Map;
-import java.util.Set;
import org.rhq.core.domain.alert.AlertDefinition;
import org.rhq.core.domain.alert.notification.AlertNotification;
@@ -35,6 +33,8 @@ import org.rhq.core.domain.configuration.Property;
import org.rhq.core.domain.configuration.PropertyList;
import org.rhq.core.domain.configuration.PropertyMap;
import org.rhq.core.domain.configuration.PropertySimple;
+import org.rhq.core.domain.content.PackageCategory;
+import org.rhq.core.domain.content.PackageType;
import org.rhq.core.domain.criteria.AlertDefinitionCriteria;
import org.rhq.core.domain.resource.composite.DisambiguationReport;
import org.rhq.core.domain.util.DisambiguationReportRenderer;
@@ -43,6 +43,7 @@ import org.rhq.core.util.IntExtractor;
import org.rhq.enterprise.server.alert.AlertDefinitionManagerLocal;
import org.rhq.enterprise.server.alert.AlertNotificationManagerLocal;
import org.rhq.enterprise.server.auth.SubjectManagerLocal;
+import org.rhq.enterprise.server.content.ContentManagerLocal;
import org.rhq.enterprise.server.plugin.pc.ControlFacet;
import org.rhq.enterprise.server.plugin.pc.ControlResults;
import org.rhq.enterprise.server.plugin.pc.ServerPluginComponent;
@@ -58,10 +59,17 @@ import org.rhq.enterprise.server.util.LookupUtil;
*/
public class CliComponent implements ServerPluginComponent, ControlFacet {
+ //TODO the package type definition could be defined somewhere accessible
+ //server-wide if we decide to use it in more places than just this alert sender
+
+ public static final String PACKAGE_TYPE_NAME = "__SERVER_SIDE_CLI_SCRIPT";
+ public static final String PACKAGE_TYPE_DESCRIPTION =
+ "A CLI script running on the server-side.";
+ public static final String PACKAGE_TYPE_DISPLAY_NAME = "Server-side CLI Script";
+
private static final String CONTROL_CHECK_ALERTS_VALIDITY = "checkAlertsValidity";
private static final String CONTROL_REASSIGN_ALERTS = "reassignAlerts";
- private static final String PROP_PACKAGE_TYPES = "packageTypes";
private static final String PROP_ALERT_DEFINITION_NAME = "alertDefinitionName";
private static final String PROP_RESOURCE_PATH = "resourcePath";
private static final String PROP_RESOURCE_ID = "resourceId";
@@ -70,31 +78,37 @@ public class CliComponent implements ServerPluginComponent, ControlFacet {
private static final String PROP_ALERT_DEFINITION_ID = "alertDefinitionId";
private static final String PROP_USER_NAME = "userName";
private static final String PROP_ALERT_DEF_IDS = "alertDefIds";
- private static final String PROP_REPO_NAME = "repoName";
- private Set<String> scriptPackageTypes;
private String pluginName;
- private String repoName;
+ private PackageType packageType;
+
+ private SubjectManagerLocal subjectManager;
public void initialize(ServerPluginContext context) throws Exception {
- scriptPackageTypes = new HashSet<String>();
pluginName = context.getPluginEnvironment().getPluginDescriptor().getName();
- PropertyList packageTypesList = context.getPluginConfiguration().getList(PROP_PACKAGE_TYPES);
- for(Property p : packageTypesList.getList()) {
- PropertySimple value = (PropertySimple) p;
+
+ subjectManager = LookupUtil.getSubjectManager();
+ ContentManagerLocal cm = LookupUtil.getContentManager();
+
+ packageType = cm.findPackageType(subjectManager.getOverlord(), null, PACKAGE_TYPE_NAME);
+
+ if (packageType == null) {
+ packageType = new PackageType(PACKAGE_TYPE_NAME, null);
+ packageType.setCategory(PackageCategory.EXECUTABLE_SCRIPT);
+ packageType.setDescription(PACKAGE_TYPE_DESCRIPTION);
+ packageType.setDisplayName(PACKAGE_TYPE_DISPLAY_NAME);
+ packageType.setSupportsArchitecture(false);
+ packageType.setCreationData(false);
+ packageType.setDeploymentConfigurationDefinition(null);
+ packageType.setDiscoveryInterval(-1);
+ packageType.setPackageExtraPropertiesDefinition(null);
- scriptPackageTypes.add(value.getStringValue());
+ packageType = cm.persistServersidePackageType(packageType);
}
-
- repoName = context.getPluginConfiguration().getSimpleValue(PROP_REPO_NAME, null);
}
- public Set<String> getScriptPackageTypes() {
- return scriptPackageTypes;
- }
-
- public String getRepoName() {
- return repoName;
+ public PackageType getScriptPackageType() {
+ return packageType;
}
public void start() {
diff --git a/modules/enterprise/server/plugins/alert-cli/src/main/resources/META-INF/rhq-serverplugin.xml b/modules/enterprise/server/plugins/alert-cli/src/main/resources/META-INF/rhq-serverplugin.xml
index 43785ff..d893471 100644
--- a/modules/enterprise/server/plugins/alert-cli/src/main/resources/META-INF/rhq-serverplugin.xml
+++ b/modules/enterprise/server/plugins/alert-cli/src/main/resources/META-INF/rhq-serverplugin.xml
@@ -48,26 +48,6 @@
</serverplugin:control>
</serverplugin:plugin-component>
- <serverplugin:plugin-configuration>
- <c:simple-property name="uploadRepoName" displayName="Repo to manually upload scripts to" required="true" default="Uploaded Scripts">
- <c:description>
- When manually uploading a script while defining an alert notification, the script will be stored in this repo.
- </c:description>
- </c:simple-property>
- <c:list-property name="packageTypes" displayName="Package Types" required="true">
- <c:description>
- The list of package types that will be considered scripts. Any package of those types in any repo will be
- considered a script and will be available for choosing as an alert script.
- The package type can be one of those defined by different agent plugins and can be applicable
- to some resource type (i.e. you might use such package type to "stream" the packages down to resources
- on different agents using the content subsystem) but it doesn't have to.
-
- A good choice is something like 'seversideCLIScript'.
- </c:description>
- <c:simple-property name="packageType" displayName="Package Type" type="string" required="true"/>
- </c:list-property>
- </serverplugin:plugin-configuration>
-
<!-- How does this sender show up in drop downs etc -->
<short-name>CLI Script</short-name>
commit 77d256e4479b031d7da07ae164af42b388c5a41f
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Mon Feb 7 10:04:57 2011 +0100
some CLI Alert sender GUI related work
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/PackageCriteria.java b/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/PackageCriteria.java
index 4a7ec19..47bc804 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/PackageCriteria.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/PackageCriteria.java
@@ -77,4 +77,8 @@ public class PackageCriteria extends Criteria {
addSortField("name");
this.sortName = sort;
}
+
+ public boolean isInventoryManagerRequired() {
+ return fetchVersions;
+ }
}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/CliNotificationSenderForm.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/CliNotificationSenderForm.java
index 4c7ac87..c7b7972 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/CliNotificationSenderForm.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/CliNotificationSenderForm.java
@@ -19,18 +19,29 @@
package org.rhq.enterprise.gui.coregui.client.alert.definitions;
+import java.util.LinkedHashMap;
+import java.util.List;
+
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.smartgwt.client.data.Criteria;
+import com.smartgwt.client.widgets.Label;
import com.smartgwt.client.widgets.form.DynamicForm;
+import com.smartgwt.client.widgets.form.fields.SelectItem;
import org.rhq.core.domain.alert.notification.AlertNotification;
import org.rhq.core.domain.auth.Subject;
+import org.rhq.core.domain.content.Package;
import org.rhq.core.domain.content.Repo;
+import org.rhq.core.domain.criteria.PackageCriteria;
import org.rhq.core.domain.criteria.RepoCriteria;
+import org.rhq.core.domain.criteria.SubjectCriteria;
import org.rhq.core.domain.util.PageList;
+import org.rhq.enterprise.gui.coregui.client.components.form.RadioGroupWithComponentsItem;
import org.rhq.enterprise.gui.coregui.client.components.selector.AbstractSelector;
import org.rhq.enterprise.gui.coregui.client.gwt.GWTServiceLookup;
import org.rhq.enterprise.gui.coregui.client.util.RPCDataSource;
+import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableDynamicForm;
+import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableVLayout;
/**
* A form to configure the CLI script alert notification.
@@ -42,10 +53,16 @@ public class CliNotificationSenderForm extends AbstractNotificationSenderForm {
private static final String PROP_PACKAGE_ID = "packageId";
private static final String PROP_REPO_ID = "repoId";
private static final String PROP_USER_ID = "userId";
+
+ boolean formBuilt;
private static class Config {
+ List<Repo> allRepos;
Repo selectedRepo;
+
+ List<Package> allPackages;
Package selectedPackage;
+
Subject selectedSubject;
}
@@ -57,17 +74,66 @@ public class CliNotificationSenderForm extends AbstractNotificationSenderForm {
protected void onInit() {
super.onInit();
+ if (!formBuilt) {
+ LocatableDynamicForm form = new LocatableDynamicForm(extendLocatorId("form"));
+
+ SelectItem repoSelector = new SelectItem("repoSelector", "Repository:"); //TODO i18n
+ repoSelector.setDefaultToFirstOption(false);
+ repoSelector.setWrapTitle(false);
+ repoSelector.setRedrawOnChange(true);
+ repoSelector.setWidth("*");
+ repoSelector.setValueMap(MSG.common_msg_loading());
+ repoSelector.setDisabled(true);
+
+ SelectItem packageSelector = new SelectItem("packageSelector", "Script:"); //TODO i18n
+ packageSelector.setDefaultToFirstOption(false);
+ packageSelector.setWrapTitle(false);
+ packageSelector.setRedrawOnChange(true);
+ packageSelector.setWidth("*");
+ packageSelector.setValueMap(MSG.common_msg_loading());
+ packageSelector.setDisabled(true);
+
+ DynamicForm anotherUserForm = createAnotherUserForm();
+
+ LinkedHashMap<String, DynamicForm> userSelectItems = new LinkedHashMap<String, DynamicForm>();
+
+ userSelectItems.put(MSG.view_alert_definition_notification_cliScript_editor_thisUser(), null);
+ userSelectItems.put(MSG.view_alert_definition_notification_cliScript_editor_anotherUser(), anotherUserForm);
+
+ RadioGroupWithComponentsItem userSelector = new RadioGroupWithComponentsItem(
+ extendLocatorId("userSelector"),
+ MSG.view_alert_definition_notification_cliScript_editor_whichUser(), userSelectItems, form);
+
+ form.setFields(repoSelector, packageSelector, userSelector);
+ addMember(form);
+
+ Config config = loadConfig();
+
+ if (config.selectedRepo != null) {
+
+ }
+
+ formBuilt = true;
+ }
+ }
+
+ public boolean validate() {
+ // TODO implement
+ return false;
+ }
+
+ private Config loadConfig() {
String repoId = getConfiguration().getSimpleValue(PROP_REPO_ID, null);
String packageId = getConfiguration().getSimpleValue(PROP_PACKAGE_ID, null);
- String userId = getConfiguration().getSimpleValue(PROP_USER_ID, null);
+ String subjectId = getConfiguration().getSimpleValue(PROP_USER_ID, null);
final Config config = new Config();
-
+
if (repoId != null && repoId.trim().length() > 0) {
int rid = Integer.parseInt(repoId);
RepoCriteria c = new RepoCriteria();
c.addFilterId(rid);
- GWTServiceLookup.getRepoService().findRepoByCriteria(c, new AsyncCallback<PageList<Repo>>() {
+ GWTServiceLookup.getRepoService().findReposByCriteria(c, new AsyncCallback<PageList<Repo>>() {
public void onSuccess(PageList<Repo> result) {
if (result.size() > 0) {
config.selectedRepo = result.get(0);
@@ -75,76 +141,53 @@ public class CliNotificationSenderForm extends AbstractNotificationSenderForm {
}
public void onFailure(Throwable caught) {
+ //TODO
}
});
}
- RepoSelector repoSelector = new RepoSelector(extendLocatorId("repoSelector"), config.selectedRepo);
- PackageSelector packageSelector = new PackageSelector(extendLocatorId("packageSelector"), config.selectedRepo, config.selectedPackage);
- //TODO UI to select the user.
- }
-
- public boolean validate() {
- // TODO implement
- return false;
- }
-
- private class RepoSelector extends AbstractSelector<Repo> {
-
- private Repo repo;
- /**
- * @param locatorId
- */
- public RepoSelector(String locatorId, Repo preselectedRepo) {
- super(locatorId);
- this.repo = preselectedRepo;
- }
-
- protected DynamicForm getAvailableFilterForm() {
- return null;
- }
-
- protected RPCDataSource<Repo> getDataSource() {
- return null;
- }
-
- protected Criteria getLatestCriteria(DynamicForm availableFilterForm) {
- return null;
+ if (packageId != null && packageId.trim().length() > 0) {
+ int pid = Integer.parseInt(packageId);
+ PackageCriteria c = new PackageCriteria();
+ c.addFilterId(pid);
+
+ GWTServiceLookup.getContentService().findPackagesByCriteria(c, new AsyncCallback<PageList<Package>>() {
+ public void onSuccess(PageList<Package> result) {
+ if (result.size() > 0) {
+ config.selectedPackage = result.get(0);
+ }
+ }
+
+ public void onFailure(Throwable caught) {
+ //TODO
+ }
+ });
}
-
- protected String getItemTitle() {
- return null;
+
+ if (subjectId != null && subjectId.trim().length() > 0) {
+ int sid = Integer.parseInt(subjectId);
+ SubjectCriteria c = new SubjectCriteria();
+ c.addFilterId(sid);
+
+ GWTServiceLookup.getSubjectService().findSubjectsByCriteria(c, new AsyncCallback<PageList<Subject>>() {
+ public void onSuccess(PageList<Subject> result) {
+ if (result.size() > 0) {
+ config.selectedSubject = result.get(0);
+ }
+ }
+
+ public void onFailure(Throwable caught) {
+ //TODO
+ }
+ });
}
+
+ return config;
}
- private class PackageSelector extends AbstractSelector<Package> {
-
- private Repo repoFilter;
+ DynamicForm createAnotherUserForm() {
+ LocatableDynamicForm form = new LocatableDynamicForm(extendLocatorId("anotherUserForm"));
- /**
- * @param locatorId
- */
- public PackageSelector(String locatorId, Repo preselectedRepo, Package preselectedPackage) {
- super(locatorId);
- this.repoFilter = preselectedRepo;
- //TODO implement
- }
-
- protected DynamicForm getAvailableFilterForm() {
- return null;
- }
-
- protected RPCDataSource<Package> getDataSource() {
- return null;
- }
-
- protected Criteria getLatestCriteria(DynamicForm availableFilterForm) {
- return null;
- }
-
- protected String getItemTitle() {
- // TODO Auto-generated method stub
- return null;
- }
+ return form;
}
-}
+}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/NewNotificationEditor.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/NewNotificationEditor.java
index bcea118..6e4b043 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/NewNotificationEditor.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/NewNotificationEditor.java
@@ -246,6 +246,8 @@ public class NewNotificationEditor extends LocatableDynamicForm {
rt = res.getResourceType();
}
newCanvas = new ResourceOperationNotificationSenderForm(newLocatorId, notificationToEdit, sender, rt, res);
+ } else if ("CLI Script".equals(sender)) {
+ newCanvas = new CliNotificationSenderForm(newLocatorId, notificationToEdit, sender);
} else {
// catch all - all other senders are assumed to just have simple configuration definition
// that can be used by our configuration editor UI component to ask for config values.
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/ContentGWTService.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/ContentGWTService.java
index 7cd0f55..b4acc31 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/ContentGWTService.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/ContentGWTService.java
@@ -28,8 +28,10 @@ import com.google.gwt.user.client.rpc.RemoteService;
import org.rhq.core.domain.content.Architecture;
import org.rhq.core.domain.content.InstalledPackageHistory;
+import org.rhq.core.domain.content.Package;
import org.rhq.core.domain.content.PackageType;
import org.rhq.core.domain.content.PackageVersion;
+import org.rhq.core.domain.criteria.PackageCriteria;
import org.rhq.core.domain.criteria.PackageVersionCriteria;
import org.rhq.core.domain.util.PageList;
@@ -42,6 +44,8 @@ public interface ContentGWTService extends RemoteService {
PageList<PackageVersion> findPackageVersionsByCriteria(PackageVersionCriteria criteria) throws RuntimeException;
+ PageList<Package> findPackagesByCriteria(PackageCriteria criteria);
+
PageList<InstalledPackageHistory> getInstalledPackageHistoryForResource(int resourceId, int count);
List<Architecture> getArchitectures() throws RuntimeException;
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/ContentGWTServiceImpl.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/ContentGWTServiceImpl.java
index caee06b..82f4e85 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/ContentGWTServiceImpl.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/ContentGWTServiceImpl.java
@@ -26,8 +26,10 @@ import java.util.List;
import org.rhq.core.domain.content.Architecture;
import org.rhq.core.domain.content.InstalledPackageHistory;
+import org.rhq.core.domain.content.Package;
import org.rhq.core.domain.content.PackageType;
import org.rhq.core.domain.content.PackageVersion;
+import org.rhq.core.domain.criteria.PackageCriteria;
import org.rhq.core.domain.criteria.PackageVersionCriteria;
import org.rhq.core.domain.util.PageControl;
import org.rhq.core.domain.util.PageList;
@@ -68,6 +70,15 @@ public class ContentGWTServiceImpl extends AbstractGWTServiceImpl implements Con
}
}
+ public PageList<Package> findPackagesByCriteria(PackageCriteria criteria) {
+ try {
+ return SerialUtility.prepare(contentManager.findPackagesByCriteria(getSessionSubject(), criteria),
+ "ContentService.findPackagesByCriteria");
+ } catch (Throwable t) {
+ throw new RuntimeException(ThrowableUtil.getAllMessages(t));
+ }
+ }
+
public PageList<InstalledPackageHistory> getInstalledPackageHistoryForResource(int resourceId, int count)
throws RuntimeException {
try {
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 cd939a9..104636d 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
@@ -797,6 +797,9 @@ view_alert_definition_notification_role_editor_saveFailed = Cannot save the sele
view_alert_definition_notification_user_editor_loadFailed = Cannot determine current users - starting empty
view_alert_definition_notification_user_editor_restoreFailed = Cannot use current users - starting empty
view_alert_definition_notification_user_editor_saveFailed = Cannot save the selected users
+view_alert_definition_notification_cliScript_editor_whichUser = User to run the script as
+view_alert_definition_notification_cliScript_editor_thisUser = Myself
+view_alert_definition_notification_cliScript_editor_anotherUser = Another user
view_alert_definition_recovery_editor_disable_when_fired = Disable When Fired
view_alert_definition_recovery_editor_disable_when_fired_tooltip = Indicates if this alert will be disabled after it fires. Once disabled, the alert can be manually re-enabled or a recovery alert can be set up to automatically re-enable it. If this alert is a recovery alert itself, this setting cannot be turned on.
view_alert_definition_recovery_editor_recovery_alert = Recover Alert
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerBean.java
index 4052693..ada868c 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerBean.java
@@ -85,6 +85,7 @@ import org.rhq.core.domain.content.transfer.RemoveIndividualPackageResponse;
import org.rhq.core.domain.content.transfer.RemovePackagesResponse;
import org.rhq.core.domain.content.transfer.ResourcePackageDetails;
import org.rhq.core.domain.criteria.InstalledPackageCriteria;
+import org.rhq.core.domain.criteria.PackageCriteria;
import org.rhq.core.domain.criteria.PackageVersionCriteria;
import org.rhq.core.domain.resource.Agent;
import org.rhq.core.domain.resource.Resource;
@@ -1490,6 +1491,20 @@ public class ContentManagerBean implements ContentManagerLocal, ContentManagerRe
return queryRunner.execute();
}
+ public PageList<Package> findPackagesByCriteria(Subject subject, PackageCriteria criteria) {
+
+ if (criteria.isInventoryManagerRequired() && !authorizationManager.isInventoryManager(subject)) {
+ throw new PermissionException("Subject [" + subject.getName()
+ + "] is required to have InventoryManager permission for requested query criteria.");
+ }
+
+ CriteriaQueryGenerator generator = new CriteriaQueryGenerator(subject, criteria);
+
+ CriteriaQueryRunner<Package> runner = new CriteriaQueryRunner<Package>(criteria, generator, entityManager);
+
+ return runner.execute();
+ }
+
public InstalledPackage getBackingPackageForResource(Subject subject, int resourceId) {
InstalledPackage result = null;
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerLocal.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerLocal.java
index 819709c..79cc072 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerLocal.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerLocal.java
@@ -42,6 +42,7 @@ import org.rhq.core.domain.content.transfer.DeployPackagesResponse;
import org.rhq.core.domain.content.transfer.RemovePackagesResponse;
import org.rhq.core.domain.content.transfer.ResourcePackageDetails;
import org.rhq.core.domain.criteria.InstalledPackageCriteria;
+import org.rhq.core.domain.criteria.PackageCriteria;
import org.rhq.core.domain.criteria.PackageVersionCriteria;
import org.rhq.core.domain.util.PageList;
import org.rhq.enterprise.server.resource.ResourceTypeNotFoundException;
@@ -346,6 +347,11 @@ public interface ContentManagerLocal {
PageList<PackageVersion> findPackageVersionsByCriteria(Subject subject, PackageVersionCriteria criteria);
/**
+ * @see ContentManagerRemote#findPackagesByCriteria(Subject, PackageCriteria)
+ */
+ PageList<Package> findPackagesByCriteria(Subject subject, PackageCriteria criteria);
+
+ /**
* @see {@link ContentManagerRemote#getBackingPackageForResource(Subject, int)
*/
InstalledPackage getBackingPackageForResource(Subject subject, int resourceId);
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerRemote.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerRemote.java
index 1190cc6..b41f434 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerRemote.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerRemote.java
@@ -29,6 +29,7 @@ import javax.jws.soap.SOAPBinding;
import org.rhq.core.domain.auth.Subject;
import org.rhq.core.domain.content.Architecture;
import org.rhq.core.domain.content.InstalledPackage;
+import org.rhq.core.domain.content.Package;
import org.rhq.core.domain.content.PackageType;
import org.rhq.core.domain.content.PackageVersion;
import org.rhq.core.domain.criteria.InstalledPackageCriteria;
@@ -166,6 +167,7 @@ public interface ContentManagerRemote {
* versions via {@link PackageCriteria#fetchVersions(boolean)}. There are no privileges required
* if only a list of packages without their associated package versions is requested.
* <p>
+ * TODO the privileges need to be worked out for this...
*
* @param subject
* @param criteria
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/RepoManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/RepoManagerBean.java
index 985c3e7..852c472 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/RepoManagerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/RepoManagerBean.java
@@ -325,6 +325,11 @@ public class RepoManagerBean implements RepoManagerLocal, RepoManagerRemote {
}
@RequiredPermission(Permission.MANAGE_INVENTORY)
+ public PackageVersion getLatestPackageVersion(Subject subject, int packageId, int repoId) {
+ return getLatestPackageVersion(subject, packageId, repoId, null);
+ }
+
+ @RequiredPermission(Permission.MANAGE_INVENTORY)
public PackageVersion getLatestPackageVersion(Subject subject, int packageId, int repoId, Comparator<PackageVersion> versionComparator) {
if (versionComparator == null) {
Query pvcsQ = entityManager.createNamedQuery(PackageVersionContentSource.QUERY_FIND_BY_PACKAGE_AND_REPO_ID_NO_FETCH);
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/RepoManagerLocal.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/RepoManagerLocal.java
index e5b8a38..640bee3 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/RepoManagerLocal.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/RepoManagerLocal.java
@@ -110,11 +110,19 @@ public interface RepoManagerLocal {
PageList<PackageVersion> findPackageVersionsInRepo(Subject subject, int repoId, String filter, PageControl pc);
/**
- * @see RepoManagerRemote#getLatestPackageVersion(Subject, int, int, Comparator)
+ * @see RepoManagerRemote#getLatestPackageVersion(Subject, int, int)
*/
- PackageVersion getLatestPackageVersion(Subject subject, int packageId, int repoId, Comparator<PackageVersion> versionComparator);
+ PackageVersion getLatestPackageVersion(Subject subject, int packageId, int repoId);
/**
+ * This is an enhanced version of the remoted method that is able to override the default
+ * package version comparator.
+ *
+ * @see RepoManagerRemote#getLatestPackageVersion(Subject, int, int)
+ */
+ PackageVersion getLatestPackageVersion(Subject subject, int packageId, int repoId, Comparator<PackageVersion> versionComparator);
+
+ /**
* Get the overall sync status of this Repository. This is a summation of all the syncs.
*
* There is a weight to the status since this returns the most 'relevant' status:
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/RepoManagerRemote.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/RepoManagerRemote.java
index 66d3b2f..99c4ca0 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/RepoManagerRemote.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/RepoManagerRemote.java
@@ -132,27 +132,24 @@ public interface RepoManagerRemote {
@WebParam(name = "criteria") PackageVersionCriteria criteria);
/**
- * Returns the latest package version of the supplied package as deemed by the supplied comparator.
- * The supplied comparator is taken as an override to the default one to use.
- * The default comparator is determined using the following algorithm:
+ * Returns the latest package version of the supplied package.
+ * The latest version is determined using a comparator which is found using the following rules:
* <ol>
* <li>Find the first content provider defining the package connected to given repo
- * that defines a non-null comparator and return that
+ * that defines a non-null version comparator
* <li>If no content provider provides explicit comparator, use {@link PackageVersion#DEFAULT_COMPARATOR}
* </ol>
*
* @param subject the authenticated user
* @param packageId the id of the package to find the latest version for.
* @param repoId the repo where to take the package versions of the package from
- * @param versionComparator if left null, the comparator to use is determined by the rules above
* @return
*/
@WebMethod
PackageVersion getLatestPackageVersion(
@WebParam(name = "subject") Subject subject,
@WebParam(name = "packageId") int packageId,
- @WebParam(name = "repoId") int repoId,
- @WebParam(name = "versionComparator") Comparator<PackageVersion> versionComparator);
+ @WebParam(name = "repoId") int repoId);
/**
* Update an existing {@link Repo} object's basic fields, like name, description, etc. Note that the given <code>
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/webservices/WebservicesManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/webservices/WebservicesManagerBean.java
index 27d06d3..3988901 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/webservices/WebservicesManagerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/webservices/WebservicesManagerBean.java
@@ -63,6 +63,7 @@ import org.rhq.core.domain.configuration.group.GroupPluginConfigurationUpdate;
import org.rhq.core.domain.configuration.group.GroupResourceConfigurationUpdate;
import org.rhq.core.domain.content.Architecture;
import org.rhq.core.domain.content.InstalledPackage;
+import org.rhq.core.domain.content.Package;
import org.rhq.core.domain.content.PackageType;
import org.rhq.core.domain.content.PackageVersion;
import org.rhq.core.domain.content.Repo;
@@ -83,6 +84,7 @@ import org.rhq.core.domain.criteria.MeasurementDataTraitCriteria;
import org.rhq.core.domain.criteria.MeasurementDefinitionCriteria;
import org.rhq.core.domain.criteria.MeasurementScheduleCriteria;
import org.rhq.core.domain.criteria.OperationDefinitionCriteria;
+import org.rhq.core.domain.criteria.PackageCriteria;
import org.rhq.core.domain.criteria.PackageVersionCriteria;
import org.rhq.core.domain.criteria.RepoCriteria;
import org.rhq.core.domain.criteria.ResourceCriteria;
@@ -518,6 +520,11 @@ public class WebservicesManagerBean implements WebservicesRemote {
return contentManager.getPackageBytes(subject, resourceId, installedPackageId);
}
+ public PageList<Package> findPackagesByCriteria(Subject subject, PackageCriteria criteria) {
+ checkParametersPassedIn(subject, criteria);
+ return contentManager.findPackagesByCriteria(subject, criteria);
+ }
+
//CONTENTMANAGER: END ----------------------------------
// //DATAACCESSMANAGER: BEGIN ----------------------------------
@@ -780,9 +787,8 @@ public class WebservicesManagerBean implements WebservicesRemote {
return repoManager.findPackageVersionsInRepoByCriteria(subject, criteria);
}
- public PackageVersion getLatestPackageVersion(Subject subject, int packageId, int repoId,
- Comparator<PackageVersion> versionComparator) {
- return repoManager.getLatestPackageVersion(subject, packageId, repoId, versionComparator);
+ public PackageVersion getLatestPackageVersion(Subject subject, int packageId, int repoId) {
+ return repoManager.getLatestPackageVersion(subject, packageId, repoId);
}
public PageList<Resource> findSubscribedResources(Subject subject, int repoId, PageControl pc) {
diff --git a/modules/enterprise/server/plugins/alert-cli/src/main/java/org/rhq/enterprise/server/plugins/alertCli/CliSender.java b/modules/enterprise/server/plugins/alert-cli/src/main/java/org/rhq/enterprise/server/plugins/alertCli/CliSender.java
index 6d7f30c..c6577ae 100644
--- a/modules/enterprise/server/plugins/alert-cli/src/main/java/org/rhq/enterprise/server/plugins/alertCli/CliSender.java
+++ b/modules/enterprise/server/plugins/alert-cli/src/main/java/org/rhq/enterprise/server/plugins/alertCli/CliSender.java
@@ -205,13 +205,12 @@ public class CliSender extends AlertSender<ServerPluginComponent> {
//now get the package and repo info
Subject overlord = LookupUtil.getSubjectManager().getOverlord();
RepoManagerLocal rm = LookupUtil.getRepoManagerLocal();
- PackageVersion versionToUse = rm.getLatestPackageVersion(overlord, config.packageId, config.repoId, null);
+ PackageVersion versionToUse = rm.getLatestPackageVersion(overlord, config.packageId, config.repoId);
ret = ret.replace("$packageName", versionToUse.getDisplayName());
ret = ret.replace("$pacakgeVersion", versionToUse.getDisplayVersion() == null ? versionToUse.getVersion()
: versionToUse.getDisplayVersion());
- RepoManagerLocal rm = LookupUtil.getRepoManagerLocal();
RepoCriteria criteria = new RepoCriteria();
criteria.addFilterId(config.repoId);
commit f80597412f4ec9ccaf7eadc877577ae136aacf50
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Thu Feb 3 09:58:47 2011 +0100
start of the CLI alert def UI, package criteria object. This doesn't even compile and will have to wait until more elaborate privileges are implemented.
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/PackageCriteria.java b/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/PackageCriteria.java
new file mode 100644
index 0000000..4a7ec19
--- /dev/null
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/PackageCriteria.java
@@ -0,0 +1,80 @@
+/*
+ * 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 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.core.domain.criteria;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+
+import org.rhq.core.domain.content.Package;
+import org.rhq.core.domain.util.PageOrdering;
+
+/**
+ * Criteria object for querying {@link Package}s.
+ *
+ * @author Lukas Krejci
+ */
+(a)XmlAccessorType(XmlAccessType.FIELD)
+@SuppressWarnings("unused")
+public class PackageCriteria extends Criteria {
+
+ private static final long serialVersionUID = 1L;
+
+ private Integer filterId;
+ private String filterName;
+ private String filterClassification;
+ private Integer filterPackageTypeId;
+
+ private boolean fetchVersions;
+
+ private PageOrdering sortName;
+
+ public PackageCriteria() {
+ filterOverrides.put("packageTypeId", "packageType.id = ? ");
+ }
+
+ public Class<?> getPersistentClass() {
+ return Package.class;
+ }
+
+ public void addFilterId(Integer id) {
+ this.filterId = id;
+ }
+
+ public void addFilterName(String name) {
+ this.filterName = name;
+ }
+
+ public void addFilterClassification(String classification) {
+ this.filterClassification = classification;
+ }
+
+ public void addFilterPackageTypeId(Integer packageTypeId) {
+ this.filterPackageTypeId = packageTypeId;
+ }
+
+ public void fetchVersions(boolean fetchVersions) {
+ this.fetchVersions = fetchVersions;
+ }
+
+ public void addSortName(PageOrdering sort) {
+ addSortField("name");
+ this.sortName = sort;
+ }
+}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/CliNotificationSenderForm.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/CliNotificationSenderForm.java
new file mode 100644
index 0000000..4c7ac87
--- /dev/null
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/CliNotificationSenderForm.java
@@ -0,0 +1,150 @@
+/*
+ * 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 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.alert.definitions;
+
+import com.google.gwt.user.client.rpc.AsyncCallback;
+import com.smartgwt.client.data.Criteria;
+import com.smartgwt.client.widgets.form.DynamicForm;
+
+import org.rhq.core.domain.alert.notification.AlertNotification;
+import org.rhq.core.domain.auth.Subject;
+import org.rhq.core.domain.content.Repo;
+import org.rhq.core.domain.criteria.RepoCriteria;
+import org.rhq.core.domain.util.PageList;
+import org.rhq.enterprise.gui.coregui.client.components.selector.AbstractSelector;
+import org.rhq.enterprise.gui.coregui.client.gwt.GWTServiceLookup;
+import org.rhq.enterprise.gui.coregui.client.util.RPCDataSource;
+
+/**
+ * A form to configure the CLI script alert notification.
+ *
+ * @author Lukas Krejci
+ */
+public class CliNotificationSenderForm extends AbstractNotificationSenderForm {
+
+ private static final String PROP_PACKAGE_ID = "packageId";
+ private static final String PROP_REPO_ID = "repoId";
+ private static final String PROP_USER_ID = "userId";
+
+ private static class Config {
+ Repo selectedRepo;
+ Package selectedPackage;
+ Subject selectedSubject;
+ }
+
+ public CliNotificationSenderForm(String locatorId, AlertNotification notif, String sender) {
+ super(locatorId, notif, sender);
+ }
+
+ @Override
+ protected void onInit() {
+ super.onInit();
+
+ String repoId = getConfiguration().getSimpleValue(PROP_REPO_ID, null);
+ String packageId = getConfiguration().getSimpleValue(PROP_PACKAGE_ID, null);
+ String userId = getConfiguration().getSimpleValue(PROP_USER_ID, null);
+
+ final Config config = new Config();
+
+ if (repoId != null && repoId.trim().length() > 0) {
+ int rid = Integer.parseInt(repoId);
+ RepoCriteria c = new RepoCriteria();
+ c.addFilterId(rid);
+ GWTServiceLookup.getRepoService().findRepoByCriteria(c, new AsyncCallback<PageList<Repo>>() {
+ public void onSuccess(PageList<Repo> result) {
+ if (result.size() > 0) {
+ config.selectedRepo = result.get(0);
+ }
+ }
+
+ public void onFailure(Throwable caught) {
+ }
+ });
+ }
+
+ RepoSelector repoSelector = new RepoSelector(extendLocatorId("repoSelector"), config.selectedRepo);
+ PackageSelector packageSelector = new PackageSelector(extendLocatorId("packageSelector"), config.selectedRepo, config.selectedPackage);
+ //TODO UI to select the user.
+ }
+
+ public boolean validate() {
+ // TODO implement
+ return false;
+ }
+
+ private class RepoSelector extends AbstractSelector<Repo> {
+
+ private Repo repo;
+ /**
+ * @param locatorId
+ */
+ public RepoSelector(String locatorId, Repo preselectedRepo) {
+ super(locatorId);
+ this.repo = preselectedRepo;
+ }
+
+ protected DynamicForm getAvailableFilterForm() {
+ return null;
+ }
+
+ protected RPCDataSource<Repo> getDataSource() {
+ return null;
+ }
+
+ protected Criteria getLatestCriteria(DynamicForm availableFilterForm) {
+ return null;
+ }
+
+ protected String getItemTitle() {
+ return null;
+ }
+ }
+
+ private class PackageSelector extends AbstractSelector<Package> {
+
+ private Repo repoFilter;
+
+ /**
+ * @param locatorId
+ */
+ public PackageSelector(String locatorId, Repo preselectedRepo, Package preselectedPackage) {
+ super(locatorId);
+ this.repoFilter = preselectedRepo;
+ //TODO implement
+ }
+
+ protected DynamicForm getAvailableFilterForm() {
+ return null;
+ }
+
+ protected RPCDataSource<Package> getDataSource() {
+ return null;
+ }
+
+ protected Criteria getLatestCriteria(DynamicForm availableFilterForm) {
+ return null;
+ }
+
+ protected String getItemTitle() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+ }
+}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerRemote.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerRemote.java
index 724a1ef..1190cc6 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerRemote.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerRemote.java
@@ -32,6 +32,7 @@ import org.rhq.core.domain.content.InstalledPackage;
import org.rhq.core.domain.content.PackageType;
import org.rhq.core.domain.content.PackageVersion;
import org.rhq.core.domain.criteria.InstalledPackageCriteria;
+import org.rhq.core.domain.criteria.PackageCriteria;
import org.rhq.core.domain.criteria.PackageVersionCriteria;
import org.rhq.core.domain.util.PageList;
import org.rhq.enterprise.server.resource.ResourceTypeNotFoundException;
@@ -161,6 +162,21 @@ public interface ContentManagerRemote {
@WebParam(name = "criteria") PackageVersionCriteria criteria);
/**
+ * This method requires InventoryManager permissions if the criteria is set up to fetch the package
+ * versions via {@link PackageCriteria#fetchVersions(boolean)}. There are no privileges required
+ * if only a list of packages without their associated package versions is requested.
+ * <p>
+ *
+ * @param subject
+ * @param criteria
+ * @return
+ */
+ @WebMethod
+ PageList<Package> findPackagesByCriteria(
+ @WebParam(name = "subject") Subject subject,
+ @WebParam(name = "criteria") PackageCriteria criteria);
+
+ /**
* For a resource that is content-backed (aka package-backed), this call will return InstalledPackage information
* for the backing content (package).
*
commit d5beb73759a02a407a609856c4c641c0ff6fd9c2
Merge: 609091a... c37617a...
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Wed Feb 2 10:00:02 2011 +0100
Merge remote branch 'origin/master' into cli-alert-notifs
commit 609091aa7ba91f773512c3603c663702659885c5
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Tue Feb 1 17:46:49 2011 +0100
Adding support for meaningful SenderResult and configuration preview, adding repoId as the required parameter to the CLI alert script so that it is clear what repo should be used to get the package from.
This brought with it some reshuffling in the server APIs (just to have a "meaningful" SLSB define the needed methods).
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/content/PackageVersion.java b/modules/core/domain/src/main/java/org/rhq/core/domain/content/PackageVersion.java
index 8b7735d..ba30f9a 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/content/PackageVersion.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/content/PackageVersion.java
@@ -240,8 +240,12 @@ import org.rhq.core.domain.util.OSGiVersionComparator;
@NamedQuery(name = PackageVersion.QUERY_FIND_BY_ID, query = "SELECT pv FROM PackageVersion pv WHERE pv.id = :id"),
@NamedQuery(name = PackageVersion.QUERY_FIND_PACKAGE_BY_FILENAME, query = "SELECT p FROM Package p "
+ "WHERE p.id IN (SELECT pv.generalPackage.id FROM PackageVersion AS pv WHERE pv.fileName = :rpmName)"),
- @NamedQuery(name = PackageVersion.QUERY_FIND_PACKAGEVERSION_BY_FILENAME, query = "SELECT pv FROM PackageVersion AS pv WHERE pv.fileName = :rpmName)")
-
+ @NamedQuery(name = PackageVersion.QUERY_FIND_PACKAGEVERSION_BY_FILENAME, query = "SELECT pv FROM PackageVersion AS pv WHERE pv.fileName = :rpmName)"),
+ @NamedQuery(name = PackageVersion.QUERY_FIND_BY_PACKAGE_AND_REPO_ID, query = "SELECT pv"
+ + " FROM PackageVersion pv"
+ + " JOIN pv.repoPackageVersions rpv"
+ + " WHERE pv.generalPackage.id = :packageId"
+ + " AND rpv.repo.id = :repoId")
})
@SequenceGenerator(name = "SEQ", sequenceName = "RHQ_PACKAGE_VERSION_ID_SEQ")
@Table(name = "RHQ_PACKAGE_VERSION")
@@ -260,6 +264,7 @@ public class PackageVersion implements Serializable {
public static final String QUERY_FIND_BY_REPO_ID = "PackageVersion.findByRepoId";
public static final String QUERY_FIND_BY_REPO_ID_FILTERED = "PackageVersion.findByRepoIdFiltered";
public static final String QUERY_FIND_BY_PACKAGE_ID = "PackageVersion.findByPackageId";
+ public static final String QUERY_FIND_BY_PACKAGE_AND_REPO_ID = "PackageVersion.findByPackageAndRepoId";
public static final String QUERY_FIND_BY_REPO_ID_WITH_PACKAGE = "PackageVersion.findByRepoIdWithPackage";
public static final String QUERY_FIND_BY_REPO_ID_WITH_PACKAGE_FILTERED = "PackageVersion.findByRepoIdWithPackageFiltered";
public static final String QUERY_FIND_METADATA_BY_RESOURCE_ID = "PackageVersion.findMetadataByResourceId";
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/content/PackageVersionContentSource.java b/modules/core/domain/src/main/java/org/rhq/core/domain/content/PackageVersionContentSource.java
index 1120774..04607ee 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/content/PackageVersionContentSource.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/content/PackageVersionContentSource.java
@@ -45,6 +45,11 @@ import javax.persistence.Table;
+ " FROM PackageVersionContentSource pvcs " + " WHERE pvcs.contentSource.id = :id "),
@NamedQuery(name = PackageVersionContentSource.QUERY_FIND_BY_PACKAGE_VERSION_ID_NO_FETCH, query = "SELECT pvcs "
+ " FROM PackageVersionContentSource pvcs WHERE pvcs.packageVersion.id = :id"),
+ @NamedQuery(name = PackageVersionContentSource.QUERY_FIND_BY_PACKAGE_AND_REPO_ID_NO_FETCH, query = "SELECT pvcs "
+ + " FROM PackageVersionContentSource pvcs"
+ + " JOIN pvcs.packageVersion.repoPackageVersions rpv"
+ + " WHERE pvcs.packageVersion.generalPackage.id = :package_id"
+ + " AND rpv.repo.id = :repo_id"),
@NamedQuery(name = PackageVersionContentSource.QUERY_FIND_BY_CONTENT_SOURCE_ID, query = "SELECT pvcs "
+ " FROM PackageVersionContentSource pvcs " //
+ " LEFT JOIN FETCH pvcs.packageVersion pv " //
@@ -116,6 +121,7 @@ public class PackageVersionContentSource implements Serializable {
public static final String QUERY_FIND_BY_PKG_VER_ID_AND_RES_ID = "PackageVersionContentSource.findByPkgVerIdAndResId";
public static final String DELETE_BY_CONTENT_SOURCE_ID = "PackageVersionContentSource.deleteByContentSourceId";
public static final String QUERY_FIND_BY_PACKAGE_VERSION_ID_NO_FETCH = "PackageVersionContentSource.findByPackageVersionIdNoFetch";
+ public static final String QUERY_FIND_BY_PACKAGE_AND_REPO_ID_NO_FETCH = "PackageVersionContentSource.findByPackageAndRepoId";
private static final long serialVersionUID = 1L;
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentSourceManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentSourceManagerBean.java
index a9fae13..225d562 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentSourceManagerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentSourceManagerBean.java
@@ -950,51 +950,6 @@ public class ContentSourceManagerBean implements ContentSourceManagerLocal {
return packageBits;
}
- public PackageVersion getLatestPackageVersion(int packageId, Comparator<PackageVersion> versionComparator) {
- if (versionComparator == null) {
- Query pvcsQ = entityManager.createNamedQuery(PackageVersionContentSource.QUERY_FIND_BY_PACKAGE_VERSION_ID_NO_FETCH);
-
- @SuppressWarnings("unchecked")
- List<PackageVersionContentSource> pvcss = (List<PackageVersionContentSource>) pvcsQ.getResultList();
-
- try {
- ContentProviderManager manager = ContentManagerHelper.getPluginContainer().getAdapterManager();
- for(PackageVersionContentSource pvcs : pvcss) {
- ContentProvider provider = manager.getIsolatedContentProvider(pvcs.getPackageVersionContentSourcePK().getContentSource().getId());
-
- if (provider instanceof PackageSource) {
- versionComparator = ((PackageSource)provider).getPackageVersionComparator();
-
- if (versionComparator != null) {
- //ok, we found one non-default, let's go with that.
- break;
- }
- }
- }
- } catch (Exception e) {
- log.warn("Searching package sources for a version comparator failed. Will use the default comparator.", e);
- }
-
- if (versionComparator == null) {
- versionComparator = PackageVersion.DEFAULT_COMPARATOR;
- }
- }
-
- Query q = entityManager.createNamedQuery(PackageVersion.QUERY_FIND_BY_PACKAGE_ID);
-
- @SuppressWarnings("unchecked")
- List<PackageVersion> results = (List<PackageVersion>) q.getResultList();
-
- if (results.size() > 0) {
- Comparator<PackageVersion> descending = Collections.reverseOrder(versionComparator);
- Collections.sort(results, descending);
-
- return results.get(0);
- }
-
- return null;
- }
-
/**
* This creates a new PackageBits entity initialized to EMPTY_BLOB for the associated PackageBitsBlob.
* Note that PackageBits and PackageBitsBlob are two entities that *share* the same db row. This is
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentSourceManagerLocal.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentSourceManagerLocal.java
index fa87526..726d2d1 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentSourceManagerLocal.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentSourceManagerLocal.java
@@ -633,20 +633,5 @@ public interface ContentSourceManagerLocal {
* @throws ContentSourceException if the content source cannot be created, such as if the data in
* the given object are not valid
*/
- ContentSource simpleCreateContentSource(Subject subject, ContentSource contentSource) throws ContentSourceException;
-
- /**
- * Returns the latest package version of the supplied package as deemed by the supplied comparator.
- * The supplied comparator is taken as an override to the default one to use.
- * The default comparator is determined using the following algorithm:
- * <ol>
- * <li>Find the first content provider defining the package that defines a non-null comparator and return that
- * <li>If no content provider provides explicit comparator, use {@link PackageVersion#DEFAULT_COMPARATOR}
- * </ol>
- *
- * @param packageId the id of the package to find the latest version for.
- * @param versionComparator if left null, the comparator to use is determined by the rules above
- * @return
- */
- PackageVersion getLatestPackageVersion(int packageId, Comparator<PackageVersion> versionComparator);
+ ContentSource simpleCreateContentSource(Subject subject, ContentSource contentSource) throws ContentSourceException;
}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/RepoManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/RepoManagerBean.java
index e7f2527..985c3e7 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/RepoManagerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/RepoManagerBean.java
@@ -20,7 +20,10 @@ package org.rhq.enterprise.server.content;
import java.text.ParseException;
import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
import java.util.HashSet;
+import java.util.Iterator;
import java.util.List;
import java.util.Set;
@@ -74,8 +77,10 @@ import org.rhq.enterprise.server.auth.SubjectManagerLocal;
import org.rhq.enterprise.server.authz.AuthorizationManagerLocal;
import org.rhq.enterprise.server.authz.PermissionException;
import org.rhq.enterprise.server.authz.RequiredPermission;
+import org.rhq.enterprise.server.plugin.pc.content.ContentProvider;
import org.rhq.enterprise.server.plugin.pc.content.ContentProviderManager;
import org.rhq.enterprise.server.plugin.pc.content.ContentServerPluginContainer;
+import org.rhq.enterprise.server.plugin.pc.content.PackageSource;
import org.rhq.enterprise.server.plugin.pc.content.RepoDetails;
import org.rhq.enterprise.server.plugin.pc.content.RepoGroupDetails;
import org.rhq.enterprise.server.plugin.pc.content.RepoImportReport;
@@ -320,6 +325,71 @@ public class RepoManagerBean implements RepoManagerLocal, RepoManagerRemote {
}
@RequiredPermission(Permission.MANAGE_INVENTORY)
+ public PackageVersion getLatestPackageVersion(Subject subject, int packageId, int repoId, Comparator<PackageVersion> versionComparator) {
+ if (versionComparator == null) {
+ Query pvcsQ = entityManager.createNamedQuery(PackageVersionContentSource.QUERY_FIND_BY_PACKAGE_AND_REPO_ID_NO_FETCH);
+ pvcsQ.setParameter("package_id", packageId);
+ pvcsQ.setParameter("repo_id", repoId);
+
+ @SuppressWarnings("unchecked")
+ List<PackageVersionContentSource> pvcss = (List<PackageVersionContentSource>) pvcsQ.getResultList();
+
+ try {
+ ContentProviderManager manager = ContentManagerHelper.getPluginContainer().getAdapterManager();
+ for(PackageVersionContentSource pvcs : pvcss) {
+ ContentProvider provider = manager.getIsolatedContentProvider(pvcs.getPackageVersionContentSourcePK().getContentSource().getId());
+
+ if (provider instanceof PackageSource) {
+ versionComparator = ((PackageSource)provider).getPackageVersionComparator();
+
+ if (versionComparator != null) {
+ //ok, we found one non-default, let's go with that.
+ break;
+ }
+ }
+ }
+ } catch (Exception e) {
+ log.warn("Searching package sources for a version comparator failed. Will use the default comparator.", e);
+ }
+
+ if (versionComparator == null) {
+ versionComparator = PackageVersion.DEFAULT_COMPARATOR;
+ }
+
+ //even though we can obtain the package versions from the pvcss elements, we can't
+ //use just these, because these are not all the package versions there might be present
+ //in the repo for this package. Some package versions can have no content source.
+ //therefore we need to query the database again in the code below to obtain the full
+ //list of package versions.
+ }
+
+ Query q = entityManager.createNamedQuery(PackageVersion.QUERY_FIND_BY_PACKAGE_AND_REPO_ID);
+ q.setParameter("packageId", packageId);
+ q.setParameter("repoId", repoId);
+
+ @SuppressWarnings("unchecked")
+ List<PackageVersion> results = (List<PackageVersion>) q.getResultList();
+
+ if (results.size() == 0) {
+ return null;
+ } else if (results.size() == 1) {
+ return results.get(0);
+ }
+
+ PackageVersion latest = results.get(0);
+ Iterator<PackageVersion> it = results.iterator();
+ it.next(); //skip the first element, we don't have to compare it with itself
+ while(it.hasNext()) {
+ PackageVersion current = it.next();
+ if (versionComparator.compare(latest, current) < 0) {
+ latest = current;
+ }
+ }
+
+ return latest;
+ }
+
+ @RequiredPermission(Permission.MANAGE_INVENTORY)
public Repo updateRepo(Subject subject, Repo repo) throws RepoException {
validateFields(repo);
// HHH-2864 - Leave this in until we move to hibernate > 3.2.r14201-2
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/RepoManagerLocal.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/RepoManagerLocal.java
index ac9e890..e5b8a38 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/RepoManagerLocal.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/RepoManagerLocal.java
@@ -18,6 +18,7 @@
*/
package org.rhq.enterprise.server.content;
+import java.util.Comparator;
import java.util.List;
import javax.ejb.Local;
@@ -109,6 +110,11 @@ public interface RepoManagerLocal {
PageList<PackageVersion> findPackageVersionsInRepo(Subject subject, int repoId, String filter, PageControl pc);
/**
+ * @see RepoManagerRemote#getLatestPackageVersion(Subject, int, int, Comparator)
+ */
+ PackageVersion getLatestPackageVersion(Subject subject, int packageId, int repoId, Comparator<PackageVersion> versionComparator);
+
+ /**
* Get the overall sync status of this Repository. This is a summation of all the syncs.
*
* There is a weight to the status since this returns the most 'relevant' status:
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/RepoManagerRemote.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/RepoManagerRemote.java
index 4337203..66d3b2f 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/RepoManagerRemote.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/RepoManagerRemote.java
@@ -18,6 +18,7 @@
*/
package org.rhq.enterprise.server.content;
+import java.util.Comparator;
import java.util.List;
import javax.ejb.Remote;
@@ -131,6 +132,29 @@ public interface RepoManagerRemote {
@WebParam(name = "criteria") PackageVersionCriteria criteria);
/**
+ * Returns the latest package version of the supplied package as deemed by the supplied comparator.
+ * The supplied comparator is taken as an override to the default one to use.
+ * The default comparator is determined using the following algorithm:
+ * <ol>
+ * <li>Find the first content provider defining the package connected to given repo
+ * that defines a non-null comparator and return that
+ * <li>If no content provider provides explicit comparator, use {@link PackageVersion#DEFAULT_COMPARATOR}
+ * </ol>
+ *
+ * @param subject the authenticated user
+ * @param packageId the id of the package to find the latest version for.
+ * @param repoId the repo where to take the package versions of the package from
+ * @param versionComparator if left null, the comparator to use is determined by the rules above
+ * @return
+ */
+ @WebMethod
+ PackageVersion getLatestPackageVersion(
+ @WebParam(name = "subject") Subject subject,
+ @WebParam(name = "packageId") int packageId,
+ @WebParam(name = "repoId") int repoId,
+ @WebParam(name = "versionComparator") Comparator<PackageVersion> versionComparator);
+
+ /**
* Update an existing {@link Repo} object's basic fields, like name, description, etc. Note that the given <code>
* repo</code>'s relationships will be ignored and not merged with the existing repo (e.g. is subscribed
* resources will not be changed, regardless of what the given repo's subscribed resources set it).
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/content/PackageSource.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/content/PackageSource.java
index 5bdfd4b..a5c7bae 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/content/PackageSource.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/content/PackageSource.java
@@ -34,6 +34,7 @@ import org.rhq.core.domain.content.PackageVersion;
* passed into the plugin through {@link ContentProvider#initialize(org.rhq.core.domain.configuration.Configuration)}
*
* @author Jason Dobies
+ * @author Lukas Krejci
*/
public interface PackageSource {
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/webservices/WebservicesManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/webservices/WebservicesManagerBean.java
index 056582f..27d06d3 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/webservices/WebservicesManagerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/webservices/WebservicesManagerBean.java
@@ -25,6 +25,7 @@ package org.rhq.enterprise.server.webservices;
import java.io.File;
import java.io.InputStream;
import java.net.URL;
+import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -779,6 +780,11 @@ public class WebservicesManagerBean implements WebservicesRemote {
return repoManager.findPackageVersionsInRepoByCriteria(subject, criteria);
}
+ public PackageVersion getLatestPackageVersion(Subject subject, int packageId, int repoId,
+ Comparator<PackageVersion> versionComparator) {
+ return repoManager.getLatestPackageVersion(subject, packageId, repoId, versionComparator);
+ }
+
public PageList<Resource> findSubscribedResources(Subject subject, int repoId, PageControl pc) {
return repoManager.findSubscribedResources(subject, repoId, pc);
}
diff --git a/modules/enterprise/server/plugins/alert-cli/src/main/java/org/rhq/enterprise/server/plugins/alertCli/CliComponent.java b/modules/enterprise/server/plugins/alert-cli/src/main/java/org/rhq/enterprise/server/plugins/alertCli/CliComponent.java
index 431d356..87cefa2 100644
--- a/modules/enterprise/server/plugins/alert-cli/src/main/java/org/rhq/enterprise/server/plugins/alertCli/CliComponent.java
+++ b/modules/enterprise/server/plugins/alert-cli/src/main/java/org/rhq/enterprise/server/plugins/alertCli/CliComponent.java
@@ -70,9 +70,11 @@ public class CliComponent implements ServerPluginComponent, ControlFacet {
private static final String PROP_ALERT_DEFINITION_ID = "alertDefinitionId";
private static final String PROP_USER_NAME = "userName";
private static final String PROP_ALERT_DEF_IDS = "alertDefIds";
+ private static final String PROP_REPO_NAME = "repoName";
private Set<String> scriptPackageTypes;
private String pluginName;
+ private String repoName;
public void initialize(ServerPluginContext context) throws Exception {
scriptPackageTypes = new HashSet<String>();
@@ -83,8 +85,18 @@ public class CliComponent implements ServerPluginComponent, ControlFacet {
scriptPackageTypes.add(value.getStringValue());
}
+
+ repoName = context.getPluginConfiguration().getSimpleValue(PROP_REPO_NAME, null);
}
+ public Set<String> getScriptPackageTypes() {
+ return scriptPackageTypes;
+ }
+
+ public String getRepoName() {
+ return repoName;
+ }
+
public void start() {
}
diff --git a/modules/enterprise/server/plugins/alert-cli/src/main/java/org/rhq/enterprise/server/plugins/alertCli/CliSender.java b/modules/enterprise/server/plugins/alert-cli/src/main/java/org/rhq/enterprise/server/plugins/alertCli/CliSender.java
index b094beb..6d7f30c 100644
--- a/modules/enterprise/server/plugins/alert-cli/src/main/java/org/rhq/enterprise/server/plugins/alertCli/CliSender.java
+++ b/modules/enterprise/server/plugins/alert-cli/src/main/java/org/rhq/enterprise/server/plugins/alertCli/CliSender.java
@@ -29,9 +29,9 @@ import java.io.OutputStream;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
import java.io.PrintWriter;
-import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.util.Collections;
+import java.util.List;
import javax.script.ScriptEngine;
import javax.script.ScriptException;
@@ -47,9 +47,12 @@ import org.rhq.core.domain.alert.notification.SenderResult;
import org.rhq.core.domain.auth.Subject;
import org.rhq.core.domain.configuration.PropertySimple;
import org.rhq.core.domain.content.PackageVersion;
+import org.rhq.core.domain.content.Repo;
+import org.rhq.core.domain.criteria.RepoCriteria;
import org.rhq.core.util.exception.ThrowableUtil;
import org.rhq.enterprise.client.LocalClient;
import org.rhq.enterprise.server.content.ContentSourceManagerLocal;
+import org.rhq.enterprise.server.content.RepoManagerLocal;
import org.rhq.enterprise.server.plugin.pc.ServerPluginComponent;
import org.rhq.enterprise.server.plugin.pc.alert.AlertSender;
import org.rhq.enterprise.server.util.LookupUtil;
@@ -62,48 +65,54 @@ import org.rhq.enterprise.server.util.LookupUtil;
public class CliSender extends AlertSender<ServerPluginComponent> {
public static final String PROP_PACKAGE_ID = "packageId";
+ public static final String PROP_REPO_ID = "repoId";
public static final String PROP_USER_ID = "userId";
private static final Log LOG = LogFactory.getLog(CliSender.class);
+ private static final String SUMMARY_TEMPLATE = "Ran script $packageName in version $packageVersion from repo $repoName as user $userName.";
+ private static final String PREVIEW_TEMPLATE = "Run script $packageName from repo $repoName as user $userName.";
+
+ /**
+ * Simple strongly typed representation of the alert configuration
+ */
+ private static class Config {
+ Subject subject;
+ int packageId;
+ int repoId;
+ }
+
public SenderResult send(Alert alert) {
SenderResult result = new SenderResult();
BufferedReader reader = null;
try {
- ByteArrayOutputStream scriptOutputStream = new ByteArrayOutputStream();
-
- ScriptEngine engine = getScriptEngine(alert, scriptOutputStream);
-
- PropertySimple packageIdProp = alertParameters.getSimple(PROP_PACKAGE_ID);
-
- if (packageIdProp == null) {
- return SenderResult
- .getSimpleFailure("The configuration doesn't contain the mandatory 'packageId' property. This should not happen.");
- }
+ Config config = getConfig();
+ result.setSummary(createSummary(config, SUMMARY_TEMPLATE));
- Integer packageId = packageIdProp.getIntegerValue();
+ ByteArrayOutputStream scriptOutputStream = new ByteArrayOutputStream();
- if (packageId == null) {
- return SenderResult.getSimpleFailure("No script defined.");
- }
+ ScriptEngine engine = getScriptEngine(alert, scriptOutputStream, config);
- InputStream packageBits = getPackageBits(packageId);
+ InputStream packageBits = getPackageBits(config.packageId, config.repoId);
reader = new BufferedReader(new InputStreamReader(packageBits));
engine.eval(reader);
String scriptOutput = scriptOutputStream.toString(Charset.defaultCharset().name());
+
+ if (scriptOutput.length() == 0) {
+ scriptOutput = "Script generated no output.";
+ }
- result.setSummary(scriptOutput);
-
- result.addSuccessMessage("The script executed successfully. Its output is stored in the summary.");
-
+ result.addSuccessMessage(scriptOutput);
+
return result;
} catch (IllegalArgumentException e) {
return SenderResult.getSimpleFailure(e.getMessage());
} catch (Exception e) {
- return SenderResult.getSimpleFailure(ThrowableUtil.getAllMessages(e));
+ result.addFailureMessage(ThrowableUtil.getAllMessages(e));
+ return result;
} finally {
if (reader != null) {
try {
@@ -115,15 +124,21 @@ public class CliSender extends AlertSender<ServerPluginComponent> {
}
}
- private ScriptEngine getScriptEngine(Alert alert, OutputStream scriptOutput) throws ScriptException, IOException, IllegalArgumentException {
- int userId = alertParameters.getSimple(PROP_USER_ID).getIntegerValue();
-
- Subject user = LookupUtil.getSubjectManager().getSubjectById(userId);
-
- if (user == null) {
- throw new IllegalArgumentException("The script cannot run because the user (id " + userId + ") configured to run it doesn't exist anymore.");
+ @Override
+ public String previewConfiguration() {
+ try {
+ Config c = getConfig();
+ return createSummary(c, PREVIEW_TEMPLATE);
+ } catch (Exception e) {
+ LOG.warn("Failed to get the configuration preview.", e);
+ return "Failed to get configuration preview: " + e.getMessage();
}
-
+ }
+
+ private static ScriptEngine getScriptEngine(Alert alert, OutputStream scriptOutput, Config config) throws ScriptException,
+ IOException {
+ Subject user = config.subject;
+
LocalClient client = new LocalClient(user);
PrintWriter output = new PrintWriter(scriptOutput);
@@ -134,9 +149,10 @@ public class CliSender extends AlertSender<ServerPluginComponent> {
bindings);
}
- private InputStream getPackageBits(int packageId) throws IOException {
+ private static InputStream getPackageBits(int packageId, int repoId) throws IOException {
final ContentSourceManagerLocal csm = LookupUtil.getContentSourceManager();
- final PackageVersion versionToUse = csm.getLatestPackageVersion(packageId, null);
+ RepoManagerLocal rm = LookupUtil.getRepoManagerLocal();
+ final PackageVersion versionToUse = rm.getLatestPackageVersion(LookupUtil.getSubjectManager().getOverlord(), packageId, repoId, null);
PipedInputStream ret = new PipedInputStream();
final PipedOutputStream out = new PipedOutputStream(ret);
@@ -167,4 +183,88 @@ public class CliSender extends AlertSender<ServerPluginComponent> {
return ret;
}
+
+ /**
+ * Possible replacements are:
+ * <ul>
+ * <li><code>$userName</code>
+ * <li><code>$packageName</code>
+ * <li><code>$packageVersion</code>
+ * <li><code>$repoName</code>
+ * </ul>
+ * @param config
+ * @param template
+ * @return
+ */
+ private static String createSummary(Config config, String template) {
+ try {
+ String ret = template;
+
+ ret = ret.replace("$userName", config.subject.getName());
+
+ //now get the package and repo info
+ Subject overlord = LookupUtil.getSubjectManager().getOverlord();
+ RepoManagerLocal rm = LookupUtil.getRepoManagerLocal();
+ PackageVersion versionToUse = rm.getLatestPackageVersion(overlord, config.packageId, config.repoId, null);
+
+ ret = ret.replace("$packageName", versionToUse.getDisplayName());
+ ret = ret.replace("$pacakgeVersion", versionToUse.getDisplayVersion() == null ? versionToUse.getVersion()
+ : versionToUse.getDisplayVersion());
+
+ RepoManagerLocal rm = LookupUtil.getRepoManagerLocal();
+ RepoCriteria criteria = new RepoCriteria();
+ criteria.addFilterId(config.repoId);
+
+ List<Repo> repos = rm.findReposByCriteria(overlord, criteria);
+
+ String repoName;
+
+ if (repos.size() > 0) {
+ repoName = repos.get(0).getName();
+ } else {
+ repoName = "unknown repo with id " + config.repoId;
+ }
+
+ ret = ret.replace("$repoName", repoName);
+
+ return ret;
+ } catch (Exception e) {
+ LOG.info("Failed to create alert sender summary.", e);
+ return "Failed to create summary: " + e.getMessage();
+ }
+ }
+
+ private Config getConfig() throws IllegalArgumentException {
+ Config ret = new Config();
+
+ int subjectId = getIntFromConfiguration(PROP_USER_ID, "User id not specified.", "Failed to read subject id property: ");
+ int packageId = getIntFromConfiguration(PROP_PACKAGE_ID, "Package id of the script not specified.", "Failed to read the package id property: ");
+ int repoId = getIntFromConfiguration(PROP_REPO_ID, "Repo to download the script package from not specified.", "Failed to read the repo id property: ");
+
+ Subject subject = LookupUtil.getSubjectManager().getSubjectById(subjectId);
+
+ if (subject == null) {
+ throw new IllegalArgumentException("User with id " + subjectId + " doesn't exist anymore.");
+ }
+
+ ret.subject = subject;
+ ret.packageId = packageId;
+ ret.repoId = repoId;
+
+ return ret;
+ }
+
+ private int getIntFromConfiguration(String propName, String errorMessage, String convertErrorMessage) throws IllegalArgumentException {
+ PropertySimple prop = alertParameters.getSimple(propName);
+
+ if (prop == null) {
+ throw new IllegalArgumentException(errorMessage);
+ }
+
+ try {
+ return prop.getIntegerValue();
+ } catch (Exception e) {
+ throw new IllegalArgumentException(convertErrorMessage + e.getMessage(), e);
+ }
+ }
}
diff --git a/modules/enterprise/server/plugins/alert-cli/src/main/resources/META-INF/rhq-serverplugin.xml b/modules/enterprise/server/plugins/alert-cli/src/main/resources/META-INF/rhq-serverplugin.xml
index 5d7dcbd..43785ff 100644
--- a/modules/enterprise/server/plugins/alert-cli/src/main/resources/META-INF/rhq-serverplugin.xml
+++ b/modules/enterprise/server/plugins/alert-cli/src/main/resources/META-INF/rhq-serverplugin.xml
@@ -58,6 +58,11 @@
<c:description>
The list of package types that will be considered scripts. Any package of those types in any repo will be
considered a script and will be available for choosing as an alert script.
+ The package type can be one of those defined by different agent plugins and can be applicable
+ to some resource type (i.e. you might use such package type to "stream" the packages down to resources
+ on different agents using the content subsystem) but it doesn't have to.
+
+ A good choice is something like 'seversideCLIScript'.
</c:description>
<c:simple-property name="packageType" displayName="Package Type" type="string" required="true"/>
</c:list-property>
@@ -71,6 +76,7 @@
<alert-configuration>
<c:simple-property name="packageId" type="integer" required="true" description="The id of the package containing the script to execute."/>
+ <c:simple-property name="repoId" type="integer" required="true" description="The id of the repo to download the package from."/>
<c:simple-property name="userId" type="integer" required="true" description="The user the script will be run as."/>
</alert-configuration>
</alert-plugin>
\ No newline at end of file
commit 9ae2df48e3057d2f3aaeab2b903cbc84e5131ef2
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Mon Jan 31 15:02:22 2011 +0100
implemented re-assigning of cli alert notifications to different users.
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/alert/notification/AlertNotification.java b/modules/core/domain/src/main/java/org/rhq/core/domain/alert/notification/AlertNotification.java
index d93c81b..ec3e849 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/alert/notification/AlertNotification.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/alert/notification/AlertNotification.java
@@ -74,8 +74,18 @@ import org.rhq.core.domain.configuration.Property;
+ " AND notifParam.name = :propertyName" //
+ " AND locate(:paramValue,notifParam.stringValue) <> 0" //
+ ")"
-
- ) })
+ ),
+ @NamedQuery(name = AlertNotification.QUERY_UPDATE_PARAMETER_FOR_NOTIFICATIONS, query = "" //
+ + " UPDATE Property property" //
+ + " SET stringValue = :propertyValue" //
+ + " WHERE id IN ( "
+ + " SELECT notifParam.id" //
+ + " FROM AlertNotification notif" //
+ + " JOIN notif.configuration.properties notifParam" //
+ + " WHERE notif.id IN ( :alertNotificationIds )" //
+ + " AND notifParam.name = :propertyName" //
+ + ")"
+ )})
@SequenceGenerator(name = "RHQ_ALERT_NOTIFICATION_ID_SEQ", sequenceName = "RHQ_ALERT_NOTIFICATION_ID_SEQ")
@Table(name = "RHQ_ALERT_NOTIFICATION")
public class AlertNotification implements Serializable {
@@ -87,7 +97,8 @@ public class AlertNotification implements Serializable {
public static final String QUERY_DELETE_ORPHANED = "AlertNotification.deleteOrphaned";
public static final String QUERY_DELETE_BY_ROLE_ID = "AlertNotification.deleteByRoleId";
public static final String QUERY_CLEANSE_PARAMETER_VALUE_FOR_ALERT_SENDER = "AlertNotification.cleanseParameterValueForAlertSender";
-
+ public static final String QUERY_UPDATE_PARAMETER_FOR_NOTIFICATIONS = "AlertNotification.updateParameterForNotifications";
+
@Column(name = "ID", nullable = false)
@GeneratedValue(strategy = GenerationType.AUTO, generator = "RHQ_ALERT_NOTIFICATION_ID_SEQ")
@Id
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/AlertDefinitionCriteria.java b/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/AlertDefinitionCriteria.java
index c329527..e38a452 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/AlertDefinitionCriteria.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/AlertDefinitionCriteria.java
@@ -43,6 +43,7 @@ public class AlertDefinitionCriteria extends Criteria {
private static final long serialVersionUID = 1L;
private Integer filterId;
+ private List<Integer> filterIds;
private String filterName;
private String filterDescription;
private AlertPriority filterPriority;
@@ -70,6 +71,7 @@ public class AlertDefinitionCriteria extends Criteria {
filterOverrides.put("resourceIds", "resource.id IN ( ? )");
filterOverrides.put("resourceGroupIds", "resourceGroup.id IN ( ? )");
filterOverrides.put("notificationSenderNames", "alertNotifications.senderName IN ( ? )");
+ filterOverrides.put("filterIds", "id IN ( ? )");
}
@Override
@@ -81,6 +83,10 @@ public class AlertDefinitionCriteria extends Criteria {
this.filterId = filterId;
}
+ public void addFilterIds(Integer... filterIds) {
+ this.filterIds = Arrays.asList(filterIds);
+ }
+
public void addFilterName(String filterName) {
this.filterName = filterName;
}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertNotificationManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertNotificationManagerBean.java
index 030b586..13f356b 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertNotificationManagerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertNotificationManagerBean.java
@@ -326,14 +326,27 @@ public class AlertNotificationManagerBean implements AlertNotificationManagerLoc
}
public int cleanseAlertNotificationBySubject(int subjectId) {
- return cleanseParmaeterValueForAlertSender("System Users", "subjectId", String.valueOf(subjectId));
+ return cleanseParameterValueForAlertSender("System Users", "subjectId", String.valueOf(subjectId));
}
public int cleanseAlertNotificationByRole(int roleId) {
- return cleanseParmaeterValueForAlertSender("System Roles", "roleId", String.valueOf(roleId));
+ return cleanseParameterValueForAlertSender("System Roles", "roleId", String.valueOf(roleId));
}
- private int cleanseParmaeterValueForAlertSender(String senderName, String propertyName, String valueToCleanse) {
+ public void massReconfigure(List<Integer> alertNotificationIds, Map<String, String> newConfigurationValues) {
+ Query query = entityManager.createNamedQuery(AlertNotification.QUERY_UPDATE_PARAMETER_FOR_NOTIFICATIONS);
+
+ query.setParameter("alertNotificationIds", alertNotificationIds);
+
+ for(Map.Entry<String, String> entry : newConfigurationValues.entrySet()) {
+ query.setParameter("propertyName", entry.getKey());
+ query.setParameter("propertyValue", entry.getValue());
+
+ query.executeUpdate();
+ }
+ }
+
+ private int cleanseParameterValueForAlertSender(String senderName, String propertyName, String valueToCleanse) {
Query query = entityManager.createNamedQuery(AlertNotification.QUERY_CLEANSE_PARAMETER_VALUE_FOR_ALERT_SENDER);
query.setParameter("senderName", senderName);
query.setParameter("propertyName", propertyName);
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertNotificationManagerLocal.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertNotificationManagerLocal.java
index ff222fc..43a8215 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertNotificationManagerLocal.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertNotificationManagerLocal.java
@@ -19,6 +19,7 @@
package org.rhq.enterprise.server.alert;
import java.util.List;
+import java.util.Map;
import javax.ejb.Local;
@@ -118,4 +119,12 @@ public interface AlertNotificationManagerLocal {
int cleanseAlertNotificationBySubject(int subjectId);
int cleanseAlertNotificationByRole(int roleId);
+
+ /**
+ * This method can be used to reconfigure a number of notifications en-masse.
+ *
+ * @param alertNotificationIds the alert notifications to update
+ * @param newConfigurationValues a map where keys are the property names and values are the new property values
+ */
+ void massReconfigure(List<Integer> alertNotificationIds, Map<String, String> newConfigurationValues);
}
diff --git a/modules/enterprise/server/plugins/alert-cli/src/main/java/org/rhq/enterprise/server/plugins/alertCli/CliComponent.java b/modules/enterprise/server/plugins/alert-cli/src/main/java/org/rhq/enterprise/server/plugins/alertCli/CliComponent.java
index 09f9abd..431d356 100644
--- a/modules/enterprise/server/plugins/alert-cli/src/main/java/org/rhq/enterprise/server/plugins/alertCli/CliComponent.java
+++ b/modules/enterprise/server/plugins/alert-cli/src/main/java/org/rhq/enterprise/server/plugins/alertCli/CliComponent.java
@@ -19,8 +19,12 @@
package org.rhq.enterprise.server.plugins.alertCli;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
import java.util.HashSet;
import java.util.List;
+import java.util.Map;
import java.util.Set;
import org.rhq.core.domain.alert.AlertDefinition;
@@ -37,6 +41,7 @@ import org.rhq.core.domain.util.DisambiguationReportRenderer;
import org.rhq.core.domain.util.PageControl;
import org.rhq.core.util.IntExtractor;
import org.rhq.enterprise.server.alert.AlertDefinitionManagerLocal;
+import org.rhq.enterprise.server.alert.AlertNotificationManagerLocal;
import org.rhq.enterprise.server.auth.SubjectManagerLocal;
import org.rhq.enterprise.server.plugin.pc.ControlFacet;
import org.rhq.enterprise.server.plugin.pc.ControlResults;
@@ -62,6 +67,9 @@ public class CliComponent implements ServerPluginComponent, ControlFacet {
private static final String PROP_RESOURCE_ID = "resourceId";
private static final String PROP_MISCONFIGURED_ALERT_DEFS = "misconfiguredAlertDefs";
private static final String PROP_ALERT_DEFINITION = "alertDefinition";
+ private static final String PROP_ALERT_DEFINITION_ID = "alertDefinitionId";
+ private static final String PROP_USER_NAME = "userName";
+ private static final String PROP_ALERT_DEF_IDS = "alertDefIds";
private Set<String> scriptPackageTypes;
private String pluginName;
@@ -103,52 +111,26 @@ public class CliComponent implements ServerPluginComponent, ControlFacet {
}
private void checkAlertsValidity(ControlResults results, Configuration parameters) {
- AlertDefinitionManagerLocal manager = LookupUtil.getAlertDefinitionManager();
- SubjectManagerLocal subjectManager = LookupUtil.getSubjectManager();
-
- Subject overlord = subjectManager.getOverlord();
-
- AlertDefinitionCriteria criteria = new AlertDefinitionCriteria();
- criteria.addFilterNotificationNames(pluginName);
- criteria.setPageControl(PageControl.getUnlimitedInstance());
-
- List<AlertDefinition> defs = manager.findAlertDefinitionsByCriteria(overlord, criteria);
+ List<AlertNotification> invalidNotifs = getAllCliNotificationsWithInvalidUser();
- for(AlertDefinition def : defs) {
- List<AlertNotification> notifications = def.getAlertNotifications();
+ for(AlertNotification cliNotification : invalidNotifs) {
+ AlertDefinition def = cliNotification.getAlertDefinition();
- AlertNotification cliNotification = getCliNotification(notifications);
+ Configuration resConfig = results.getComplexResults();
- if (cliNotification == null) {
- //we alway should find this but a little bit of paranoia never hurt anyone
- continue;
+ PropertyList misconfigured = resConfig.getList(PROP_MISCONFIGURED_ALERT_DEFS);
+ if (misconfigured == null) {
+ misconfigured = new PropertyList(PROP_MISCONFIGURED_ALERT_DEFS);
+ resConfig.put(misconfigured);
}
- Subject checkSubject = null;
+ PropertyMap alertDefinitionMap = new PropertyMap(PROP_ALERT_DEFINITION);
- PropertySimple subjectIdProperty = cliNotification.getConfiguration().getSimple(CliSender.PROP_USER_ID);
- if (subjectIdProperty != null) {
- int subjectId = subjectIdProperty.getIntegerValue();
-
- checkSubject = subjectManager.getSubjectById(subjectId);
- }
+ alertDefinitionMap.put(new PropertySimple(PROP_ALERT_DEFINITION_ID, def.getId()));
+ alertDefinitionMap.put(new PropertySimple(PROP_ALERT_DEFINITION_NAME, def.getName()));
+ alertDefinitionMap.put(new PropertySimple(PROP_RESOURCE_ID, def.getResource().getId()));
- if (checkSubject == null) {
- Configuration resConfig = results.getComplexResults();
-
- PropertyList misconfigured = resConfig.getList(PROP_MISCONFIGURED_ALERT_DEFS);
- if (misconfigured == null) {
- misconfigured = new PropertyList(PROP_MISCONFIGURED_ALERT_DEFS);
- resConfig.put(misconfigured);
- }
-
- PropertyMap alertDefinitionMap = new PropertyMap(PROP_ALERT_DEFINITION);
-
- alertDefinitionMap.put(new PropertySimple(PROP_ALERT_DEFINITION_NAME, def.getName()));
- alertDefinitionMap.put(new PropertySimple(PROP_RESOURCE_ID, def.getResource().getId()));
-
- misconfigured.add(alertDefinitionMap);
- }
+ misconfigured.add(alertDefinitionMap);
}
//ok, now we have to obtain the resource paths. doing it out of the above loop reduces the number
@@ -179,10 +161,46 @@ public class CliComponent implements ServerPluginComponent, ControlFacet {
}
private void reassignAlerts(ControlResults results, Configuration parameters) {
- //TODO implement
+ PropertySimple userNameProp = parameters.getSimple(PROP_USER_NAME);
+ PropertySimple alertDefIdsProp = parameters.getSimple(PROP_ALERT_DEF_IDS);
+
+ if (userNameProp == null) {
+ throw new IllegalArgumentException("User name not specified.");
+ }
+
+ String userName = userNameProp.getStringValue();
+ SubjectManagerLocal subjectManager = LookupUtil.getSubjectManager();
+ Subject subject = subjectManager.getSubjectByName(userName);
+
+ if (subject == null) {
+ throw new IllegalArgumentException("User '" + userName + "' doesn't exist.");
+ }
+
+ //now get the list of the alert notifications to update
+ List<AlertNotification> notifsToReAssign = null;
+ if (alertDefIdsProp == null || alertDefIdsProp.getStringValue().trim().length() == 0) {
+ notifsToReAssign = getAllCliNotificationsWithInvalidUser();
+ } else {
+ List<Integer> alertDefIds = asIdList(alertDefIdsProp.getStringValue().split("\\s*,\\s*"));
+ List<AlertDefinition> defs = getAlertDefinitionsWithCliNotifications(alertDefIds);
+
+ notifsToReAssign = new ArrayList<AlertNotification>();
+ for(AlertDefinition def : defs) {
+ AlertNotification cliNotif = getCliNotification(def.getAlertNotifications());
+ if (cliNotif != null) {
+ notifsToReAssign.add(cliNotif);
+ }
+ }
+ }
+
+ AlertNotificationManagerLocal notificationManager = LookupUtil.getAlertNotificationManager();
+
+ List<Integer> notifIds = asIdList(notifsToReAssign);
+ Map<String, String> updates = Collections.singletonMap(CliSender.PROP_USER_ID, Integer.toString(subject.getId()));
+ notificationManager.massReconfigure(notifIds, updates);
}
- AlertNotification getCliNotification(List<AlertNotification> notifications) {
+ private AlertNotification getCliNotification(List<AlertNotification> notifications) {
for(AlertNotification n : notifications) {
if (pluginName.equals(n.getSenderName())) {
return n;
@@ -191,4 +209,74 @@ public class CliComponent implements ServerPluginComponent, ControlFacet {
return null;
}
+
+ private List<AlertDefinition> getAlertDefinitionsWithCliNotifications(Collection<Integer> ids) {
+ SubjectManagerLocal subjectManager = LookupUtil.getSubjectManager();
+ AlertDefinitionManagerLocal manager = LookupUtil.getAlertDefinitionManager();
+
+ Subject overlord = subjectManager.getOverlord();
+
+ AlertDefinitionCriteria criteria = new AlertDefinitionCriteria();
+ criteria.addFilterNotificationNames(pluginName);
+ criteria.setPageControl(PageControl.getUnlimitedInstance());
+ criteria.fetchAlertNotifications(true);
+ if (ids != null) {
+ criteria.addFilterIds(ids.toArray(new Integer[ids.size()]));
+ }
+
+ return manager.findAlertDefinitionsByCriteria(overlord, criteria);
+ }
+
+ private List<AlertNotification> getAllCliNotificationsWithInvalidUser() {
+ List<AlertNotification> ret = new ArrayList<AlertNotification>();
+
+ SubjectManagerLocal subjectManager = LookupUtil.getSubjectManager();
+
+ List<AlertDefinition> defs = getAlertDefinitionsWithCliNotifications(null);
+
+ for(AlertDefinition def : defs) {
+ List<AlertNotification> notifications = def.getAlertNotifications();
+
+ AlertNotification cliNotification = getCliNotification(notifications);
+
+ if (cliNotification == null) {
+ //we always should find this but a little bit of paranoia never hurt anyone
+ continue;
+ }
+
+ Subject checkSubject = null;
+
+ PropertySimple subjectIdProperty = cliNotification.getConfiguration().getSimple(CliSender.PROP_USER_ID);
+ if (subjectIdProperty != null) {
+ int subjectId = subjectIdProperty.getIntegerValue();
+
+ checkSubject = subjectManager.getSubjectById(subjectId);
+ }
+
+ if (checkSubject == null) {
+ ret.add(cliNotification);
+ }
+ }
+
+ return ret;
+ }
+
+ private List<Integer> asIdList(String... ids) {
+ List<Integer> ret = new ArrayList<Integer>();
+ for(String id : ids) {
+ ret.add(Integer.parseInt(id));
+ }
+
+ return ret;
+ }
+
+ private List<Integer> asIdList(Collection<AlertNotification> notifs) {
+ ArrayList<Integer> ret = new ArrayList<Integer>();
+
+ for(AlertNotification n : notifs) {
+ ret.add(n.getId());
+ }
+
+ return ret;
+ }
}
diff --git a/modules/enterprise/server/plugins/alert-cli/src/main/resources/META-INF/rhq-serverplugin.xml b/modules/enterprise/server/plugins/alert-cli/src/main/resources/META-INF/rhq-serverplugin.xml
index cb3ed60..5d7dcbd 100644
--- a/modules/enterprise/server/plugins/alert-cli/src/main/resources/META-INF/rhq-serverplugin.xml
+++ b/modules/enterprise/server/plugins/alert-cli/src/main/resources/META-INF/rhq-serverplugin.xml
@@ -24,16 +24,28 @@
This operation returns a list of such misconfigured alert definitions.
</c:description>
<c:map-property name="alertDefinition">
+ <c:simple-property name="alertDefinitionId" />
+ <c:simple-property name="alertDefinitionName" />
<c:simple-property name="resourceId" />
<c:simple-property name="resourcePath" />
- <c:simple-property name="alertDefinitionName" />
</c:map-property>
</c:list-property>
</serverplugin:results>
</serverplugin:control>
- <!-- TODO define the args and results of this operation -->
- <serverplugin:control name="reassignAlerts" description="Re-assign alerts to run as different users" />
+ <serverplugin:control name="reassignAlerts" description="Re-assign alerts to run as different users">
+ <serverplugin:parameters>
+ <c:simple-property name="userName" displayName="User Name" description="The name of the user to re-assign the alerts to." />
+ <c:simple-property name="alertDefIds" displayName="Alert Definition IDs" required="false">
+ <c:description>
+ The comma-separated list of the alert definition ids to re-assign.
+ If left empty, all the alert definitions with the CLI notifications that have
+ an invalid user assigned, will be re-assigned to the provided user.
+ </c:description>
+ <c:constraint><c:regex-constraint expression="(\d+(\s*,\s*\d+)*)?"/></c:constraint>
+ </c:simple-property>
+ </serverplugin:parameters>
+ </serverplugin:control>
</serverplugin:plugin-component>
<serverplugin:plugin-configuration>
commit 2f77ae3b3f9bb4ab748466a97fad2be9d3ac6223
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Mon Jan 31 12:37:45 2011 +0100
consider cli notifications with no userId property at all invalid (these should never exist, but one never knows).
diff --git a/modules/enterprise/server/plugins/alert-cli/src/main/java/org/rhq/enterprise/server/plugins/alertCli/CliComponent.java b/modules/enterprise/server/plugins/alert-cli/src/main/java/org/rhq/enterprise/server/plugins/alertCli/CliComponent.java
index f0ba8aa..09f9abd 100644
--- a/modules/enterprise/server/plugins/alert-cli/src/main/java/org/rhq/enterprise/server/plugins/alertCli/CliComponent.java
+++ b/modules/enterprise/server/plugins/alert-cli/src/main/java/org/rhq/enterprise/server/plugins/alertCli/CliComponent.java
@@ -124,17 +124,16 @@ public class CliComponent implements ServerPluginComponent, ControlFacet {
continue;
}
+ Subject checkSubject = null;
+
PropertySimple subjectIdProperty = cliNotification.getConfiguration().getSimple(CliSender.PROP_USER_ID);
- if (subjectIdProperty == null) {
- continue;
+ if (subjectIdProperty != null) {
+ int subjectId = subjectIdProperty.getIntegerValue();
+
+ checkSubject = subjectManager.getSubjectById(subjectId);
}
- int subjectId = subjectIdProperty.getIntegerValue();
-
- Subject checkSubject = subjectManager.getSubjectById(subjectId);
-
if (checkSubject == null) {
- //TODO this is the invalid user we're after.. let's store the info about the alert
Configuration resConfig = results.getComplexResults();
PropertyList misconfigured = resConfig.getList(PROP_MISCONFIGURED_ALERT_DEFS);
commit 8dac9334905eb046d5c935d6b4a2c7a394928da2
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Mon Jan 31 12:16:23 2011 +0100
Specifically ask for full path while asking the disambiguate() method to generate the resource paths.
diff --git a/modules/enterprise/server/plugins/alert-cli/src/main/java/org/rhq/enterprise/server/plugins/alertCli/CliComponent.java b/modules/enterprise/server/plugins/alert-cli/src/main/java/org/rhq/enterprise/server/plugins/alertCli/CliComponent.java
index 584d8cd..f0ba8aa 100644
--- a/modules/enterprise/server/plugins/alert-cli/src/main/java/org/rhq/enterprise/server/plugins/alertCli/CliComponent.java
+++ b/modules/enterprise/server/plugins/alert-cli/src/main/java/org/rhq/enterprise/server/plugins/alertCli/CliComponent.java
@@ -164,7 +164,7 @@ public class CliComponent implements ServerPluginComponent, ControlFacet {
return map.getSimple(PROP_RESOURCE_ID).getIntegerValue();
};
},
- DefaultDisambiguationUpdateStrategies.getDefault());
+ DefaultDisambiguationUpdateStrategies.KEEP_ALL_PARENTS);
DisambiguationReportRenderer renderer = new DisambiguationReportRenderer();
commit 7fcb68a9781b9119705cd994683fa54b871ccbd5
Merge: 8e5793c... bb15343...
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Wed Jan 26 18:54:20 2011 +0100
Merge remote branch 'origin/master' into cli-alert-notifs
commit 8e5793cffc1fb68049a0065aaad9d9e19cbd6529
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Wed Jan 26 18:53:37 2011 +0100
starting to implement the CLI alert plugin controls to support re-enabling of corrupted alerts after user deletion.
Note that there already is a hook for the in the form of AlertNotificationManagerLocal.cleanse* methods but I'm not sure
what state they leave the notifications in (not to mention that the cleanse methods are a hack).
diff --git a/modules/enterprise/server/plugins/alert-cli/src/main/java/org/rhq/enterprise/server/plugins/alertCli/CliComponent.java b/modules/enterprise/server/plugins/alert-cli/src/main/java/org/rhq/enterprise/server/plugins/alertCli/CliComponent.java
new file mode 100644
index 0000000..584d8cd
--- /dev/null
+++ b/modules/enterprise/server/plugins/alert-cli/src/main/java/org/rhq/enterprise/server/plugins/alertCli/CliComponent.java
@@ -0,0 +1,195 @@
+/*
+ * 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 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.server.plugins.alertCli;
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.rhq.core.domain.alert.AlertDefinition;
+import org.rhq.core.domain.alert.notification.AlertNotification;
+import org.rhq.core.domain.auth.Subject;
+import org.rhq.core.domain.configuration.Configuration;
+import org.rhq.core.domain.configuration.Property;
+import org.rhq.core.domain.configuration.PropertyList;
+import org.rhq.core.domain.configuration.PropertyMap;
+import org.rhq.core.domain.configuration.PropertySimple;
+import org.rhq.core.domain.criteria.AlertDefinitionCriteria;
+import org.rhq.core.domain.resource.composite.DisambiguationReport;
+import org.rhq.core.domain.util.DisambiguationReportRenderer;
+import org.rhq.core.domain.util.PageControl;
+import org.rhq.core.util.IntExtractor;
+import org.rhq.enterprise.server.alert.AlertDefinitionManagerLocal;
+import org.rhq.enterprise.server.auth.SubjectManagerLocal;
+import org.rhq.enterprise.server.plugin.pc.ControlFacet;
+import org.rhq.enterprise.server.plugin.pc.ControlResults;
+import org.rhq.enterprise.server.plugin.pc.ServerPluginComponent;
+import org.rhq.enterprise.server.plugin.pc.ServerPluginContext;
+import org.rhq.enterprise.server.resource.ResourceManagerLocal;
+import org.rhq.enterprise.server.resource.disambiguation.DefaultDisambiguationUpdateStrategies;
+import org.rhq.enterprise.server.util.LookupUtil;
+
+/**
+ * The plugin component for controlling the CLI alerts.
+ *
+ * @author Lukas Krejci
+ */
+public class CliComponent implements ServerPluginComponent, ControlFacet {
+
+ private static final String CONTROL_CHECK_ALERTS_VALIDITY = "checkAlertsValidity";
+ private static final String CONTROL_REASSIGN_ALERTS = "reassignAlerts";
+
+ private static final String PROP_PACKAGE_TYPES = "packageTypes";
+ private static final String PROP_ALERT_DEFINITION_NAME = "alertDefinitionName";
+ private static final String PROP_RESOURCE_PATH = "resourcePath";
+ private static final String PROP_RESOURCE_ID = "resourceId";
+ private static final String PROP_MISCONFIGURED_ALERT_DEFS = "misconfiguredAlertDefs";
+ private static final String PROP_ALERT_DEFINITION = "alertDefinition";
+
+ private Set<String> scriptPackageTypes;
+ private String pluginName;
+
+ public void initialize(ServerPluginContext context) throws Exception {
+ scriptPackageTypes = new HashSet<String>();
+ pluginName = context.getPluginEnvironment().getPluginDescriptor().getName();
+ PropertyList packageTypesList = context.getPluginConfiguration().getList(PROP_PACKAGE_TYPES);
+ for(Property p : packageTypesList.getList()) {
+ PropertySimple value = (PropertySimple) p;
+
+ scriptPackageTypes.add(value.getStringValue());
+ }
+ }
+
+ public void start() {
+ }
+
+ public void stop() {
+ }
+
+ public void shutdown() {
+ }
+
+ public ControlResults invoke(String name, Configuration parameters) {
+ ControlResults results = new ControlResults();
+
+ try {
+ if (CONTROL_CHECK_ALERTS_VALIDITY.equals(name)) {
+ checkAlertsValidity(results, parameters);
+ } else if (CONTROL_REASSIGN_ALERTS.equals(name)) {
+ reassignAlerts(results, parameters);
+ }
+ } catch (Exception e) {
+ results.setError(e);
+ }
+
+ return results;
+ }
+
+ private void checkAlertsValidity(ControlResults results, Configuration parameters) {
+ AlertDefinitionManagerLocal manager = LookupUtil.getAlertDefinitionManager();
+ SubjectManagerLocal subjectManager = LookupUtil.getSubjectManager();
+
+ Subject overlord = subjectManager.getOverlord();
+
+ AlertDefinitionCriteria criteria = new AlertDefinitionCriteria();
+ criteria.addFilterNotificationNames(pluginName);
+ criteria.setPageControl(PageControl.getUnlimitedInstance());
+
+ List<AlertDefinition> defs = manager.findAlertDefinitionsByCriteria(overlord, criteria);
+
+ for(AlertDefinition def : defs) {
+ List<AlertNotification> notifications = def.getAlertNotifications();
+
+ AlertNotification cliNotification = getCliNotification(notifications);
+
+ if (cliNotification == null) {
+ //we alway should find this but a little bit of paranoia never hurt anyone
+ continue;
+ }
+
+ PropertySimple subjectIdProperty = cliNotification.getConfiguration().getSimple(CliSender.PROP_USER_ID);
+ if (subjectIdProperty == null) {
+ continue;
+ }
+
+ int subjectId = subjectIdProperty.getIntegerValue();
+
+ Subject checkSubject = subjectManager.getSubjectById(subjectId);
+
+ if (checkSubject == null) {
+ //TODO this is the invalid user we're after.. let's store the info about the alert
+ Configuration resConfig = results.getComplexResults();
+
+ PropertyList misconfigured = resConfig.getList(PROP_MISCONFIGURED_ALERT_DEFS);
+ if (misconfigured == null) {
+ misconfigured = new PropertyList(PROP_MISCONFIGURED_ALERT_DEFS);
+ resConfig.put(misconfigured);
+ }
+
+ PropertyMap alertDefinitionMap = new PropertyMap(PROP_ALERT_DEFINITION);
+
+ alertDefinitionMap.put(new PropertySimple(PROP_ALERT_DEFINITION_NAME, def.getName()));
+ alertDefinitionMap.put(new PropertySimple(PROP_RESOURCE_ID, def.getResource().getId()));
+
+ misconfigured.add(alertDefinitionMap);
+ }
+ }
+
+ //ok, now we have to obtain the resource paths. doing it out of the above loop reduces the number
+ //of server roundtrips
+ ResourceManagerLocal resourceManager = LookupUtil.getResourceManager();
+ PropertyList misconfigured = results.getComplexResults().getList(PROP_MISCONFIGURED_ALERT_DEFS);
+ if (misconfigured != null) {
+ List<DisambiguationReport<Property>> disambiguated = resourceManager.disambiguate(misconfigured.getList(),
+ new IntExtractor<Property>() {
+ public int extract(Property object) {
+ PropertyMap map = (PropertyMap) object;
+ return map.getSimple(PROP_RESOURCE_ID).getIntegerValue();
+ };
+ },
+ DefaultDisambiguationUpdateStrategies.getDefault());
+
+ DisambiguationReportRenderer renderer = new DisambiguationReportRenderer();
+
+ for(DisambiguationReport<Property> r : disambiguated) {
+ PropertyMap map = (PropertyMap) r.getOriginal();
+
+ String resourcePath = renderer.render(r);
+
+ map.put(new PropertySimple(PROP_RESOURCE_PATH, resourcePath));
+ }
+ }
+
+ }
+
+ private void reassignAlerts(ControlResults results, Configuration parameters) {
+ //TODO implement
+ }
+
+ AlertNotification getCliNotification(List<AlertNotification> notifications) {
+ for(AlertNotification n : notifications) {
+ if (pluginName.equals(n.getSenderName())) {
+ return n;
+ }
+ }
+
+ return null;
+ }
+}
diff --git a/modules/enterprise/server/plugins/alert-cli/src/main/resources/META-INF/rhq-serverplugin.xml b/modules/enterprise/server/plugins/alert-cli/src/main/resources/META-INF/rhq-serverplugin.xml
index 6408c88..cb3ed60 100644
--- a/modules/enterprise/server/plugins/alert-cli/src/main/resources/META-INF/rhq-serverplugin.xml
+++ b/modules/enterprise/server/plugins/alert-cli/src/main/resources/META-INF/rhq-serverplugin.xml
@@ -14,6 +14,43 @@
Used to execute a CLI script.
</serverplugin:help>
+ <serverplugin:plugin-component class="CliComponent">
+ <serverplugin:control name="checkAlertsValidity">
+ <serverplugin:results>
+ <c:list-property name="misconfiguredAlertDefs" displayName="Misconfigured Alert Definitions">
+ <c:description>
+ Alert scripts run authenticated as a user specified in their definitions. If a user is deleted,
+ the alert definition will contain invalid reference to that user and needs to be update manually.
+ This operation returns a list of such misconfigured alert definitions.
+ </c:description>
+ <c:map-property name="alertDefinition">
+ <c:simple-property name="resourceId" />
+ <c:simple-property name="resourcePath" />
+ <c:simple-property name="alertDefinitionName" />
+ </c:map-property>
+ </c:list-property>
+ </serverplugin:results>
+ </serverplugin:control>
+
+ <!-- TODO define the args and results of this operation -->
+ <serverplugin:control name="reassignAlerts" description="Re-assign alerts to run as different users" />
+ </serverplugin:plugin-component>
+
+ <serverplugin:plugin-configuration>
+ <c:simple-property name="uploadRepoName" displayName="Repo to manually upload scripts to" required="true" default="Uploaded Scripts">
+ <c:description>
+ When manually uploading a script while defining an alert notification, the script will be stored in this repo.
+ </c:description>
+ </c:simple-property>
+ <c:list-property name="packageTypes" displayName="Package Types" required="true">
+ <c:description>
+ The list of package types that will be considered scripts. Any package of those types in any repo will be
+ considered a script and will be available for choosing as an alert script.
+ </c:description>
+ <c:simple-property name="packageType" displayName="Package Type" type="string" required="true"/>
+ </c:list-property>
+ </serverplugin:plugin-configuration>
+
<!-- How does this sender show up in drop downs etc -->
<short-name>CLI Script</short-name>
commit 55a3aaaae7364761f895fe4e261660cb6f1be427
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Wed Jan 26 18:51:16 2011 +0100
Adding support for finalization and validation of the alert parameters and extra parameters by the alert senders.
The default impl does nothing but the facility will be used by the CliSender to actually validate the user credentials
provided by the GUI and store just a userId in the configuration stored in the DB.
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertDefinitionManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertDefinitionManagerBean.java
index c5507cb..5537c48 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertDefinitionManagerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertDefinitionManagerBean.java
@@ -78,6 +78,7 @@ public class AlertDefinitionManagerBean implements AlertDefinitionManagerLocal,
private AuthorizationManagerLocal authorizationManager;
@EJB
private AlertDefinitionManagerLocal alertDefinitionManager;
+
@EJB
@IgnoreDependency
private AlertManagerLocal alertManager;
@@ -85,6 +86,10 @@ public class AlertDefinitionManagerBean implements AlertDefinitionManagerLocal,
@EJB
private StatusManagerLocal agentStatusManager;
+ @EJB
+ @IgnoreDependency
+ private AlertNotificationManagerLocal alertNotificationManager;
+
private boolean checkViewPermission(Subject subject, AlertDefinition alertDefinition) {
if (alertDefinition.getResourceType() != null) { // an alert template
return authorizationManager.hasGlobalPermission(subject, Permission.MANAGE_SETTINGS);
@@ -530,6 +535,7 @@ public class AlertDefinitionManagerBean implements AlertDefinitionManagerLocal,
}
fixRecoveryId(oldAlertDefinition);
+
AlertDefinition newAlertDefinition = entityManager.merge(oldAlertDefinition);
if (isResourceLevel
@@ -611,9 +617,9 @@ public class AlertDefinitionManagerBean implements AlertDefinitionManagerLocal,
+ "' is a trending metric, and thus will never have baselines calculated for it.");
}
}
- }
-
- return;
+ }
+
+ alertNotificationManager.finalizeNotifications(alertDefinition.getAlertNotifications());
}
private void notifyAlertConditionCacheManager(Subject subject, String methodName, AlertDefinition alertDefinition,
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertNotificationManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertNotificationManagerBean.java
index 1a1ae19..030b586 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertNotificationManagerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertNotificationManagerBean.java
@@ -20,8 +20,10 @@ package org.rhq.enterprise.server.alert;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collections;
import java.util.HashSet;
import java.util.List;
+import java.util.Map;
import java.util.Set;
import javax.ejb.EJB;
@@ -40,13 +42,20 @@ import org.rhq.core.domain.alert.AlertDefinition;
import org.rhq.core.domain.alert.AlertDefinitionContext;
import org.rhq.core.domain.alert.notification.AlertNotification;
import org.rhq.core.domain.auth.Subject;
+import org.rhq.core.domain.configuration.AbstractPropertyMap;
+import org.rhq.core.domain.configuration.Property;
+import org.rhq.core.domain.configuration.PropertyList;
+import org.rhq.core.domain.configuration.PropertyMap;
+import org.rhq.core.domain.configuration.PropertySimple;
import org.rhq.core.domain.configuration.definition.ConfigurationDefinition;
import org.rhq.core.domain.plugin.PluginKey;
import org.rhq.enterprise.server.RHQConstants;
import org.rhq.enterprise.server.auth.SubjectManagerLocal;
import org.rhq.enterprise.server.plugin.ServerPluginsLocal;
+import org.rhq.enterprise.server.plugin.pc.alert.AlertSender;
import org.rhq.enterprise.server.plugin.pc.alert.AlertSenderInfo;
import org.rhq.enterprise.server.plugin.pc.alert.AlertSenderPluginManager;
+import org.rhq.enterprise.server.plugin.pc.alert.AlertSenderValidationResults;
import org.rhq.enterprise.server.plugin.pc.alert.CustomAlertSenderBackingBean;
import org.rhq.enterprise.server.xmlschema.generated.serverplugin.alert.AlertPluginDescriptorType;
@@ -296,6 +305,26 @@ public class AlertNotificationManagerBean implements AlertNotificationManagerLoc
return notification;
}
+ public boolean finalizeNotifications(List<AlertNotification> notifications) {
+ boolean hasErrors = false;
+
+ AlertSenderPluginManager pluginManager = alertManager.getAlertPluginManager();
+
+ for(AlertNotification notification : notifications) {
+ AlertSender<?> sender = pluginManager.getAlertSenderForNotification(notification);
+
+ AlertSenderValidationResults validation = sender.validateAndFinalizeConfiguration();
+
+ notification.setConfiguration(validation.getAlertParameters());
+ notification.setExtraConfiguration(validation.getExtraParameters());
+
+ hasErrors = hasErrors || hasErrors(validation.getAlertParameters()) ||
+ hasErrors(validation.getExtraParameters());
+ }
+
+ return hasErrors;
+ }
+
public int cleanseAlertNotificationBySubject(int subjectId) {
return cleanseParmaeterValueForAlertSender("System Users", "subjectId", String.valueOf(subjectId));
}
@@ -313,4 +342,45 @@ public class AlertNotificationManagerBean implements AlertNotificationManagerLoc
return affectedRows;
}
+ private boolean hasErrors(AbstractPropertyMap configuration) {
+ if (configuration instanceof PropertyMap) {
+ if (((PropertyMap)configuration).getErrorMessage() != null) {
+ return true;
+ }
+ }
+
+ for(Map.Entry<String, Property> entry : configuration.getMap().entrySet()) {
+ if (hasErrors(entry.getValue())) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ private boolean hasErrors(PropertyList list) {
+ if (list.getErrorMessage() != null) {
+ return true;
+ }
+
+ for(Property p : list.getList()) {
+ if (hasErrors(p)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ private boolean hasErrors(Property property) {
+ if (property instanceof PropertySimple) {
+ return property.getErrorMessage() != null;
+ } else if (property instanceof PropertyList) {
+ return hasErrors((PropertyList) property);
+ } else if (property instanceof PropertyMap) {
+ return hasErrors((AbstractPropertyMap)property);
+ } else {
+ return false;
+ }
+ }
}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertNotificationManagerLocal.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertNotificationManagerLocal.java
index 8a137e0..ff222fc 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertNotificationManagerLocal.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertNotificationManagerLocal.java
@@ -31,8 +31,8 @@ import org.rhq.enterprise.server.plugin.pc.alert.CustomAlertSenderBackingBean;
/**
* @author Joseph Marques
+ * @author Lukas Krejci
*/
-
@Local
public interface AlertNotificationManagerLocal {
@@ -42,15 +42,17 @@ public interface AlertNotificationManagerLocal {
* @param alertDefinitionId Id of the alert definition
* @param senderName shortName of the {@link AlertSender}
* @param configuration Properties for this alert sender.
+ * @throws AlertNotificationValidationException if the alert sender of the notification failed to finalize and validate the provided notification's configuration
*/
- AlertNotification addAlertNotification(Subject user, int alertDefinitionId, AlertNotification notification);
+ AlertNotification addAlertNotification(Subject user, int alertDefinitionId, AlertNotification notification) throws AlertDefinitionUpdateException, AlertNotificationValidationException;
/**
* Persist changes to the passed {@link AlertNotification}
*
* @param notification
+ * @throws AlertNotificationValidationException if the alert sender of the notification failed to finalize and validate the notification's configuration
*/
- void updateAlertNotification(Subject subject, int alertDefinitionId, AlertNotification notification);
+ void updateAlertNotification(Subject subject, int alertDefinitionId, AlertNotification notification) throws AlertDefinitionUpdateException, AlertNotificationValidationException;
/**
* Remove the passed notifications from the passed alert definition (all identified by their id)
@@ -61,6 +63,21 @@ public interface AlertNotificationManagerLocal {
*/
int removeNotifications(Subject subject, Integer alertDefinitionId, Integer[] notificationIds);
+ /**
+ * This method calls out to the alert senders responsible to individual notifications and ask
+ * them to finalize and validate the notifications before they are processed further.
+ * This gives the alert senders the chance to transform their configurations from what's being
+ * input by the user to what needs to be persisted and to perform validation of the configurations.
+ * <p>
+ * The notifications can be modified during this call. New properties can be added to their configurations, etc.
+ *
+ * @param notifications the notifications to process
+ * @return true if everything went ok, false if the validation fails. In this case one or more properties
+ * in the configuration or extra configuration of one or more of the notifications contains an error message
+ * describing the error.
+ */
+ boolean finalizeNotifications(List<AlertNotification> notifications);
+
int purgeOrphanedAlertNotifications();
/**
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertNotificationValidationException.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertNotificationValidationException.java
new file mode 100644
index 0000000..636c45f
--- /dev/null
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertNotificationValidationException.java
@@ -0,0 +1,49 @@
+/*
+ * 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 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.server.alert;
+
+
+/**
+ * Thrown when alert definition notifications validation fails during creation or update of
+ * alert definition.
+ *
+ * @author Lukas Krejci
+ */
+public class AlertNotificationValidationException extends AlertDefinitionException {
+
+ private static final long serialVersionUID = 1L;
+
+ public AlertNotificationValidationException() {
+ super();
+ }
+
+ public AlertNotificationValidationException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public AlertNotificationValidationException(String message) {
+ super(message);
+ }
+
+ public AlertNotificationValidationException(Throwable cause) {
+ super(cause);
+ }
+
+}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertTemplateManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertTemplateManagerBean.java
index 76c196c..d8ce44e 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertTemplateManagerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertTemplateManagerBean.java
@@ -232,7 +232,7 @@ public class AlertTemplateManagerBean implements AlertTemplateManagerLocal {
@RequiredPermission(Permission.MANAGE_SETTINGS)
@TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
public AlertDefinition updateAlertTemplate(Subject user, AlertDefinition alertTemplate, boolean purgeInternals)
- throws InvalidAlertDefinitionException, AlertDefinitionUpdateException {
+ throws InvalidAlertDefinitionException, AlertDefinitionUpdateException, AlertNotificationValidationException {
if (LOG.isDebugEnabled()) {
LOG.debug("updateAlertTemplate: " + alertTemplate);
}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/AlertSender.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/AlertSender.java
index de35d54..f204106 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/AlertSender.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/AlertSender.java
@@ -29,6 +29,7 @@ import org.rhq.core.domain.configuration.Configuration;
import org.rhq.core.domain.configuration.Property;
import org.rhq.core.domain.configuration.PropertyMap;
import org.rhq.core.domain.configuration.PropertySimple;
+import org.rhq.enterprise.server.plugin.pc.ControlResults;
import org.rhq.enterprise.server.plugin.pc.ServerPluginComponent;
import org.rhq.enterprise.server.plugin.pc.ServerPluginEnvironment;
@@ -99,6 +100,23 @@ public abstract class AlertSender<T extends ServerPluginComponent> {
return builder.toString();
}
+ /**
+ * Validates the alert and extra parameters. The results should be initialized with the current
+ * parameters of this alert sender and the erroneous properties should have their
+ * {@link Property#getErrorMessage() error messages} set.
+ * <p>
+ * The implementation is free to change (add/update/delete) properties in either of the configurations
+ * (i.e. finalize them). This is to support scenarios where the user inputs values that need to be
+ * further processed in an alert sender specific way before they get stored into the database.
+ * <p>
+ * The default implementation makes no changes to the configurations.
+ *
+ * @return the validation results
+ */
+ public AlertSenderValidationResults validateAndFinalizeConfiguration() {
+ return new AlertSenderValidationResults(alertParameters, extraParameters);
+ }
+
private String printProperty(Property property) {
if (property instanceof PropertySimple) {
return ((PropertySimple) property).getStringValue();
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/AlertSenderValidationResults.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/AlertSenderValidationResults.java
new file mode 100644
index 0000000..f235835
--- /dev/null
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/AlertSenderValidationResults.java
@@ -0,0 +1,46 @@
+/*
+ * 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 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.server.plugin.pc.alert;
+
+import org.rhq.core.domain.configuration.Configuration;
+
+/**
+ *
+ *
+ * @author Lukas Krejci
+ */
+public class AlertSenderValidationResults {
+
+ private Configuration alertParameters;
+ private Configuration extraParameters;
+
+ public AlertSenderValidationResults(Configuration alertParameters, Configuration extraParameters) {
+ this.alertParameters = alertParameters == null ? null : alertParameters.deepCopy();
+ this.extraParameters = extraParameters == null ? null : extraParameters.deepCopy();
+ }
+
+ public Configuration getAlertParameters() {
+ return alertParameters;
+ }
+
+ public Configuration getExtraParameters() {
+ return extraParameters;
+ }
+}
commit 54200aea1f94cdb2af93d5792006c3e9dfadb13d
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Wed Jan 26 18:47:03 2011 +0100
exposing slightly more data from the disambiguation report by exposing the full "resource" (i.e. id, name and type) also for the resource representing the "original".
This enables us to provide a generic disambiguated path renderer which is also included in this commit.
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/resource/composite/DisambiguationReport.java b/modules/core/domain/src/main/java/org/rhq/core/domain/resource/composite/DisambiguationReport.java
index 717721b..dd8e6ad 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/resource/composite/DisambiguationReport.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/resource/composite/DisambiguationReport.java
@@ -35,8 +35,7 @@ public class DisambiguationReport<T> implements Serializable {
private T original;
private List<Resource> parents;
- private ResourceType resourceType;
- private String name;
+ private Resource resource;
public static class ResourceType implements Serializable {
@@ -124,18 +123,21 @@ public class DisambiguationReport<T> implements Serializable {
}
}
- public DisambiguationReport() {
+ //GWT needs this
+ protected DisambiguationReport() {
}
- public DisambiguationReport(T original, List<Resource> parents, ResourceType resourceType, String name) {
+ public DisambiguationReport(T original, List<Resource> parents, Resource resource) {
this.original = original;
// this.parents = Collections.unmodifiableList(parents);
//spinder: the returned type is not Serializable and causes GWT serialization errors.
this.parents = parents;
- this.resourceType = resourceType;
- this.name = name;
+ this.resource = resource;
}
+ /**
+ * @return an object from the original result list that this disambiguation report represents.
+ */
public T getOriginal() {
return original;
}
@@ -149,23 +151,37 @@ public class DisambiguationReport<T> implements Serializable {
}
/**
+ * @return the resource that the {@link #getOriginal() original} represents.
+ */
+ public Resource getResource() {
+ return resource;
+ }
+
+ /**
* @return the ResourceType of the resource represented by the {@link #getOriginal()}
* or null if type disambiguation isn't needed.
+ *
+ * @deprecated use {@link #getResource()}.{@link Resource#getType() getType()}
*/
+ @Deprecated
public ResourceType getResourceType() {
- return resourceType;
+ return resource.getType();
}
/**
*
* @return the Resource name
+ *
+ * @deprecated use {@link #getResource()}.{@link Resource#getName() getName()}
*/
+ @Deprecated
public String getName() {
- return name;
+ return resource.getName();
}
public String toString() {
- return "DisambiguationReport(type=" + resourceType + ", parents=" + parents + ", original=" + original
- + ", name=" + name + ")";
+ return "DisambiguationReport(resource=" + resource + ", parents=" + parents + ", original=" + original
+ + ")";
}
+
}
\ No newline at end of file
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/util/DisambiguationReportRenderer.java b/modules/core/domain/src/main/java/org/rhq/core/domain/util/DisambiguationReportRenderer.java
new file mode 100644
index 0000000..c110f4b
--- /dev/null
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/util/DisambiguationReportRenderer.java
@@ -0,0 +1,683 @@
+/*
+ * 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 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.core.domain.util;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.rhq.core.domain.resource.composite.DisambiguationReport;
+import org.rhq.core.domain.resource.composite.DisambiguationReport.Resource;
+import org.rhq.core.domain.resource.composite.DisambiguationReport.ResourceType;
+
+/**
+ * This class can be used to produce a "pretty" textual representation of a {@link DisambiguationReport}.
+ * It supports a simple templating mechanism to configure the representation's format.
+ * <p>
+ * In the {@link DisambiguationReport}, a resource (either the resource being disambiguated or one of its parents)
+ * is represented by an instance of {@link DisambiguationReport.Resource}. The template uses this instance and its
+ * properties:
+ * <ul>
+ * <li>id - the resource id
+ * <li>name - the name of the resource
+ * <li>type - the type of the resource
+ * <ul>
+ * <li>name - the name of the resource type
+ * <li>plugin - the name of the plugin defining the resource type
+ * <li>singleton - a boolean whether the resource type is a singleton type or not
+ * </ul>
+ * </li>
+ * </ul>
+ * <p>
+ * The template has the following format:<br/>
+ * <code>...text...%([..text...])?<identifier>([...text...])?...text...</code>
+ * <p>
+ * It is best explained by an example. The {@link #DEFAULT_SEGMENT_TEMPLATE default segment template} looks like this:<br/>
+ * <code>%type.name[ ]%[(]type.plugin[) ]%name</code>
+ * <p>
+ * The <code>%type.name[ ]</code> is rendered as the name of the resource type followed by a space <b>IF</b> the
+ * resource type and the name are not null. If either of them is null <code>%type.name[ ]</code> renders as an
+ * empty string.
+ * <p>
+ * <code>%[(]type.plugin[) ]</code> renders as a bracket followed by the name of the plugin followed by a bracket and
+ * a space if both resource type and plugin are not null. If either of them is null, again the whole <code>%...</code> is
+ * rendered as an empty string.
+ * <p>
+ * The escape character is \.
+ *
+ * @author Lukas Krejci
+ */
+public class DisambiguationReportRenderer {
+
+ public enum RenderingOrder {
+ ASCENDING, DESCENDING
+ }
+
+ public static final String DEFAULT_SEGMENT_TEMPLATE = "%type.name[ ]%[(]type.plugin[) ]%name";
+ public static final String DEFALUT_SEGMENT_SEPARATOR = " > ";
+
+ private boolean includeResource = true;
+ private boolean includeParents = true;
+ private RenderingOrder renderingOrder = RenderingOrder.ASCENDING;
+ private String segmentTemplate = DEFAULT_SEGMENT_TEMPLATE;
+ private String singletonSegmentTemplate = DEFAULT_SEGMENT_TEMPLATE;
+ private String segmentSeparator = DEFALUT_SEGMENT_SEPARATOR;
+ private List<Segment> parsedTemplate = null;
+ private List<Segment> parsedSingletonTemplate = null;
+
+ /*
+ * The Field, ResourceField and ResourceTypeField constructs are here to
+ * prevent the usage of java reflection. This class is exposed (and probably
+ * used) in the GWT javascript user interface which does not support reflection.
+ *
+ * The below 3 classes are therefore here to mimic what we'd need from reflection
+ * at the cost of lost flexibility and additional verbosity.
+ *
+ * If the DisambiguationReport.Resource or DisambiguationReport.ResourceType classes
+ * change, the below enums will have to accomodate for that change. If we could use
+ * reflection, it would work generically..
+ */
+
+ private interface Field {
+ Object getValue(Object object);
+
+ Field getRepresentation();
+
+ Field getSiblingField(String name);
+ }
+
+ private enum ResourceField implements Field {
+ ANY("") {
+ public Object getValue(Object object) {
+ return null;
+ }
+
+ public Field getRepresentation() {
+ return null;
+ }
+ },
+ ID("id") {
+ public Object getValue(Object object) {
+ return ((Resource)object).getId();
+ }
+
+ public Field getRepresentation() {
+ return null;
+ }
+ },
+ NAME("name") {
+ public Object getValue(Object object) {
+ return ((Resource)object).getName();
+ }
+
+ public Field getRepresentation() {
+ return null;
+ }
+
+ },
+ TYPE("type") {
+ public Object getValue(Object object) {
+ return ((Resource)object).getType();
+ }
+
+ public Field getRepresentation() {
+ return ResourceTypeField.ANY;
+ }
+ };
+
+ private String name;
+
+ private ResourceField(String name) {
+ this.name = name;
+ }
+
+ public Field getSiblingField(String name) {
+ return getByName(name);
+ }
+
+ public static ResourceField getByName(String name) {
+ for(ResourceField f : ResourceField.values()) {
+ if (f.name.equals(name)) {
+ return f;
+ }
+ }
+
+ return null;
+ }
+ }
+
+ private enum ResourceTypeField implements Field {
+ ANY("") {
+ public Field getRepresentation() {
+ return null;
+ }
+
+ public Object getValue(Object object) {
+ return null;
+ }
+ },
+ NAME("name") {
+ public Field getRepresentation() {
+ return null;
+ }
+
+ public Object getValue(Object object) {
+ return ((ResourceType)object).getName();
+ }
+ },
+ PLUGIN("plugin") {
+ public Field getRepresentation() {
+ return null;
+ }
+
+ public Object getValue(Object object) {
+ return ((ResourceType)object).getPlugin();
+ }
+ },
+ SINGLETON("singleton") {
+ public Field getRepresentation() {
+ return null;
+ }
+
+ public Object getValue(Object object) {
+ return ((ResourceType)object).isSingleton();
+ }
+ };
+
+ private String name;
+
+ private ResourceTypeField(String name) {
+ this.name = name;
+ }
+
+ public Field getSiblingField(String name) {
+ return getByName(name);
+ }
+
+ public static ResourceTypeField getByName(String name) {
+ for(ResourceTypeField f : ResourceTypeField.values()) {
+ if (f.name.equals(name)) {
+ return f;
+ }
+ }
+
+ return null;
+ }
+ }
+
+ /**
+ * Segment represents a part of the template with some semantics.
+ * A segment is able to render itself using data from a resource.
+ *
+ * @author Lukas Krejci
+ */
+ private interface Segment {
+ void render(DisambiguationReport.Resource resource, StringBuilder bld);
+
+ /**
+ * Each segment holds an internal string builder to build up the data
+ * from the template it will later need to render itself.
+ *
+ * @return the internal string builder.
+ */
+ StringBuilder getCurrentString();
+ }
+
+ private static class TextSegment implements Segment {
+ public StringBuilder text = new StringBuilder();
+
+ public void render(DisambiguationReport.Resource resource, StringBuilder bld) {
+ if (text != null) {
+ bld.append(text);
+ }
+ }
+
+ public StringBuilder getCurrentString() {
+ return text;
+ }
+ }
+ private static class ResourceSegment implements Segment {
+ public String prefix;
+ public List<Field> fields = new ArrayList<Field>();
+ public String suffix;
+
+ public StringBuilder currentString = new StringBuilder();
+ public Field currentField = ResourceField.ANY;
+
+ public StringBuilder getCurrentString() {
+ return currentString;
+ }
+
+ public void render(DisambiguationReport.Resource resource, StringBuilder bld) {
+ String value = null;
+ if (fields != null && fields.size() > 0) {
+ Object object = resource;
+ for(Field f : fields) {
+ if (object == null) {
+ break;
+ }
+ object = f.getValue(object);
+ }
+
+ if (object != null) {
+ value = object.toString();
+ }
+ }
+
+ if (value != null) {
+ if (prefix != null) {
+ bld.append(prefix);
+ }
+
+ bld.append(value.toString());
+
+ if (suffix != null) {
+ bld.append(suffix);
+ }
+ }
+ }
+ }
+
+ private static class SegmentAndState {
+ public Segment segment;
+ public ParserState state;
+ public ParserState lastState;
+ }
+
+ /**
+ * The guts of the template parser. Each state can process a single character and modify the state for the next
+ * char.
+ */
+ private enum ParserState {
+ START {
+ public SegmentAndState process(SegmentAndState seg, Character c) {
+ if (c == null) {
+ return null;
+ }
+
+ seg.lastState = null;
+
+ switch(c) {
+ case '%':
+ seg.segment = new ResourceSegment();
+ seg.state = ParserState.IN_RESOURCE_START;
+ break;
+ case '\\':
+ seg.segment = new TextSegment();
+ seg.lastState = ParserState.IN_TEXT;
+ seg.state = ParserState.ESCAPING;
+ break;
+ default:
+ seg.segment = new TextSegment();
+ seg.segment.getCurrentString().append(c);
+ seg.state = ParserState.IN_TEXT;
+ break;
+ }
+
+ return seg;
+ }
+ }, IN_TEXT {
+ public SegmentAndState process(SegmentAndState seg, Character c) {
+ if (c == null) {
+ return null;
+ }
+
+ seg.lastState = null;
+
+ switch(c) {
+ case '%':
+ seg.segment = new ResourceSegment();
+ seg.state = ParserState.IN_RESOURCE_START;
+ break;
+ case '\\':
+ seg.lastState = seg.state;
+ seg.state = ParserState.ESCAPING;
+ break;
+ default:
+ seg.segment.getCurrentString().append(c);
+ break;
+ }
+
+ return seg;
+ }
+ }, IN_RESOURCE_START {
+ public SegmentAndState process(SegmentAndState seg, Character c) {
+ if (c == null) {
+ return null;
+ }
+
+ seg.lastState = null;
+
+ switch(c) {
+ case '[':
+ seg.state = ParserState.IN_RESOURCE_PREFIX;
+ break;
+ default:
+ seg.segment.getCurrentString().append(c);
+ seg.state = ParserState.IN_RESOURCE_DEF;
+ break;
+ }
+
+ return seg;
+ }
+ }, IN_RESOURCE_PREFIX {
+ public SegmentAndState process(SegmentAndState seg, Character c) {
+ if (c == null) {
+ return null;
+ }
+
+ seg.lastState = null;
+
+ switch(c) {
+ case '\\':
+ seg.lastState = seg.state;
+ seg.state = ParserState.ESCAPING;
+ break;
+ case ']':
+ ((ResourceSegment)seg.segment).prefix = seg.segment.getCurrentString().toString();
+ ((ResourceSegment)seg.segment).currentString = new StringBuilder();
+ seg.state = ParserState.IN_RESOURCE_DEF;
+ break;
+ default:
+ seg.segment.getCurrentString().append(c);
+ break;
+ }
+
+ return seg;
+ }
+ }, IN_RESOURCE_DEF {
+ public SegmentAndState process(SegmentAndState seg, Character c) {
+ if (c == null) {
+ processField(seg);
+ return null;
+ }
+
+ seg.lastState = null;
+
+ switch(c) {
+ case '\\':
+ seg.lastState = seg.state;
+ seg.state = ParserState.ESCAPING;
+ break;
+ case '.':
+ processField(seg);
+ break;
+ case '%':
+ processField(seg);
+ seg.segment = new ResourceSegment();
+ seg.state = ParserState.IN_RESOURCE_START;
+ break;
+ case '[':
+ processField(seg);
+ seg.state = ParserState.IN_RESOURCE_SUFFIX;
+ break;
+ default:
+ if (isWhitespace(c)) {
+ processField(seg);
+ seg.segment = new TextSegment();
+ seg.segment.getCurrentString().append(c);
+ seg.state = ParserState.IN_TEXT;
+ } else {
+ seg.segment.getCurrentString().append(c);
+ }
+ break;
+ }
+
+ return seg;
+ }
+
+ //this would have been better implemented if we had reflection in GWT.
+ private void processField(SegmentAndState seg) {
+ ResourceSegment s = (ResourceSegment)seg.segment;
+ String fieldName = s.getCurrentString().toString();
+ try {
+ Field field = s.currentField.getSiblingField(fieldName);
+ s.fields.add(field);
+ s.currentField = field.getRepresentation();
+ s.currentString = new StringBuilder();
+ } catch(Exception e) {
+ s.fields = null;
+ seg.state = ParserState.START;
+ }
+ }
+
+ private boolean isWhitespace(char c) {
+ //if we had the Character class in GWT...
+ //return Character.isWhitespace(c)
+
+ return c == ' ' || c == '\n' || c == '\t';
+ }
+ }, IN_RESOURCE_SUFFIX {
+ public SegmentAndState process(SegmentAndState seg, Character c) {
+ if (c == null) {
+ return null;
+ }
+
+ seg.lastState = null;
+
+ switch(c) {
+ case '\\':
+ seg.lastState = seg.state;
+ seg.state = ParserState.ESCAPING;
+ break;
+ case ']':
+ ((ResourceSegment)seg.segment).suffix = seg.segment.getCurrentString().toString();
+ ((ResourceSegment)seg.segment).currentString = new StringBuilder();
+ seg.state = ParserState.START;
+ break;
+ default:
+ seg.segment.getCurrentString().append(c);
+ break;
+ }
+
+ return seg;
+ }
+ }, ESCAPING {
+ public SegmentAndState process(SegmentAndState seg, Character c) {
+ if (c == null) {
+ return null;
+ }
+
+ seg.segment.getCurrentString().append(c);
+ seg.state = seg.lastState;
+ seg.lastState = null;
+
+ return seg;
+ }
+
+ };
+
+ public abstract SegmentAndState process(SegmentAndState currentSegment, Character c);
+ }
+
+ public DisambiguationReportRenderer() {
+ parsedTemplate = parse(segmentTemplate);
+ parsedSingletonTemplate = parse(singletonSegmentTemplate);
+ }
+
+ /**
+ * @return the includeResource
+ */
+ public boolean isIncludeResource() {
+ return includeResource;
+ }
+
+ /**
+ * @param includeResource the includeResource to set
+ */
+ public void setIncludeResource(boolean includeResource) {
+ this.includeResource = includeResource;
+ }
+
+ /**
+ * @return the includeParents
+ */
+ public boolean isIncludeParents() {
+ return includeParents;
+ }
+
+ /**
+ * @param includeParents the includeParents to set
+ */
+ public void setIncludeParents(boolean includeParents) {
+ this.includeParents = includeParents;
+ }
+
+ /**
+ * @return the renderingOrder
+ */
+ public RenderingOrder getRenderingOrder() {
+ return renderingOrder;
+ }
+
+ /**
+ * @param renderingOrder the renderingOrder to set
+ */
+ public void setRenderingOrder(RenderingOrder renderingOrder) {
+ this.renderingOrder = renderingOrder;
+ }
+
+ /**
+ * @return the segmentTemplate
+ */
+ public String getSegmentTemplate() {
+ return segmentTemplate;
+ }
+
+ /**
+ * @param segmentTemplate the segmentTemplate to set
+ */
+ public void setSegmentTemplate(String segmentTemplate) {
+ this.segmentTemplate = segmentTemplate;
+ parsedTemplate = parse(segmentTemplate);
+ }
+
+ /**
+ * @return the singletonSegmentTemplate
+ */
+ public String getSingletonSegmentTemplate() {
+ return singletonSegmentTemplate;
+ }
+
+ /**
+ * @param singletonSegmentTemplate the singletonSegmentTemplate to set
+ */
+ public void setSingletonSegmentTemplate(String singletonSegmentTemplate) {
+ this.singletonSegmentTemplate = singletonSegmentTemplate;
+ parsedSingletonTemplate = parse(singletonSegmentTemplate);
+ }
+
+ /**
+ * @return the segmentSeparator
+ */
+ public String getSegmentSeparator() {
+ return segmentSeparator;
+ }
+
+ /**
+ * @param segmentSeparator the segmentSeparator to set
+ */
+ public void setSegmentSeparator(String segmentSeparator) {
+ this.segmentSeparator = segmentSeparator;
+ }
+
+ public String render(DisambiguationReport<?> report) {
+ if (parsedTemplate != null) {
+ StringBuilder bld = new StringBuilder();
+
+ List<DisambiguationReport.Resource> resources = new ArrayList<DisambiguationReport.Resource>();
+
+ switch(renderingOrder) {
+ case ASCENDING:
+ if (includeResource) {
+ resources.add(report.getResource());
+ }
+ if (includeParents) {
+ resources.addAll(report.getParents());
+ }
+ break;
+ case DESCENDING:
+ if (includeParents) {
+ ArrayList<DisambiguationReport.Resource> reverseCopy = new ArrayList<DisambiguationReport.Resource>(report.getParents());
+ Collections.reverse(reverseCopy);
+ resources.addAll(reverseCopy);
+ }
+
+ if (includeResource) {
+ resources.add(report.getResource());
+ }
+ break;
+ default:;
+ }
+
+ String separator = getSegmentSeparator();
+ for(DisambiguationReport.Resource r : resources) {
+ renderResource(r, bld);
+ bld.append(separator);
+ }
+
+ if (resources.size() > 0) {
+ bld.replace(bld.length() - separator.length(), bld.length(), "");
+ }
+
+ return bld.toString();
+ } else {
+ return null;
+ }
+ }
+
+ private List<Segment> parse(String template) {
+ List<Segment> ret = new ArrayList<Segment>();
+
+ int idx = 0;
+
+ SegmentAndState currentState = new SegmentAndState();
+ currentState.state = ParserState.START;
+
+ while(idx < template.length()) {
+ char c = template.charAt(idx);
+ Segment lastSegment = currentState.segment;
+ currentState = currentState.state.process(currentState, c);
+
+ //if the state created a new segment, store it in the results and
+ //continue with it. yes, the reference equality is what we want here
+ if (lastSegment != currentState.segment) {
+ ret.add(currentState.segment);
+ }
+
+ ++idx;
+ }
+
+ currentState.state.process(currentState, null);
+
+ return ret;
+ }
+
+ private void renderResource(DisambiguationReport.Resource resource, StringBuilder bld) {
+ List<Segment> template = parsedTemplate;
+ if (resource.getType() != null && resource.getType().isSingleton()) {
+ template = parsedSingletonTemplate;
+ }
+
+ for(Segment seg : template) {
+ seg.render(resource, bld);
+ }
+ }
+}
diff --git a/modules/core/domain/src/test/java/org/rhq/core/domain/util/DisambiguationReportRendererTest.java b/modules/core/domain/src/test/java/org/rhq/core/domain/util/DisambiguationReportRendererTest.java
new file mode 100644
index 0000000..0fc4782
--- /dev/null
+++ b/modules/core/domain/src/test/java/org/rhq/core/domain/util/DisambiguationReportRendererTest.java
@@ -0,0 +1,184 @@
+/*
+ * 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 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.core.domain.util;
+
+import static org.testng.Assert.assertEquals;
+import static org.rhq.core.domain.resource.composite.DisambiguationReport.*;
+
+import java.util.ArrayList;
+import java.util.Collections;
+
+import org.testng.annotations.Test;
+
+import org.rhq.core.domain.resource.composite.DisambiguationReport;
+
+/**
+ *
+ *
+ * @author Lukas Krejci
+ */
+public class DisambiguationReportRendererTest {
+
+ private static final String RESOURCE_NAME = "testResource";
+ private static final String RESOURCE_TYPE_NAME = "testResourceType";
+ private static final String RESOURCE_TYPE_PLUGIN_NAME = "testPlugin";
+ private static final int RESOURCE_ID = 0;
+ private static final String PARENT_RESOURCE_NAME = "testResourceParent";
+ private static final String PARENT_RESOURCE_TYPE_NAME = "testResourceTypeParent";
+ private static final String PARENT_RESOURCE_TYPE_PLUGIN_NAME = "testPluginParent";
+
+ private static final String TEST_NO_PARENTS_TEMPLATE = "seeing %[a resource called ]name[ ]%[with an id of ]id%[ in a type ]type.name%[ in a plugin ]type.plugin[].";
+ private static final String EXPECTED_NO_PARENTS_RENDERING_FULL = "seeing a resource called " + RESOURCE_NAME
+ + " with an id of " + RESOURCE_ID + " in a type " + RESOURCE_TYPE_NAME + " in a plugin "
+ + RESOURCE_TYPE_PLUGIN_NAME + ".";
+ private static final String EXPECTED_NO_PARENTS_RENDERING_NO_PLUGIN = "seeing a resource called " + RESOURCE_NAME
+ + " with an id of " + RESOURCE_ID + " in a type " + RESOURCE_TYPE_NAME + ".";
+ private static final String EXPECTED_NO_PARENTS_RENDERING_NO_TYPE = "seeing a resource called " + RESOURCE_NAME
+ + " with an id of " + RESOURCE_ID + ".";
+
+ private static final String TEST_PARENTS_TEMPLATE = "%type.name[ ]%[(]type.plugin[) ]%name";
+ private static final String TEST_PARENTS_SINGLETON_TEMPLATE = "%name (\\%singleton)";
+ private static final String ASCENDING_SEPARATOR = " -> ";
+ private static final String DESCENDING_SEPARATOR = " <- ";
+ private static final int NOF_PARENTS = 2;
+
+ private static final String EXPECTED_PARENTS_RENDERING_FULL_NO_SINGLETON_ASCENDING = RESOURCE_TYPE_NAME + " (" + RESOURCE_TYPE_PLUGIN_NAME + ") " + RESOURCE_NAME +
+ ASCENDING_SEPARATOR + PARENT_RESOURCE_TYPE_NAME + " (" + PARENT_RESOURCE_TYPE_PLUGIN_NAME + ") " + PARENT_RESOURCE_NAME + "1" +
+ ASCENDING_SEPARATOR + PARENT_RESOURCE_TYPE_NAME + " (" + PARENT_RESOURCE_TYPE_PLUGIN_NAME + ") " + PARENT_RESOURCE_NAME + "2";
+
+ private static final String EXPECTED_PARENTS_RENDERING_FULL_WITH_SINGLETON_ASCENDING = RESOURCE_TYPE_NAME + " (" + RESOURCE_TYPE_PLUGIN_NAME + ") " + RESOURCE_NAME +
+ ASCENDING_SEPARATOR + PARENT_RESOURCE_NAME + "1 (%singleton)" +
+ ASCENDING_SEPARATOR + PARENT_RESOURCE_TYPE_NAME + " (" + PARENT_RESOURCE_TYPE_PLUGIN_NAME + ") " + PARENT_RESOURCE_NAME + "2";
+
+ private static final String EXPECTED_PARENTS_RENDERING_FULL_NO_SINGLETON_DESCENDING =
+ PARENT_RESOURCE_TYPE_NAME + " (" + PARENT_RESOURCE_TYPE_PLUGIN_NAME + ") " + PARENT_RESOURCE_NAME + "2" +
+ DESCENDING_SEPARATOR + PARENT_RESOURCE_TYPE_NAME + " (" + PARENT_RESOURCE_TYPE_PLUGIN_NAME + ") " + PARENT_RESOURCE_NAME + "1" +
+ DESCENDING_SEPARATOR + RESOURCE_TYPE_NAME + " (" + RESOURCE_TYPE_PLUGIN_NAME + ") " + RESOURCE_NAME;
+
+ private static final String EXPECTED_PARENTS_RENDERING_FULL_WITH_SINGLETON_DESCENDING =
+ PARENT_RESOURCE_TYPE_NAME + " (" + PARENT_RESOURCE_TYPE_PLUGIN_NAME + ") " + PARENT_RESOURCE_NAME + "2" +
+ DESCENDING_SEPARATOR + PARENT_RESOURCE_NAME + "1 (%singleton)" +
+ DESCENDING_SEPARATOR + RESOURCE_TYPE_NAME + " (" + RESOURCE_TYPE_PLUGIN_NAME + ") " + RESOURCE_NAME;
+
+ private static final String EXPECTED_PARENTS_RENDERING_MINIMAL_WITH_SINGLETON_ASCENDING = RESOURCE_NAME +
+ ASCENDING_SEPARATOR + PARENT_RESOURCE_NAME + "1 (%singleton)" +
+ ASCENDING_SEPARATOR + PARENT_RESOURCE_NAME + "2";
+
+ @Test
+ public void testNoParents() {
+ DisambiguationReport<?> report = getNoParentsTestReport(true, true);
+
+ DisambiguationReportRenderer renderer = new DisambiguationReportRenderer();
+
+ renderer.setIncludeParents(false);
+ renderer.setSegmentTemplate(TEST_NO_PARENTS_TEMPLATE);
+ renderer.setSingletonSegmentTemplate(TEST_NO_PARENTS_TEMPLATE);
+
+ String rendering = renderer.render(report);
+ assertEquals(rendering, EXPECTED_NO_PARENTS_RENDERING_FULL);
+
+ report = getNoParentsTestReport(true, false);
+ rendering = renderer.render(report);
+ assertEquals(rendering, EXPECTED_NO_PARENTS_RENDERING_NO_PLUGIN);
+
+ report = getNoParentsTestReport(false, false);
+ rendering = renderer.render(report);
+ assertEquals(rendering, EXPECTED_NO_PARENTS_RENDERING_NO_TYPE);
+ }
+
+ @Test
+ public void testParents() {
+ DisambiguationReport<?> report = getParentsTestReport(true, true, true, true, false);
+
+ DisambiguationReportRenderer renderer = new DisambiguationReportRenderer();
+ renderer.setSegmentTemplate(TEST_PARENTS_TEMPLATE);
+ renderer.setSingletonSegmentTemplate(TEST_PARENTS_SINGLETON_TEMPLATE);
+ renderer.setSegmentSeparator(ASCENDING_SEPARATOR);
+
+ String rendering = renderer.render(report);
+ assertEquals(rendering, EXPECTED_PARENTS_RENDERING_FULL_NO_SINGLETON_ASCENDING);
+
+ renderer.setSegmentSeparator(DESCENDING_SEPARATOR);
+ renderer.setRenderingOrder(DisambiguationReportRenderer.RenderingOrder.DESCENDING);
+ rendering = renderer.render(report);
+ assertEquals(rendering, EXPECTED_PARENTS_RENDERING_FULL_NO_SINGLETON_DESCENDING);
+
+ report = getParentsTestReport(true, true, true, true, true);
+
+ renderer.setSegmentSeparator(ASCENDING_SEPARATOR);
+ renderer.setRenderingOrder(DisambiguationReportRenderer.RenderingOrder.ASCENDING);
+ rendering = renderer.render(report);
+ assertEquals(rendering, EXPECTED_PARENTS_RENDERING_FULL_WITH_SINGLETON_ASCENDING);
+
+ renderer.setSegmentSeparator(DESCENDING_SEPARATOR);
+ renderer.setRenderingOrder(DisambiguationReportRenderer.RenderingOrder.DESCENDING);
+ rendering = renderer.render(report);
+ assertEquals(rendering, EXPECTED_PARENTS_RENDERING_FULL_WITH_SINGLETON_DESCENDING);
+
+ report = getParentsTestReport(false, false, false, false, true);
+
+ renderer.setSegmentSeparator(ASCENDING_SEPARATOR);
+ renderer.setRenderingOrder(DisambiguationReportRenderer.RenderingOrder.ASCENDING);
+ rendering = renderer.render(report);
+ assertEquals(rendering, EXPECTED_PARENTS_RENDERING_MINIMAL_WITH_SINGLETON_ASCENDING);
+ }
+
+ private <T> DisambiguationReport<T> getNoParentsTestReport(boolean includeType, boolean includePlugin) {
+ return new DisambiguationReport<T>(null, Collections.<Resource> emptyList(),
+ createResource(0, includeType, includePlugin, false));
+ }
+
+ private <T> DisambiguationReport<T> getParentsTestReport(boolean includeType, boolean includePlugin, boolean includeParentsType, boolean includeParentsPlugin, boolean firstParentSingleton) {
+ Resource resource = createResource(0, includeType, includePlugin, false);
+ Resource firstParent = createResource(1, includeParentsType, includeParentsPlugin, firstParentSingleton);
+
+ ArrayList<Resource> parents = new ArrayList<Resource>();
+ parents.add(firstParent);
+
+ for(int i = 2; i <= NOF_PARENTS; ++i) {
+ Resource parent = createResource(i, includeParentsType, includeParentsPlugin, false);
+ parents.add(parent);
+ }
+
+ return new DisambiguationReport<T>(null, parents, resource);
+ }
+
+ private static Resource createResource(int parentage, boolean includeType, boolean includePlugin, boolean singleton) {
+ ResourceType type = null;
+
+ String resourceTypeName = parentage > 0 ? PARENT_RESOURCE_TYPE_NAME : RESOURCE_TYPE_NAME;
+ String pluginName = parentage > 0 ? PARENT_RESOURCE_TYPE_PLUGIN_NAME : RESOURCE_TYPE_PLUGIN_NAME;
+
+ if (includeType || singleton) {
+ type = new ResourceType(resourceTypeName, includePlugin ? pluginName
+ : null, singleton);
+ }
+
+ String name;
+
+ if (parentage == 0) {
+ name = RESOURCE_NAME;
+ } else {
+ name = PARENT_RESOURCE_NAME + parentage;
+ }
+
+ return new Resource(parentage, name, type);
+ }
+}
diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/legacy/portlet/recentlyApproved/ViewAction.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/legacy/portlet/recentlyApproved/ViewAction.java
index e3d4723..9c167cd 100644
--- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/legacy/portlet/recentlyApproved/ViewAction.java
+++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/legacy/portlet/recentlyApproved/ViewAction.java
@@ -154,7 +154,7 @@ public class ViewAction extends TilesAction {
}
public DisambiguatedRecentlyAddedResourceComposite(DisambiguationReport<RecentlyAddedResourceComposite> report) {
- super(report.getOriginal(), report.getParents(), report.getResourceType(), report.getName());
+ super(report.getOriginal(), report.getParents(), report.getResource());
children = new ArrayList<DisambiguatedRecentlyAddedResourceComposite>();
}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/disambiguation/MutableDisambiguationReport.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/disambiguation/MutableDisambiguationReport.java
index 8c4f78b..de0141f 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/disambiguation/MutableDisambiguationReport.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/disambiguation/MutableDisambiguationReport.java
@@ -99,7 +99,8 @@ public class MutableDisambiguationReport<T> {
realParents.add(p.getResource());
}
}
- return new DisambiguationReport<T>(original, realParents, resource.resourceType.getResourceType(), resource.name);
+
+ return new DisambiguationReport<T>(original, realParents, resource.getResource());
}
@Override
commit 3ff9c793cc2b0052c531acee6f2438434c8573dd
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Tue Jan 25 12:26:32 2011 +0100
CliSender implemented. Not so much the supporting infrastructure around it.
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/AlertDefinitionCriteria.java b/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/AlertDefinitionCriteria.java
index 5c84c62..c329527 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/AlertDefinitionCriteria.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/AlertDefinitionCriteria.java
@@ -53,7 +53,8 @@ public class AlertDefinitionCriteria extends Criteria {
private List<Integer> filterResourceGroupIds; // requires overrides
private Boolean filterEnabled;
private Boolean filterDeleted = false; // find enabled definitions by default
-
+ private List<String> filterNotificationSenderNames;
+
private boolean fetchAlerts;
private boolean fetchGroupAlertDefinition;
private boolean fetchConditions;
@@ -62,12 +63,13 @@ public class AlertDefinitionCriteria extends Criteria {
private PageOrdering sortName;
private PageOrdering sortPriority;
- public AlertDefinitionCriteria() {
+ public AlertDefinitionCriteria() {
filterOverrides.put("alertTemplateParentId", "parentId = ?");
filterOverrides.put("alertTemplateResourceTypeId", "resourceType.id = ?");
filterOverrides.put("alertTemplateResourceTypeName", "resourceType.name like ?");
filterOverrides.put("resourceIds", "resource.id IN ( ? )");
filterOverrides.put("resourceGroupIds", "resourceGroup.id IN ( ? )");
+ filterOverrides.put("notificationSenderNames", "alertNotifications.senderName IN ( ? )");
}
@Override
@@ -119,6 +121,11 @@ public class AlertDefinitionCriteria extends Criteria {
this.filterDeleted = filterDeleted;
}
+ public void addFilterNotificationNames(String... notificationNames) {
+ fetchAlertNotifications(true);
+ this.filterNotificationSenderNames = Arrays.asList(notificationNames);
+ }
+
public void fetchAlerts(boolean fetchAlerts) {
this.fetchAlerts = fetchAlerts;
}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertDefinitionManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertDefinitionManagerBean.java
index 03aba63..c5507cb 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertDefinitionManagerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertDefinitionManagerBean.java
@@ -707,7 +707,6 @@ public class AlertDefinitionManagerBean implements AlertDefinitionManagerLocal,
return queryRunner.execute();
}
- @Override
public String[] getAlertNotificationConfigurationPreview(Subject sessionSubject, AlertNotification[] notifications) {
if (notifications == null || notifications.length == 0) {
return new String[0];
diff --git a/modules/enterprise/server/plugins/alert-cli/src/main/java/org/rhq/enterprise/server/plugins/alertCli/CliSender.java b/modules/enterprise/server/plugins/alert-cli/src/main/java/org/rhq/enterprise/server/plugins/alertCli/CliSender.java
index 61d795a..b094beb 100644
--- a/modules/enterprise/server/plugins/alert-cli/src/main/java/org/rhq/enterprise/server/plugins/alertCli/CliSender.java
+++ b/modules/enterprise/server/plugins/alert-cli/src/main/java/org/rhq/enterprise/server/plugins/alertCli/CliSender.java
@@ -20,12 +20,17 @@
package org.rhq.enterprise.server.plugins.alertCli;
import java.io.BufferedReader;
+import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
+import java.io.OutputStream;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
+import java.io.PrintWriter;
+import java.nio.ByteBuffer;
+import java.nio.charset.Charset;
import java.util.Collections;
import javax.script.ScriptEngine;
@@ -42,6 +47,7 @@ import org.rhq.core.domain.alert.notification.SenderResult;
import org.rhq.core.domain.auth.Subject;
import org.rhq.core.domain.configuration.PropertySimple;
import org.rhq.core.domain.content.PackageVersion;
+import org.rhq.core.util.exception.ThrowableUtil;
import org.rhq.enterprise.client.LocalClient;
import org.rhq.enterprise.server.content.ContentSourceManagerLocal;
import org.rhq.enterprise.server.plugin.pc.ServerPluginComponent;
@@ -54,15 +60,21 @@ import org.rhq.enterprise.server.util.LookupUtil;
* @author Lukas Krejci
*/
public class CliSender extends AlertSender<ServerPluginComponent> {
+
+ public static final String PROP_PACKAGE_ID = "packageId";
+ public static final String PROP_USER_ID = "userId";
+
private static final Log LOG = LogFactory.getLog(CliSender.class);
public SenderResult send(Alert alert) {
SenderResult result = new SenderResult();
BufferedReader reader = null;
try {
- ScriptEngine engine = getScriptEngine(alert);
+ ByteArrayOutputStream scriptOutputStream = new ByteArrayOutputStream();
+
+ ScriptEngine engine = getScriptEngine(alert, scriptOutputStream);
- PropertySimple packageIdProp = alertParameters.getSimple("packageId");
+ PropertySimple packageIdProp = alertParameters.getSimple(PROP_PACKAGE_ID);
if (packageIdProp == null) {
return SenderResult
@@ -79,14 +91,19 @@ public class CliSender extends AlertSender<ServerPluginComponent> {
reader = new BufferedReader(new InputStreamReader(packageBits));
- Object ret = engine.eval(reader);
-
- //TODO what to do with the return value, if any
+ engine.eval(reader);
+ String scriptOutput = scriptOutputStream.toString(Charset.defaultCharset().name());
+
+ result.setSummary(scriptOutput);
+
+ result.addSuccessMessage("The script executed successfully. Its output is stored in the summary.");
+
return result;
- } catch (Exception e) {
- //TODO I don't like this
+ } catch (IllegalArgumentException e) {
return SenderResult.getSimpleFailure(e.getMessage());
+ } catch (Exception e) {
+ return SenderResult.getSimpleFailure(ThrowableUtil.getAllMessages(e));
} finally {
if (reader != null) {
try {
@@ -98,13 +115,19 @@ public class CliSender extends AlertSender<ServerPluginComponent> {
}
}
- private ScriptEngine getScriptEngine(Alert alert) throws ScriptException, IOException {
- Subject overlord = LookupUtil.getSubjectManager().getOverlord();
-
- LocalClient client = new LocalClient(overlord);
+ private ScriptEngine getScriptEngine(Alert alert, OutputStream scriptOutput) throws ScriptException, IOException, IllegalArgumentException {
+ int userId = alertParameters.getSimple(PROP_USER_ID).getIntegerValue();
+
+ Subject user = LookupUtil.getSubjectManager().getSubjectById(userId);
+
+ if (user == null) {
+ throw new IllegalArgumentException("The script cannot run because the user (id " + userId + ") configured to run it doesn't exist anymore.");
+ }
+
+ LocalClient client = new LocalClient(user);
- //TODO define some meaningful printwriter
- StandardBindings bindings = new StandardBindings(null, client);
+ PrintWriter output = new PrintWriter(scriptOutput);
+ StandardBindings bindings = new StandardBindings(output, client);
bindings.put("alert", alert);
return ScriptEngineFactory.getScriptEngine("JavaScript", new PackageFinder(Collections.<File> emptyList()),
diff --git a/modules/enterprise/server/plugins/alert-cli/src/main/resources/META-INF/rhq-serverplugin.xml b/modules/enterprise/server/plugins/alert-cli/src/main/resources/META-INF/rhq-serverplugin.xml
index ffcbb4b..6408c88 100644
--- a/modules/enterprise/server/plugins/alert-cli/src/main/resources/META-INF/rhq-serverplugin.xml
+++ b/modules/enterprise/server/plugins/alert-cli/src/main/resources/META-INF/rhq-serverplugin.xml
@@ -22,5 +22,6 @@
<alert-configuration>
<c:simple-property name="packageId" type="integer" required="true" description="The id of the package containing the script to execute."/>
+ <c:simple-property name="userId" type="integer" required="true" description="The user the script will be run as."/>
</alert-configuration>
</alert-plugin>
\ No newline at end of file
commit b8e6d9bb7c056043ce828b6d11acf9964ef036b5
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Tue Jan 25 12:08:06 2011 +0100
moving OSGiVersionComparator from core-util to core-domain so that GWT compilation has access to its source.
This is not ideal, because logically the OSGiVersionComparator should belong to just util, but in order to support
the GWT compilation, we'd have to create a whole new GWT module from core-util just because of this single class that
doesn't seem to be used anywhere else anyway.
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/content/PackageVersion.java b/modules/core/domain/src/main/java/org/rhq/core/domain/content/PackageVersion.java
index 8d2b9b4..8b7735d 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/content/PackageVersion.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/content/PackageVersion.java
@@ -47,7 +47,7 @@ import org.hibernate.annotations.NamedQuery;
import org.rhq.core.domain.configuration.Configuration;
import org.rhq.core.domain.resource.ProductVersion;
-import org.rhq.core.util.OSGiVersionComparator;
+import org.rhq.core.domain.util.OSGiVersionComparator;
/**
* Represents a specific version of a {@link Package}. This does <i>not</i> represent an installed package found
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/util/OSGiVersionComparator.java b/modules/core/domain/src/main/java/org/rhq/core/domain/util/OSGiVersionComparator.java
new file mode 100644
index 0000000..1f3936d
--- /dev/null
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/util/OSGiVersionComparator.java
@@ -0,0 +1,94 @@
+ /*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2008 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.core.domain.util;
+
+import java.util.Comparator;
+
+/**
+ * The specification for what makes up an OSGi compliant version string and how they can be compared was taken from
+ * here:
+ * http://help.eclipse.org/help31/index.jsp?topic=/org.eclipse.platform.doc....
+ *
+ * @author Charles Crouch
+ *
+ */
+public class OSGiVersionComparator implements Comparator<String> {
+ public OSGiVersionComparator() {
+ }
+
+ public int compare(String string1, String string2) {
+ Version ver1 = new Version(string1);
+ Version ver2 = new Version(string2);
+
+ int result = ver1.major - ver2.major;
+ if (result == 0) {
+ result = ver1.minor - ver2.minor;
+ if (result == 0) {
+ result = ver1.micro - ver2.micro;
+ if (result == 0) {
+ result = ver1.qualifier.compareTo(ver2.qualifier);
+ }
+ }
+ }
+
+ return result;
+ }
+
+ private class Version {
+ int major;
+ int minor;
+ int micro;
+ String qualifier = "";
+
+ Version(String version) {
+ String[] parts = version.split("\\.");
+
+ try {
+ switch (parts.length) {
+ case 4: {
+ qualifier = parts[3];
+ }
+
+ case 3: {
+ micro = Integer.parseInt(parts[2]);
+ }
+
+ case 2: {
+ minor = Integer.parseInt(parts[1]);
+ }
+
+ case 1: {
+ major = Integer.parseInt(parts[0]);
+ break;
+ }
+
+ default: {
+ throw new IllegalArgumentException("Malformed version string [" + version + "]");
+ }
+ }
+ } catch (NumberFormatException e) {
+ throw new IllegalArgumentException("Malformed version string [" + version + "]");
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/modules/core/domain/src/test/java/org/rhq/core/domain/util/OSGiVersionComparatorTest.java b/modules/core/domain/src/test/java/org/rhq/core/domain/util/OSGiVersionComparatorTest.java
new file mode 100644
index 0000000..d5959ea
--- /dev/null
+++ b/modules/core/domain/src/test/java/org/rhq/core/domain/util/OSGiVersionComparatorTest.java
@@ -0,0 +1,82 @@
+ /*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2008 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.core.domain.util;
+
+import org.rhq.core.domain.util.OSGiVersionComparator;
+
+import junit.framework.TestCase;
+
+public class OSGiVersionComparatorTest extends TestCase {
+ public OSGiVersionComparatorTest(String arg0) {
+ super(arg0);
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ }
+
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+ /*
+ * Test method for 'net.hyperic.hq.ui.action.resource.common.patch.JBossONVersionComparator.compare(Object, Object)'
+ */
+ public void testCompare() {
+ OSGiVersionComparator comparator = new OSGiVersionComparator();
+
+ assertTrue("1.2 > 1.1", comparator.compare("1.2", "1.1") > 0);
+ assertTrue("1.1 < 1.2", comparator.compare("1.1", "1.2") < 0);
+ assertTrue("1.0 = 1.0", comparator.compare("1.0", "1.0") == 0);
+ assertTrue("9.9 < 9.22", comparator.compare("9.9", "9.22") < 0);
+ assertTrue("9.9 < 10.2", comparator.compare("9.9", "10.2") < 0);
+ assertTrue("9 < 10", comparator.compare("9", "10") < 0);
+ assertTrue("1.2.13.BETA > 1.2.13.ALPHA", comparator.compare("1.2.13.BETA", "1.2.13.ALPHA") > 0);
+ assertTrue("4.0.4.GA_CP_2006_06 > 4.0.4.GA", comparator.compare("4.0.4.GA_CP_2006_06", "4.0.4.GA") > 0);
+ }
+
+ public void testInvalidComparisons() {
+ OSGiVersionComparator comparator = new OSGiVersionComparator();
+ try {
+ assertTrue("EA > 1.2", comparator.compare("EA", "1.2") > 0);
+ fail("Should have thrown an IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ }
+
+ ;
+ try {
+ assertTrue("1.2.alpha < 1.2.beta", comparator.compare("1.2.alpha", "1.2.beta") < 0);
+ fail("Should have thrown an IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ }
+
+ ;
+ try {
+ assertTrue("1.2.3.4.5 < 1.2.3.4.6", comparator.compare("1.2.3.4.5", "1.2.3.4.6") < 0);
+ fail("Should have thrown an IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ }
+
+ ;
+ }
+}
\ No newline at end of file
diff --git a/modules/core/util/src/main/java/org/rhq/core/util/OSGiVersionComparator.java b/modules/core/util/src/main/java/org/rhq/core/util/OSGiVersionComparator.java
deleted file mode 100644
index 0b6a30d..0000000
--- a/modules/core/util/src/main/java/org/rhq/core/util/OSGiVersionComparator.java
+++ /dev/null
@@ -1,94 +0,0 @@
- /*
- * RHQ Management Platform
- * Copyright (C) 2005-2008 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.core.util;
-
-import java.util.Comparator;
-
-/**
- * The specification for what makes up an OSGi compliant version string and how they can be compared was taken from
- * here:
- * http://help.eclipse.org/help31/index.jsp?topic=/org.eclipse.platform.doc....
- *
- * @author Charles Crouch
- *
- */
-public class OSGiVersionComparator implements Comparator<String> {
- public OSGiVersionComparator() {
- }
-
- public int compare(String string1, String string2) {
- Version ver1 = new Version(string1);
- Version ver2 = new Version(string2);
-
- int result = ver1.major - ver2.major;
- if (result == 0) {
- result = ver1.minor - ver2.minor;
- if (result == 0) {
- result = ver1.micro - ver2.micro;
- if (result == 0) {
- result = ver1.qualifier.compareTo(ver2.qualifier);
- }
- }
- }
-
- return result;
- }
-
- private class Version {
- int major;
- int minor;
- int micro;
- String qualifier = "";
-
- Version(String version) {
- String[] parts = version.split("\\.");
-
- try {
- switch (parts.length) {
- case 4: {
- qualifier = parts[3];
- }
-
- case 3: {
- micro = Integer.parseInt(parts[2]);
- }
-
- case 2: {
- minor = Integer.parseInt(parts[1]);
- }
-
- case 1: {
- major = Integer.parseInt(parts[0]);
- break;
- }
-
- default: {
- throw new IllegalArgumentException("Malformed version string [" + version + "]");
- }
- }
- } catch (NumberFormatException e) {
- throw new IllegalArgumentException("Malformed version string [" + version + "]");
- }
- }
- }
-}
\ No newline at end of file
diff --git a/modules/core/util/src/test/java/org/rhq/core/util/OSGiVersionComparatorTest.java b/modules/core/util/src/test/java/org/rhq/core/util/OSGiVersionComparatorTest.java
deleted file mode 100644
index dd108fc..0000000
--- a/modules/core/util/src/test/java/org/rhq/core/util/OSGiVersionComparatorTest.java
+++ /dev/null
@@ -1,80 +0,0 @@
- /*
- * RHQ Management Platform
- * Copyright (C) 2005-2008 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.core.util;
-
-import junit.framework.TestCase;
-
-public class OSGiVersionComparatorTest extends TestCase {
- public OSGiVersionComparatorTest(String arg0) {
- super(arg0);
- }
-
- protected void setUp() throws Exception {
- super.setUp();
- }
-
- protected void tearDown() throws Exception {
- super.tearDown();
- }
-
- /*
- * Test method for 'net.hyperic.hq.ui.action.resource.common.patch.JBossONVersionComparator.compare(Object, Object)'
- */
- public void testCompare() {
- OSGiVersionComparator comparator = new OSGiVersionComparator();
-
- assertTrue("1.2 > 1.1", comparator.compare("1.2", "1.1") > 0);
- assertTrue("1.1 < 1.2", comparator.compare("1.1", "1.2") < 0);
- assertTrue("1.0 = 1.0", comparator.compare("1.0", "1.0") == 0);
- assertTrue("9.9 < 9.22", comparator.compare("9.9", "9.22") < 0);
- assertTrue("9.9 < 10.2", comparator.compare("9.9", "10.2") < 0);
- assertTrue("9 < 10", comparator.compare("9", "10") < 0);
- assertTrue("1.2.13.BETA > 1.2.13.ALPHA", comparator.compare("1.2.13.BETA", "1.2.13.ALPHA") > 0);
- assertTrue("4.0.4.GA_CP_2006_06 > 4.0.4.GA", comparator.compare("4.0.4.GA_CP_2006_06", "4.0.4.GA") > 0);
- }
-
- public void testInvalidComparisons() {
- OSGiVersionComparator comparator = new OSGiVersionComparator();
- try {
- assertTrue("EA > 1.2", comparator.compare("EA", "1.2") > 0);
- fail("Should have thrown an IllegalArgumentException");
- } catch (IllegalArgumentException e) {
- }
-
- ;
- try {
- assertTrue("1.2.alpha < 1.2.beta", comparator.compare("1.2.alpha", "1.2.beta") < 0);
- fail("Should have thrown an IllegalArgumentException");
- } catch (IllegalArgumentException e) {
- }
-
- ;
- try {
- assertTrue("1.2.3.4.5 < 1.2.3.4.6", comparator.compare("1.2.3.4.5", "1.2.3.4.6") < 0);
- fail("Should have thrown an IllegalArgumentException");
- } catch (IllegalArgumentException e) {
- }
-
- ;
- }
-}
\ No newline at end of file
commit 4979cf7f751b5fbf7559e3887c89e96516089f55
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Tue Jan 25 12:05:22 2011 +0100
Package types can now exist independently of the resource types.
diff --git a/modules/core/dbutils/pom.xml b/modules/core/dbutils/pom.xml
index 2d8d1fc..76b00e9 100644
--- a/modules/core/dbutils/pom.xml
+++ b/modules/core/dbutils/pom.xml
@@ -22,7 +22,7 @@
<properties>
<scm.module.path>modules/core/dbutils/</scm.module.path>
- <db.schema.version>2.102</db.schema.version>
+ <db.schema.version>2.103</db.schema.version>
</properties>
<dependencies>
diff --git a/modules/core/dbutils/src/main/scripts/dbsetup/content-schema.xml b/modules/core/dbutils/src/main/scripts/dbsetup/content-schema.xml
index dec8587..f262087 100644
--- a/modules/core/dbutils/src/main/scripts/dbsetup/content-schema.xml
+++ b/modules/core/dbutils/src/main/scripts/dbsetup/content-schema.xml
@@ -112,7 +112,7 @@
<column name="IS_CREATION_DATA" type="BOOLEAN" required="true"/>
<column name="SUPPORTS_ARCHITECTURE" type="BOOLEAN" required="true"/>
- <column name="RESOURCE_TYPE_ID" type="INTEGER" references="RHQ_RESOURCE_TYPE" required="true"/>
+ <column name="RESOURCE_TYPE_ID" type="INTEGER" references="RHQ_RESOURCE_TYPE" required="false"/>
<column name="DEPLOYMENT_CONFIG_DEF_ID" type="INTEGER" references="RHQ_CONFIG_DEF" required="false"/>
<column name="PACKAGE_EXTRA_CONFIG_ID" type="INTEGER" references="RHQ_CONFIG_DEF" required="false"/>
diff --git a/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml b/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml
index 975c778..a5ef90a 100644
--- a/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml
+++ b/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml
@@ -3296,6 +3296,10 @@
</schema-directSQL>
</schemaSpec>
+ <schemaSpec version="2.103">
+ <!-- package types no longer require to be coupled with a resource type. They can exist on their own. -->
+ <schema-alterColumn table="RHQ_PACKAGE_TYPE" column="RESOURCE_TYPE_ID" nullable="true"/>
+ </schemaSpec>
</dbupgrade>
</target>
</project>
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/content/PackageType.java b/modules/core/domain/src/main/java/org/rhq/core/domain/content/PackageType.java
index 380a46f..c400bc6 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/content/PackageType.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/content/PackageType.java
@@ -129,7 +129,7 @@ public class PackageType implements Serializable {
@OneToMany(fetch = FetchType.LAZY, mappedBy = "packageType", cascade = { CascadeType.REMOVE })
private Set<Package> packages;
- @JoinColumn(name = "RESOURCE_TYPE_ID", referencedColumnName = "ID", nullable = false)
+ @JoinColumn(name = "RESOURCE_TYPE_ID", referencedColumnName = "ID", nullable = true)
@ManyToOne
@XmlTransient
private ResourceType resourceType;
@@ -289,7 +289,8 @@ public class PackageType implements Serializable {
/**
* The resource type that defined this package type. Resources of this resource type can have packages of this
- * package type installed on them.
+ * package type installed on them. This can be null if this package type only exists in support of some serverside-only
+ * functionality.
*/
public ResourceType getResourceType() {
return this.resourceType;
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerBean.java
index 2431230..4052693 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerBean.java
@@ -1301,7 +1301,9 @@ public class ContentManagerBean implements ContentManagerLocal, ContentManagerRe
q.setParameter("packageTypeName", pv.getGeneralPackage().getPackageType().getName());
q.setParameter("architectureName", pv.getArchitecture().getName());
q.setParameter("version", pv.getVersion());
- q.setParameter("resourceTypeId", pv.getGeneralPackage().getPackageType().getResourceType().getId());
+
+ ResourceType rt = pv.getGeneralPackage().getPackageType().getResourceType();
+ q.setParameter("resourceTypeId", rt != null ? rt.getId() : null);
List<PackageVersion> found = q.getResultList();
if (error != null && found.size() == 0) {
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentSourceManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentSourceManagerBean.java
index 3670ea2..a9fae13 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentSourceManagerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentSourceManagerBean.java
@@ -1616,26 +1616,29 @@ public class ContentSourceManagerBean implements ContentSourceManagerLocal {
ContentProviderPackageDetailsKey key = newDetails.getContentProviderPackageDetailsKey();
// find the new package's associated resource type (should already exist)
- ResourceType rt = new ResourceType();
- rt.setName(key.getResourceTypeName());
- rt.setPlugin(key.getResourceTypePluginName());
+ ResourceType rt = null;
+ if (key.getResourceTypeName() != null && key.getResourceTypePluginName() != null) {
+ rt = new ResourceType();
+ rt.setName(key.getResourceTypeName());
+ rt.setPlugin(key.getResourceTypePluginName());
- if (!knownResourceTypes.containsKey(rt)) {
- q = entityManager.createNamedQuery(ResourceType.QUERY_FIND_BY_NAME_AND_PLUGIN);
- q.setParameter("name", rt.getName());
- q.setParameter("plugin", rt.getPlugin());
+ if (!knownResourceTypes.containsKey(rt)) {
+ q = entityManager.createNamedQuery(ResourceType.QUERY_FIND_BY_NAME_AND_PLUGIN);
+ q.setParameter("name", rt.getName());
+ q.setParameter("plugin", rt.getPlugin());
- try {
- rt = (ResourceType) q.getSingleResult();
- knownResourceTypes.put(rt, rt); // cache it so we don't have to keep querying the DB
- knownProductVersions.put(rt, new HashMap<String, ProductVersion>());
- } catch (NoResultException nre) {
- log.warn("Content source adapter found a package for an unknown resource type ["
- + key.getResourceTypeName() + "|" + key.getResourceTypePluginName() + "] Skipping it.");
- continue; // skip this one but move on to the next
- }
- } else {
- rt = knownResourceTypes.get(rt);
+ try {
+ rt = (ResourceType) q.getSingleResult();
+ knownResourceTypes.put(rt, rt); // cache it so we don't have to keep querying the DB
+ knownProductVersions.put(rt, new HashMap<String, ProductVersion>());
+ } catch (NoResultException nre) {
+ log.warn("Content source adapter found a package for an unknown resource type ["
+ + key.getResourceTypeName() + "|" + key.getResourceTypePluginName() + "] Skipping it.");
+ continue; // skip this one but move on to the next
+ }
+ } else {
+ rt = knownResourceTypes.get(rt);
+ }
}
// find the new package's type (package types should already exist, agent plugin descriptors define them)
@@ -1643,7 +1646,7 @@ public class ContentSourceManagerBean implements ContentSourceManagerLocal {
if (!knownPackageTypes.containsKey(pt)) {
q = entityManager.createNamedQuery(PackageType.QUERY_FIND_BY_RESOURCE_TYPE_ID_AND_NAME);
- q.setParameter("typeId", rt.getId());
+ q.setParameter("typeId", rt != null ? rt.getId() : null);
q.setParameter("name", pt.getName());
try {
@@ -1664,7 +1667,7 @@ public class ContentSourceManagerBean implements ContentSourceManagerLocal {
q = entityManager.createNamedQuery(Package.QUERY_FIND_BY_NAME_PKG_TYPE_RESOURCE_TYPE);
q.setParameter("name", newDetails.getName());
q.setParameter("packageTypeName", newDetails.getPackageTypeName());
- q.setParameter("resourceTypeId", rt.getId());
+ q.setParameter("resourceTypeId", rt != null ? rt.getId() : null);
Package pkg;
try {
pkg = (Package) q.getSingleResult();
@@ -1753,7 +1756,12 @@ public class ContentSourceManagerBean implements ContentSourceManagerLocal {
// For each resource version that is supported, make sure we have an entry for that in product version
Set<String> resourceVersions = newDetails.getResourceVersions();
- if (resourceVersions != null) {
+
+ // the check for null resource type shouldn't be necessary here because
+ // the package shouldn't declare any resource versions if it doesn't declare a resource type.
+ // Nevertheless, let's make that check just to prevent disasters caused by "malicious" content
+ // providers.
+ if (resourceVersions != null && rt != null) {
Map<String, ProductVersion> cachedProductVersions = knownProductVersions.get(rt); // we are guaranteed that this returns non-null
for (String version : resourceVersions) {
ProductVersion productVersion = cachedProductVersions.get(version);
@@ -1765,6 +1773,9 @@ public class ContentSourceManagerBean implements ContentSourceManagerLocal {
ProductVersionPackageVersion mapping = new ProductVersionPackageVersion(productVersion, pv);
entityManager.merge(mapping); // use merge just in case this mapping somehow already exists
}
+ } else if (resourceVersions != null) {
+ log.info("Misbehaving content provider detected. It declares resource versions " + resourceVersions
+ + " but no resource type in package " + newDetails + ".");
}
// now create the mapping between the package version and content source
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/content/ContentProviderPackageDetailsKey.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/content/ContentProviderPackageDetailsKey.java
index b6b2dac..c9cc00a 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/content/ContentProviderPackageDetailsKey.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/content/ContentProviderPackageDetailsKey.java
@@ -54,22 +54,23 @@ public class ContentProviderPackageDetailsKey extends PackageDetailsKey {
}
/**
- * The name of the {@link ResourceType} that this package's type belongs to. All package types are defined and
+ * The name of the {@link ResourceType} that this package's type belongs to. Package types are usually defined and
* supported by a particular {@link ResourceType}, this name is part of the natural key of a resource type. See
* {@link #getResourceTypePluginName() plugin name} for the other part.
*
- * @return resource type name
+ * @return resource type name or null if the package type isn't tied to a resource type
*/
public String getResourceTypeName() {
return resourceTypeName;
}
/**
- * The name of the plugin that defined the {@link ResourceType} that this package's type belongs to. All package
- * types are defined and supported by a particular {@link ResourceType}, this plugin name is part of the natural key
+ * The name of the plugin that defined the {@link ResourceType} that this package's type belongs to. Package
+ * types are usually defined and supported by a particular {@link ResourceType}, this plugin name is part of the natural key
* of a resource type. See {@link #getResourceTypeName() resource type name} for the other part.
*
- * @return the name of the plugin that defines the resource type that defined the package type
+ * @return the name of the plugin that defines the resource type that defined the package type or null if the package
+ * type isn't tied to a resource type
*/
public String getResourceTypePluginName() {
return resourceTypePluginName;
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/content/sync/PackageSourceSynchronizer.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/content/sync/PackageSourceSynchronizer.java
index 48c26a3..a0c141a 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/content/sync/PackageSourceSynchronizer.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/content/sync/PackageSourceSynchronizer.java
@@ -239,10 +239,12 @@ public class PackageSourceSynchronizer {
PackageVersion pv = pvcs.getPackageVersionContentSourcePK().getPackageVersion();
org.rhq.core.domain.content.Package p = pv.getGeneralPackage();
ResourceType rt = p.getPackageType().getResourceType();
-
+ String resourceTypeName = rt != null ? rt.getName() : null;
+ String resourceTypePlugin = rt != null ? rt.getPlugin() : null;
+
ContentProviderPackageDetailsKey key;
key = new ContentProviderPackageDetailsKey(p.getName(), pv.getVersion(), p.getPackageType().getName(), pv
- .getArchitecture().getName(), rt.getName(), rt.getPlugin());
+ .getArchitecture().getName(), resourceTypeName, resourceTypePlugin);
ContentProviderPackageDetails details = new ContentProviderPackageDetails(key);
details.setClassification(pv.getGeneralPackage().getClassification());
commit 427d9fc65f5218dac34f1c05541e1efa25228b6a
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Thu Jan 20 11:56:27 2011 +0100
Added the ability to read in the latest version of a package. The "latest" version is based on the ability of the content source to compare versions of the packages it provides.
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/content/PackageVersion.java b/modules/core/domain/src/main/java/org/rhq/core/domain/content/PackageVersion.java
index f05b36c..8d2b9b4 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/content/PackageVersion.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/content/PackageVersion.java
@@ -23,6 +23,7 @@
package org.rhq.core.domain.content;
import java.io.Serializable;
+import java.util.Comparator;
import java.util.HashSet;
import java.util.Set;
@@ -46,6 +47,7 @@ import org.hibernate.annotations.NamedQuery;
import org.rhq.core.domain.configuration.Configuration;
import org.rhq.core.domain.resource.ProductVersion;
+import org.rhq.core.util.OSGiVersionComparator;
/**
* Represents a specific version of a {@link Package}. This does <i>not</i> represent an installed package found
@@ -275,6 +277,51 @@ public class PackageVersion implements Serializable {
public static final String QUERY_FIND_BY_ID = "PackageVersion.findById";
public static final String QUERY_FIND_PACKAGE_BY_FILENAME = "PackageVersion.findPackageByFilename";
public static final String QUERY_FIND_PACKAGEVERSION_BY_FILENAME = "PackageVersion.findPackageVersionByFilename";
+
+ /**
+ * This is a default {@link Comparator} implementation for package versions.
+ * If the package versions being compared both have non-null {@link PackageVersion#getVersion() versions}
+ * an {@link OSGiVersionComparator} is used to compare them. If it fails or if one of the versions
+ * is null the package versions are compared by {@link PackageVersion#getFileCreatedDate() file created date}.
+ * If the creation date is not specified for one of the package versions, they proclaimed equal.
+ * <p>
+ * Note that this comparator is *INCONSISTENT* with <code>equals()</code> and therefore care should be taken
+ * when using it with sets and maps (read this {@link Comparator documentation}).
+ *
+ * @author Lukas Krejci
+ */
+ public static class DefaultPackageVersionComparator implements Comparator<PackageVersion>, Serializable {
+ private static final long serialVersionUID = 1L;
+
+ public int compare(PackageVersion p1, PackageVersion p2) {
+ String v1 = p1.getVersion();
+ String v2 = p2.getVersion();
+
+ OSGiVersionComparator c = new OSGiVersionComparator();
+
+ if (v1 != null && v2 != null) {
+ try {
+ return c.compare(v1, v2);
+ } catch (IllegalArgumentException e) {
+ //well, this can happen.. not all packages have OSGi type versions.
+ }
+ }
+
+ if (p1.getFileCreatedDate() != null && p2.getFileCreatedDate() != null) {
+ return p1.getFileCreatedDate().compareTo(p2.getFileCreatedDate());
+ }
+
+ //hmm... there's actually nothing we can sort these two by..
+ //pronounce them equal
+ return 0;
+ }
+ };
+
+ /**
+ * @see DefaultPackageVersionComparator
+ */
+ public static final DefaultPackageVersionComparator DEFAULT_COMPARATOR = new DefaultPackageVersionComparator();
+
// Attributes --------------------------------------------
@Column(name = "ID", nullable = false)
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/content/PackageVersionContentSource.java b/modules/core/domain/src/main/java/org/rhq/core/domain/content/PackageVersionContentSource.java
index 316150b..1120774 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/content/PackageVersionContentSource.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/content/PackageVersionContentSource.java
@@ -43,6 +43,8 @@ import javax.persistence.Table;
@NamedQueries( {
@NamedQuery(name = PackageVersionContentSource.QUERY_FIND_BY_CONTENT_SOURCE_ID_NO_FETCH, query = "SELECT pvcs "
+ " FROM PackageVersionContentSource pvcs " + " WHERE pvcs.contentSource.id = :id "),
+ @NamedQuery(name = PackageVersionContentSource.QUERY_FIND_BY_PACKAGE_VERSION_ID_NO_FETCH, query = "SELECT pvcs "
+ + " FROM PackageVersionContentSource pvcs WHERE pvcs.packageVersion.id = :id"),
@NamedQuery(name = PackageVersionContentSource.QUERY_FIND_BY_CONTENT_SOURCE_ID, query = "SELECT pvcs "
+ " FROM PackageVersionContentSource pvcs " //
+ " LEFT JOIN FETCH pvcs.packageVersion pv " //
@@ -113,7 +115,8 @@ public class PackageVersionContentSource implements Serializable {
public static final String QUERY_FIND_BY_CONTENT_SOURCE_ID_AND_NOT_LOADED_COUNT = "PackageVersionContentSource.findByCSIdAndNotLoadedCount";
public static final String QUERY_FIND_BY_PKG_VER_ID_AND_RES_ID = "PackageVersionContentSource.findByPkgVerIdAndResId";
public static final String DELETE_BY_CONTENT_SOURCE_ID = "PackageVersionContentSource.deleteByContentSourceId";
-
+ public static final String QUERY_FIND_BY_PACKAGE_VERSION_ID_NO_FETCH = "PackageVersionContentSource.findByPackageVersionIdNoFetch";
+
private static final long serialVersionUID = 1L;
/*
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentSourceManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentSourceManagerBean.java
index 4160793..3670ea2 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentSourceManagerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentSourceManagerBean.java
@@ -33,6 +33,8 @@ import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
@@ -117,6 +119,7 @@ import org.rhq.enterprise.server.plugin.pc.content.DistributionFileDetails;
import org.rhq.enterprise.server.plugin.pc.content.DistributionSource;
import org.rhq.enterprise.server.plugin.pc.content.DistributionSyncReport;
import org.rhq.enterprise.server.plugin.pc.content.InitializationException;
+import org.rhq.enterprise.server.plugin.pc.content.PackageSource;
import org.rhq.enterprise.server.plugin.pc.content.PackageSyncReport;
import org.rhq.enterprise.server.plugin.pc.content.RepoDetails;
import org.rhq.enterprise.server.resource.ProductVersionManagerLocal;
@@ -947,6 +950,51 @@ public class ContentSourceManagerBean implements ContentSourceManagerLocal {
return packageBits;
}
+ public PackageVersion getLatestPackageVersion(int packageId, Comparator<PackageVersion> versionComparator) {
+ if (versionComparator == null) {
+ Query pvcsQ = entityManager.createNamedQuery(PackageVersionContentSource.QUERY_FIND_BY_PACKAGE_VERSION_ID_NO_FETCH);
+
+ @SuppressWarnings("unchecked")
+ List<PackageVersionContentSource> pvcss = (List<PackageVersionContentSource>) pvcsQ.getResultList();
+
+ try {
+ ContentProviderManager manager = ContentManagerHelper.getPluginContainer().getAdapterManager();
+ for(PackageVersionContentSource pvcs : pvcss) {
+ ContentProvider provider = manager.getIsolatedContentProvider(pvcs.getPackageVersionContentSourcePK().getContentSource().getId());
+
+ if (provider instanceof PackageSource) {
+ versionComparator = ((PackageSource)provider).getPackageVersionComparator();
+
+ if (versionComparator != null) {
+ //ok, we found one non-default, let's go with that.
+ break;
+ }
+ }
+ }
+ } catch (Exception e) {
+ log.warn("Searching package sources for a version comparator failed. Will use the default comparator.", e);
+ }
+
+ if (versionComparator == null) {
+ versionComparator = PackageVersion.DEFAULT_COMPARATOR;
+ }
+ }
+
+ Query q = entityManager.createNamedQuery(PackageVersion.QUERY_FIND_BY_PACKAGE_ID);
+
+ @SuppressWarnings("unchecked")
+ List<PackageVersion> results = (List<PackageVersion>) q.getResultList();
+
+ if (results.size() > 0) {
+ Comparator<PackageVersion> descending = Collections.reverseOrder(versionComparator);
+ Collections.sort(results, descending);
+
+ return results.get(0);
+ }
+
+ return null;
+ }
+
/**
* This creates a new PackageBits entity initialized to EMPTY_BLOB for the associated PackageBitsBlob.
* Note that PackageBits and PackageBitsBlob are two entities that *share* the same db row. This is
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentSourceManagerLocal.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentSourceManagerLocal.java
index f861764..fa87526 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentSourceManagerLocal.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentSourceManagerLocal.java
@@ -20,6 +20,7 @@ package org.rhq.enterprise.server.content;
import java.io.OutputStream;
import java.util.Collection;
+import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -633,4 +634,19 @@ public interface ContentSourceManagerLocal {
* the given object are not valid
*/
ContentSource simpleCreateContentSource(Subject subject, ContentSource contentSource) throws ContentSourceException;
+
+ /**
+ * Returns the latest package version of the supplied package as deemed by the supplied comparator.
+ * The supplied comparator is taken as an override to the default one to use.
+ * The default comparator is determined using the following algorithm:
+ * <ol>
+ * <li>Find the first content provider defining the package that defines a non-null comparator and return that
+ * <li>If no content provider provides explicit comparator, use {@link PackageVersion#DEFAULT_COMPARATOR}
+ * </ol>
+ *
+ * @param packageId the id of the package to find the latest version for.
+ * @param versionComparator if left null, the comparator to use is determined by the rules above
+ * @return
+ */
+ PackageVersion getLatestPackageVersion(int packageId, Comparator<PackageVersion> versionComparator);
}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/content/PackageSource.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/content/PackageSource.java
index a31885e..5bdfd4b 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/content/PackageSource.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/content/PackageSource.java
@@ -24,6 +24,9 @@ package org.rhq.enterprise.server.plugin.pc.content;
import java.io.InputStream;
import java.util.Collection;
+import java.util.Comparator;
+
+import org.rhq.core.domain.content.PackageVersion;
/**
* Indicates a content source has the capability to provide packages into the server. Package synchronization will
@@ -60,4 +63,15 @@ public interface PackageSource {
*/
InputStream getInputStream(String location) throws Exception;
+ /**
+ * This comparator will be used to determine the latest version of a package.
+ * It should sort the package versions from the "oldest" to the "youngest", i.e. when comparing
+ * <br/>
+ * <code>comparator.compare(older, younger)</code>
+ * <br/>
+ * the comparator should return a value < 0.
+ *
+ * @return a comparator to use when sorting the package versions or null if {@link PackageVersion#DEFAULT_COMPARATOR} should be used.
+ */
+ Comparator<PackageVersion> getPackageVersionComparator();
}
diff --git a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/plugin/pc/content/TestContentProvider.java b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/plugin/pc/content/TestContentProvider.java
index 20805e4..0258f3a 100644
--- a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/plugin/pc/content/TestContentProvider.java
+++ b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/plugin/pc/content/TestContentProvider.java
@@ -5,11 +5,13 @@ import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.rhq.core.domain.configuration.Configuration;
+import org.rhq.core.domain.content.PackageVersion;
public class TestContentProvider implements ContentProvider, PackageSource, RepoSource, DistributionSource {
@@ -249,6 +251,10 @@ public class TestContentProvider implements ContentProvider, PackageSource, Repo
return bis;
}
+ public Comparator<PackageVersion> getPackageVersionComparator() {
+ return null;
+ }
+
public void synchronizeDistribution(String repoName, DistributionSyncReport report,
Collection<DistributionDetails> existingDistros) throws SyncException, InterruptedException {
diff --git a/modules/enterprise/server/plugins/alert-cli/src/main/java/org/rhq/enterprise/server/plugins/alertCli/CliSender.java b/modules/enterprise/server/plugins/alert-cli/src/main/java/org/rhq/enterprise/server/plugins/alertCli/CliSender.java
index 64d1a22..61d795a 100644
--- a/modules/enterprise/server/plugins/alert-cli/src/main/java/org/rhq/enterprise/server/plugins/alertCli/CliSender.java
+++ b/modules/enterprise/server/plugins/alert-cli/src/main/java/org/rhq/enterprise/server/plugins/alertCli/CliSender.java
@@ -24,14 +24,15 @@ import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
+import java.io.PipedInputStream;
+import java.io.PipedOutputStream;
import java.util.Collections;
import javax.script.ScriptEngine;
import javax.script.ScriptException;
-import org.apache.commons.logging.LogFactory;
-
import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
import org.rhq.bindings.ScriptEngineFactory;
import org.rhq.bindings.StandardBindings;
@@ -40,7 +41,9 @@ import org.rhq.core.domain.alert.Alert;
import org.rhq.core.domain.alert.notification.SenderResult;
import org.rhq.core.domain.auth.Subject;
import org.rhq.core.domain.configuration.PropertySimple;
+import org.rhq.core.domain.content.PackageVersion;
import org.rhq.enterprise.client.LocalClient;
+import org.rhq.enterprise.server.content.ContentSourceManagerLocal;
import org.rhq.enterprise.server.plugin.pc.ServerPluginComponent;
import org.rhq.enterprise.server.plugin.pc.alert.AlertSender;
import org.rhq.enterprise.server.util.LookupUtil;
@@ -52,36 +55,34 @@ import org.rhq.enterprise.server.util.LookupUtil;
*/
public class CliSender extends AlertSender<ServerPluginComponent> {
private static final Log LOG = LogFactory.getLog(CliSender.class);
-
+
public SenderResult send(Alert alert) {
SenderResult result = new SenderResult();
BufferedReader reader = null;
try {
ScriptEngine engine = getScriptEngine(alert);
-
+
PropertySimple packageIdProp = alertParameters.getSimple("packageId");
-
+
if (packageIdProp == null) {
- return SenderResult.getSimpleFailure("The configuration doesn't contain the mandatory 'packageId' property. This should not happen.");
+ return SenderResult
+ .getSimpleFailure("The configuration doesn't contain the mandatory 'packageId' property. This should not happen.");
}
-
+
Integer packageId = packageIdProp.getIntegerValue();
-
+
if (packageId == null) {
return SenderResult.getSimpleFailure("No script defined.");
}
-
- //TODO getting the package bits is going to require changes to the content manager
- //this is gonna have to be asynchronous because the package bits are possibly
- //only going to be downloaded.
- InputStream packageBits = null;
-
+
+ InputStream packageBits = getPackageBits(packageId);
+
reader = new BufferedReader(new InputStreamReader(packageBits));
-
+
Object ret = engine.eval(reader);
-
+
//TODO what to do with the return value, if any
-
+
return result;
} catch (Exception e) {
//TODO I don't like this
@@ -94,7 +95,7 @@ public class CliSender extends AlertSender<ServerPluginComponent> {
LOG.error("Failed to close the script reader.", e);
}
}
- }
+ }
}
private ScriptEngine getScriptEngine(Alert alert) throws ScriptException, IOException {
@@ -105,8 +106,42 @@ public class CliSender extends AlertSender<ServerPluginComponent> {
//TODO define some meaningful printwriter
StandardBindings bindings = new StandardBindings(null, client);
bindings.put("alert", alert);
-
+
return ScriptEngineFactory.getScriptEngine("JavaScript", new PackageFinder(Collections.<File> emptyList()),
bindings);
}
+
+ private InputStream getPackageBits(int packageId) throws IOException {
+ final ContentSourceManagerLocal csm = LookupUtil.getContentSourceManager();
+ final PackageVersion versionToUse = csm.getLatestPackageVersion(packageId, null);
+
+ PipedInputStream ret = new PipedInputStream();
+ final PipedOutputStream out = new PipedOutputStream(ret);
+
+ Thread reader = new Thread(new Runnable() {
+ public void run() {
+ try {
+ csm.outputPackageVersionBits(versionToUse, out);
+ } catch (RuntimeException e) {
+ LOG.warn("The thread for reading the bits of package version [" + versionToUse
+ + "] failed with exception.", e);
+ throw e;
+ } finally {
+ try {
+ out.close();
+ } catch (IOException e) {
+ //doesn't happen in piped output stream
+ LOG.error(
+ "Failed to close the piped output stream receiving the package bits of package version "
+ + versionToUse + ". This should never happen.", e);
+ }
+ }
+ }
+ });
+ reader.setName("CLI Alert download thread for package version " + versionToUse);
+ reader.setDaemon(true);
+ reader.start();
+
+ return ret;
+ }
}
diff --git a/modules/enterprise/server/plugins/disk/src/main/java/org/rhq/enterprise/server/plugins/disk/DiskSource.java b/modules/enterprise/server/plugins/disk/src/main/java/org/rhq/enterprise/server/plugins/disk/DiskSource.java
index 336117f..1c408ab 100644
--- a/modules/enterprise/server/plugins/disk/src/main/java/org/rhq/enterprise/server/plugins/disk/DiskSource.java
+++ b/modules/enterprise/server/plugins/disk/src/main/java/org/rhq/enterprise/server/plugins/disk/DiskSource.java
@@ -24,6 +24,7 @@ import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -32,6 +33,7 @@ import org.rhq.core.domain.configuration.Configuration;
import org.rhq.core.domain.configuration.Property;
import org.rhq.core.domain.configuration.PropertyMap;
import org.rhq.core.domain.configuration.PropertySimple;
+import org.rhq.core.domain.content.PackageVersion;
import org.rhq.core.util.MessageDigestGenerator;
import org.rhq.core.util.file.ContentFileInfo;
import org.rhq.core.util.file.ContentFileInfoFactory;
@@ -164,6 +166,20 @@ public class DiskSource implements ContentProvider, PackageSource, RepoSource {
return new FileInputStream(new File(getRootDirectory(), location));
}
+ /**
+ * The disk source doesn't have a meaningful version strings, so this
+ * implementation compares strictly by {@link PackageVersion#getFileCreatedDate() file creation date}.
+ *
+ * @return a comparator comparing two package versions coming from DiskSource by their file-created-date.
+ */
+ public Comparator<PackageVersion> getPackageVersionComparator() {
+ return new Comparator<PackageVersion>() {
+ public int compare(PackageVersion o1, PackageVersion o2) {
+ return o1.getFileCreatedDate().compareTo(o2.getFileCreatedDate());
+ }
+ };
+ }
+
protected File getRootDirectory() {
return this.rootDirectory;
}
diff --git a/modules/enterprise/server/plugins/jboss-software/src/main/java/org/rhq/enterprise/server/plugins/jboss/software/JBossSoftwareContentSourceAdapter.java b/modules/enterprise/server/plugins/jboss-software/src/main/java/org/rhq/enterprise/server/plugins/jboss/software/JBossSoftwareContentSourceAdapter.java
index 2758e2b..a40047a 100644
--- a/modules/enterprise/server/plugins/jboss-software/src/main/java/org/rhq/enterprise/server/plugins/jboss/software/JBossSoftwareContentSourceAdapter.java
+++ b/modules/enterprise/server/plugins/jboss-software/src/main/java/org/rhq/enterprise/server/plugins/jboss/software/JBossSoftwareContentSourceAdapter.java
@@ -22,6 +22,7 @@ import java.io.InputStream;
import java.net.URI;
import java.net.URL;
import java.util.Collection;
+import java.util.Comparator;
import churchillobjects.rss4j.RssDocument;
import churchillobjects.rss4j.parser.RssParser;
@@ -38,6 +39,7 @@ import org.apache.commons.logging.LogFactory;
import org.rhq.core.domain.configuration.Configuration;
import org.rhq.core.domain.configuration.PropertySimple;
+import org.rhq.core.domain.content.PackageVersion;
import org.rhq.enterprise.server.plugin.pc.content.ContentProvider;
import org.rhq.enterprise.server.plugin.pc.content.ContentProviderPackageDetails;
import org.rhq.enterprise.server.plugin.pc.content.PackageSource;
@@ -163,6 +165,13 @@ public class JBossSoftwareContentSourceAdapter implements ContentProvider, Packa
return stream;
}
+ /**
+ * @return null so that the {@link PackageVersion#DEFAULT_COMPARATOR} is used because it is well suited for the CSP packages.
+ */
+ public Comparator<PackageVersion> getPackageVersionComparator() {
+ return null;
+ }
+
public RepoImportReport importRepos() throws Exception {
RepoDetails repo = new RepoDetails("JBoss Patches");
diff --git a/modules/enterprise/server/plugins/rhnhosted/src/main/java/org/rhq/enterprise/server/plugins/rhnhosted/RHNProvider.java b/modules/enterprise/server/plugins/rhnhosted/src/main/java/org/rhq/enterprise/server/plugins/rhnhosted/RHNProvider.java
index 03e7ba6..f9710cf 100644
--- a/modules/enterprise/server/plugins/rhnhosted/src/main/java/org/rhq/enterprise/server/plugins/rhnhosted/RHNProvider.java
+++ b/modules/enterprise/server/plugins/rhnhosted/src/main/java/org/rhq/enterprise/server/plugins/rhnhosted/RHNProvider.java
@@ -28,6 +28,7 @@ import java.net.URL;
import java.security.KeyException;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.Comparator;
import java.util.List;
import org.apache.commons.io.FileUtils;
@@ -36,6 +37,7 @@ import org.apache.commons.logging.LogFactory;
import org.apache.xmlrpc.XmlRpcException;
import org.rhq.core.domain.configuration.Configuration;
+import org.rhq.core.domain.content.PackageVersion;
import org.rhq.enterprise.server.plugin.pc.content.AdvisoryDetails;
import org.rhq.enterprise.server.plugin.pc.content.AdvisorySource;
import org.rhq.enterprise.server.plugin.pc.content.AdvisorySyncReport;
@@ -225,6 +227,13 @@ public class RHNProvider implements ContentProvider, PackageSource, RepoSource,
}
/**
+ * @return null so that the {@link PackageVersion#DEFAULT_COMPARATOR} is used because it is well suited for the RHN packages.
+ */
+ public Comparator<PackageVersion> getPackageVersionComparator() {
+ return null;
+ }
+
+ /**
* @inheritDoc
*/
public void synchronizeAdvisory(String repoName, AdvisorySyncReport report,
diff --git a/modules/enterprise/server/plugins/url/src/main/java/org/rhq/enterprise/server/plugins/url/UrlProvider.java b/modules/enterprise/server/plugins/url/src/main/java/org/rhq/enterprise/server/plugins/url/UrlProvider.java
index c229a2b..2f98600 100644
--- a/modules/enterprise/server/plugins/url/src/main/java/org/rhq/enterprise/server/plugins/url/UrlProvider.java
+++ b/modules/enterprise/server/plugins/url/src/main/java/org/rhq/enterprise/server/plugins/url/UrlProvider.java
@@ -25,6 +25,7 @@ import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -33,6 +34,7 @@ import org.rhq.core.domain.configuration.Configuration;
import org.rhq.core.domain.configuration.Property;
import org.rhq.core.domain.configuration.PropertyList;
import org.rhq.core.domain.configuration.PropertyMap;
+import org.rhq.core.domain.content.PackageVersion;
import org.rhq.enterprise.server.plugin.pc.content.ContentProvider;
import org.rhq.enterprise.server.plugin.pc.content.ContentProviderPackageDetails;
import org.rhq.enterprise.server.plugin.pc.content.ContentProviderPackageDetailsKey;
@@ -209,6 +211,14 @@ public class UrlProvider implements ContentProvider, PackageSource {
return;
}
+ /**
+ * This uses the default comparator.
+ * @return null so that the {@link PackageVersion#DEFAULT_COMPARATOR} is used.
+ */
+ public Comparator<PackageVersion> getPackageVersionComparator() {
+ return null;
+ }
+
public void testConnection() throws Exception {
// to test, just make sure we can read the index file;
// errors will caused exceptions to be thrown.
diff --git a/modules/enterprise/server/plugins/yum/src/main/java/org/rhq/enterprise/server/plugins/yum/RepoProvider.java b/modules/enterprise/server/plugins/yum/src/main/java/org/rhq/enterprise/server/plugins/yum/RepoProvider.java
index f065ba7..ffff370 100644
--- a/modules/enterprise/server/plugins/yum/src/main/java/org/rhq/enterprise/server/plugins/yum/RepoProvider.java
+++ b/modules/enterprise/server/plugins/yum/src/main/java/org/rhq/enterprise/server/plugins/yum/RepoProvider.java
@@ -21,12 +21,14 @@ package org.rhq.enterprise.server.plugins.yum;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.Comparator;
import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.rhq.core.domain.configuration.Configuration;
+import org.rhq.core.domain.content.PackageVersion;
import org.rhq.enterprise.server.plugin.pc.content.ContentProvider;
import org.rhq.enterprise.server.plugin.pc.content.ContentProviderPackageDetails;
import org.rhq.enterprise.server.plugin.pc.content.PackageSource;
@@ -177,6 +179,13 @@ public class RepoProvider implements ContentProvider, PackageSource {
}
/**
+ * @return null so that the {@link PackageVersion#DEFAULT_COMPARATOR} is used because it is well suited for YUM packages.
+ */
+ public Comparator<PackageVersion> getPackageVersionComparator() {
+ return null;
+ }
+
+ /**
* Trim white space and trailing (/) characters.
*
* @param path A url/directory path string.
commit 0bda2cfb69992d67687415671bc6b86820fd2344
Merge: 8e95ac8... eab08df...
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Wed Jan 19 11:35:39 2011 +0100
Merge branch 'master' into cli-alert-notifs
commit 8e95ac8a1089cbef1e69976a4376cb5fe16adaed
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Mon Jan 17 16:24:52 2011 +0100
dev profile and cobertura support in the new maven modules.
diff --git a/modules/enterprise/binding/pom.xml b/modules/enterprise/binding/pom.xml
index 661af79..7e6b120 100644
--- a/modules/enterprise/binding/pom.xml
+++ b/modules/enterprise/binding/pom.xml
@@ -1,200 +1,387 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <artifactId>rhq-enterprise-parent</artifactId>
- <groupId>org.rhq</groupId>
- <version>4.0.0-SNAPSHOT</version>
- </parent>
- <groupId>org.rhq</groupId>
- <artifactId>rhq-script-bindings</artifactId>
- <version>4.0.0-SNAPSHOT</version>
- <name>RHQ Script Bindings</name>
- <description>Abstraction of different facilities and default configurations for script bindings</description>
-
- <properties>
- <persistence-api.version>1.0</persistence-api.version>
- <opencsv.version>1.8</opencsv.version>
- </properties>
-
- <dependencies>
-
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>rhq-core-domain</artifactId>
- <version>${project.version}</version>
- <exclusions>
- <exclusion>
- <groupId>hibernate</groupId>
- <artifactId>hibernate3</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
-
- <dependency>
- <groupId>${groupId}</groupId>
- <artifactId>rhq-core-domain</artifactId>
- <version>${project.version}</version>
- <type>test-jar</type>
- <scope>test</scope>
- </dependency>
-
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>rhq-enterprise-server</artifactId>
- <version>${project.version}</version>
- <type>ejb-client</type>
- <exclusions>
- <exclusion>
- <groupId>ant</groupId>
- <artifactId>ant</artifactId>
- </exclusion>
- <exclusion>
- <groupId>commons-beanutils</groupId>
- <artifactId>commons-beanutils</artifactId>
- </exclusion>
- <exclusion>
- <groupId>commons-collections</groupId>
- <artifactId>commons-collections</artifactId>
- </exclusion>
- <exclusion>
- <groupId>commons-httpclient</groupId>
- <artifactId>commons-httpclient</artifactId>
- </exclusion>
- <exclusion>
- <groupId>commons-lang</groupId>
- <artifactId>commons-lang</artifactId>
- </exclusion>
- <exclusion>
- <groupId>commons-validator</groupId>
- <artifactId>commons-validator</artifactId>
- </exclusion>
- <exclusion>
- <groupId>dom4j</groupId>
- <artifactId>dom4j</artifactId>
- </exclusion>
- <exclusion>
- <groupId>gnu-getopt</groupId>
- <artifactId>getopt</artifactId>
- </exclusion>
- <exclusion>
- <groupId>jboss</groupId>
- <artifactId>jboss-cache</artifactId>
- </exclusion>
- <exclusion>
- <groupId>jboss</groupId>
- <artifactId>jbpm</artifactId>
- </exclusion>
- <exclusion>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- </exclusion>
- <exclusion>
- <groupId>org.rhq</groupId>
- <artifactId>rhq-core-client-api</artifactId>
- </exclusion>
- <exclusion>
- <groupId>org.rhq</groupId>
- <artifactId>rhq-core-dbutils</artifactId>
- </exclusion>
- <exclusion>
- <groupId>org.rhq</groupId>
- <artifactId>rhq-enterprise-server-xml-schemas</artifactId>
- </exclusion>
- <exclusion>
- <groupId>org.rhq</groupId>
- <artifactId>safe-invoker</artifactId>
- </exclusion>
- <exclusion>
- <groupId>org.rhq</groupId>
- <artifactId>test-utils</artifactId>
- </exclusion>
- <exclusion>
- <groupId>org.snmp4j</groupId>
- <artifactId>snmp4j</artifactId>
- </exclusion>
- <exclusion>
- <groupId>oswego-concurrent</groupId>
- <artifactId>concurrent</artifactId>
- </exclusion>
- <exclusion>
- <groupId>postgresql</groupId>
- <artifactId>postgresql</artifactId>
- </exclusion>
- <exclusion>
- <groupId>rss4j</groupId>
- <artifactId>rss4j</artifactId>
- </exclusion>
- <exclusion>
- <groupId>jboss</groupId>
- <artifactId>jboss-common</artifactId>
- </exclusion>
- <exclusion>
- <groupId>jboss</groupId>
- <artifactId>jboss-jmx</artifactId>
- </exclusion>
- <exclusion>
- <groupId>jboss</groupId>
- <artifactId>jboss-remoting</artifactId>
- </exclusion>
- <exclusion>
- <groupId>jboss</groupId>
- <artifactId>jboss-serialization</artifactId>
- </exclusion>
- <exclusion>
- <groupId>org.antlr</groupId>
- <artifactId>antlr</artifactId>
- </exclusion>
- <exclusion>
- <groupId>com.jcraft</groupId>
- <artifactId>jsch</artifactId>
- </exclusion>
- <exclusion>
- <groupId>org.rhq</groupId>
- <artifactId>rhq-enterprise-comm</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
-
- <dependency>
- <groupId>commons-lang</groupId>
- <artifactId>commons-lang</artifactId>
- <version>2.4</version>
- <scope>test</scope>
- </dependency>
-
- <dependency>
- <groupId>javax.persistence</groupId>
- <artifactId>persistence-api</artifactId>
- <version>${persistence-api.version}</version>
- <scope>provided</scope>
- </dependency>
-
- <dependency>
- <groupId>hibernate-annotations</groupId>
- <artifactId>hibernate-annotations</artifactId>
- <!-- NOTE: The version is defined in the root POM's dependencyManagement
- section. -->
- <scope>provided</scope>
- </dependency>
-
- <dependency>
- <groupId>org.testng</groupId>
- <artifactId>testng</artifactId>
- <version>${testng.version}</version>
- <scope>compile</scope> <!-- yes, this is meant to be in compile, because we're providing assertions
- to the scripts -->
- </dependency>
-
- <dependency>
- <groupId>net.sf.opencsv</groupId>
- <artifactId>opencsv</artifactId>
- <version>${opencsv.version}</version>
- </dependency>
-
- <dependency>
- <groupId>jboss</groupId>
- <artifactId>javassist</artifactId>
- </dependency>
- </dependencies>
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <artifactId>rhq-enterprise-parent</artifactId>
+ <groupId>org.rhq</groupId>
+ <version>4.0.0-SNAPSHOT</version>
+ </parent>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-script-bindings</artifactId>
+ <version>4.0.0-SNAPSHOT</version>
+ <name>RHQ Script Bindings</name>
+ <description>Abstraction of different facilities and default configurations for script bindings</description>
+
+ <properties>
+ <persistence-api.version>1.0</persistence-api.version>
+ <opencsv.version>1.8</opencsv.version>
+ </properties>
+
+ <dependencies>
+
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>rhq-core-domain</artifactId>
+ <version>${project.version}</version>
+ <exclusions>
+ <exclusion>
+ <groupId>hibernate</groupId>
+ <artifactId>hibernate3</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+
+ <dependency>
+ <groupId>${groupId}</groupId>
+ <artifactId>rhq-core-domain</artifactId>
+ <version>${project.version}</version>
+ <type>test-jar</type>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>rhq-enterprise-server</artifactId>
+ <version>${project.version}</version>
+ <type>ejb-client</type>
+ <exclusions>
+ <exclusion>
+ <groupId>ant</groupId>
+ <artifactId>ant</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>commons-beanutils</groupId>
+ <artifactId>commons-beanutils</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>commons-collections</groupId>
+ <artifactId>commons-collections</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>commons-httpclient</groupId>
+ <artifactId>commons-httpclient</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>commons-lang</groupId>
+ <artifactId>commons-lang</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>commons-validator</groupId>
+ <artifactId>commons-validator</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>dom4j</groupId>
+ <artifactId>dom4j</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>gnu-getopt</groupId>
+ <artifactId>getopt</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>jboss</groupId>
+ <artifactId>jboss-cache</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>jboss</groupId>
+ <artifactId>jbpm</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-core-client-api</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-core-dbutils</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-enterprise-server-xml-schemas</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.rhq</groupId>
+ <artifactId>safe-invoker</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.rhq</groupId>
+ <artifactId>test-utils</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.snmp4j</groupId>
+ <artifactId>snmp4j</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>oswego-concurrent</groupId>
+ <artifactId>concurrent</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>postgresql</groupId>
+ <artifactId>postgresql</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>rss4j</groupId>
+ <artifactId>rss4j</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>jboss</groupId>
+ <artifactId>jboss-common</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>jboss</groupId>
+ <artifactId>jboss-jmx</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>jboss</groupId>
+ <artifactId>jboss-remoting</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>jboss</groupId>
+ <artifactId>jboss-serialization</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.antlr</groupId>
+ <artifactId>antlr</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>com.jcraft</groupId>
+ <artifactId>jsch</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-enterprise-comm</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+
+ <dependency>
+ <groupId>commons-lang</groupId>
+ <artifactId>commons-lang</artifactId>
+ <version>2.4</version>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>javax.persistence</groupId>
+ <artifactId>persistence-api</artifactId>
+ <version>${persistence-api.version}</version>
+ <scope>provided</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>hibernate-annotations</groupId>
+ <artifactId>hibernate-annotations</artifactId>
+ <!-- NOTE: The version is defined in the root POM's dependencyManagement
+ section. -->
+ <scope>provided</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.testng</groupId>
+ <artifactId>testng</artifactId>
+ <version>${testng.version}</version>
+ <scope>compile</scope> <!-- yes, this is meant to be in compile, because we're providing assertions
+ to the scripts -->
+ </dependency>
+
+ <dependency>
+ <groupId>net.sf.opencsv</groupId>
+ <artifactId>opencsv</artifactId>
+ <version>${opencsv.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>jboss</groupId>
+ <artifactId>javassist</artifactId>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+
+ <plugin>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <configuration>
+ <excludedGroups>${rhq.testng.excludedGroups}</excludedGroups>
+ <!-- <argLine>-Xdebug -Xnoagent -Djava.compiler=NONE
+ -Xrunjdwp:transport=dt_socket,address=8787,server=y,suspend=y</argLine> -->
+ </configuration>
+ </plugin>
+
+ </plugins>
+ </build>
+
+ <profiles>
+
+ <profile>
+ <id>dev</id>
+
+ <properties>
+ <rhq.rootDir>../../..</rhq.rootDir>
+ <rhq.containerDir>${rhq.rootDir}/${rhq.defaultDevContainerPath}</rhq.containerDir>
+ <rhq.deploymentDir>${rhq.containerDir}/jbossas/server/default/deploy/${rhq.earName}/lib</rhq.deploymentDir>
+ </properties>
+
+ <build>
+ <plugins>
+
+ <plugin>
+ <artifactId>maven-antrun-plugin</artifactId>
+ <version>1.1</version>
+ <executions>
+
+ <execution>
+ <id>deploy</id>
+ <phase>compile</phase>
+ <configuration>
+ <tasks>
+ <mkdir dir="${rhq.deploymentDir}" />
+ <property name="deployment.file"
+ location="${rhq.deploymentDir}/${project.build.finalName}.jar" />
+ <echo>*** Updating
+ ${deployment.file}...</echo>
+ <jar destfile="${deployment.file}"
+ basedir="${project.build.outputDirectory}" />
+ </tasks>
+ </configuration>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ </execution>
+
+ <execution>
+ <id>undeploy</id>
+ <phase>clean</phase>
+ <configuration>
+ <tasks>
+ <property name="deployment.file"
+ location="${rhq.deploymentDir}/${project.build.finalName}.jar" />
+ <echo>*** Deleting
+ ${deployment.file}...</echo>
+ <delete file="${deployment.file}" />
+ </tasks>
+ </configuration>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ </execution>
+
+ </executions>
+ </plugin>
+
+ </plugins>
+ </build>
+ </profile>
+
+ <profile>
+ <id>cobertura-plugins</id>
+ <activation>
+ <activeByDefault>false</activeByDefault>
+ </activation>
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-antrun-plugin</artifactId>
+ <dependencies>
+ <dependency>
+ <groupId>net.sourceforge.cobertura</groupId>
+ <artifactId>cobertura</artifactId>
+ <version>1.9.4.1</version>
+ </dependency>
+ </dependencies>
+ <executions>
+ <execution>
+ <id>cobertura-instrument</id>
+ <phase>pre-integration-test</phase>
+ <configuration>
+ <tasks>
+ <!-- prepare directory structure
+ for cobertura -->
+ <mkdir dir="target/cobertura" />
+ <mkdir dir="target/cobertura/backup" />
+ <!-- backup all classes so that we
+ can instrument the original classes -->
+ <copy toDir="target/cobertura/backup"
+ verbose="true" overwrite="true">
+ <fileset dir="target/classes">
+ <include name="**/*.class" />
+ </fileset>
+ </copy>
+ <!-- create a properties file and
+ save there location of cobertura data file -->
+ <touch
+ file="target/classes/cobertura.properties" />
+ <echo
+ file="target/classes/cobertura.properties">net.sourceforge.cobertura.datafile=${project.build.directory}/cobertura/cobertura.ser</echo>
+ <taskdef
+ classpathref="maven.plugin.classpath"
+ resource="tasks.properties" />
+ <!-- instrument all classes in target/classes
+ directory -->
+ <cobertura-instrument
+ datafile="${project.build.directory}/cobertura/cobertura.ser"
+ todir="${project.build.directory}/classes">
+ <fileset
+ dir="${project.build.directory}/classes">
+ <include name="**/*.class" />
+ </fileset>
+ </cobertura-instrument>
+ </tasks>
+ </configuration>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ </execution>
+ <execution>
+ <id>cobertura-report</id>
+ <phase>post-integration-test</phase>
+ <configuration>
+ <tasks>
+ <taskdef
+ classpathref="maven.plugin.classpath"
+ resource="tasks.properties" />
+ <!-- prepare directory structure
+ for cobertura -->
+ <mkdir dir="target/cobertura" />
+ <mkdir dir="target/site/cobertura" />
+ <!-- restore classes from backup
+ folder to classes folder -->
+ <copy toDir="target/classes"
+ verbose="true" overwrite="true">
+ <fileset
+ dir="target/cobertura/backup">
+ <include name="**/*.class" />
+ </fileset>
+ </copy>
+ <!-- delete backup folder -->
+ <delete
+ dir="target/cobertura/backup" />
+ <!-- create a code coverage report -->
+ <cobertura-report
+ format="html"
+ datafile="${project.build.directory}/cobertura/cobertura.ser"
+ destdir="${project.build.directory}/site/cobertura">
+ <fileset
+ dir="${basedir}/src/main/java">
+ <include name="**/*.java" />
+ </fileset>
+ </cobertura-report>
+ <!-- delete cobertura.properties
+ file -->
+ <delete
+ file="target/classes/cobertura.properties" />
+ </tasks>
+ </configuration>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ </profiles>
</project>
\ No newline at end of file
diff --git a/modules/enterprise/server/client-api/pom.xml b/modules/enterprise/server/client-api/pom.xml
index 47d1f6b..d605b1c 100644
--- a/modules/enterprise/server/client-api/pom.xml
+++ b/modules/enterprise/server/client-api/pom.xml
@@ -1,21 +1,228 @@
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <artifactId>rhq-enterprise-server-parent</artifactId>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <artifactId>rhq-enterprise-server-parent</artifactId>
+ <groupId>org.rhq</groupId>
+ <version>4.0.0-SNAPSHOT</version>
+ </parent>
<groupId>org.rhq</groupId>
+ <artifactId>rhq-server-client-api</artifactId>
<version>4.0.0-SNAPSHOT</version>
- </parent>
- <groupId>org.rhq</groupId>
- <artifactId>rhq-server-client-api</artifactId>
- <version>4.0.0-SNAPSHOT</version>
- <name>RHQ Enterprise Server Client API</name>
- <description>The implementation of the client API when accessing the server locally</description>
- <dependencies>
- <dependency>
- <groupId>org.rhq</groupId>
- <artifactId>rhq-script-bindings</artifactId>
- <version>4.0.0-SNAPSHOT</version>
- <scope>compile</scope>
- </dependency>
- </dependencies>
+ <name>RHQ Enterprise Server Client API</name>
+ <description>The implementation of the client API when accessing the server locally</description>
+
+ <properties>
+ <persistence-api.version>1.0</persistence-api.version>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-script-bindings</artifactId>
+ <version>${project.version}</version>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>javax.persistence</groupId>
+ <artifactId>persistence-api</artifactId>
+ <version>${persistence-api.version}</version>
+ <scope>provided</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>hibernate-annotations</groupId>
+ <artifactId>hibernate-annotations</artifactId>
+ <!-- NOTE: The version is defined in the root POM's dependencyManagement
+ section. -->
+ <scope>provided</scope>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+
+ <plugin>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <configuration>
+ <excludedGroups>${rhq.testng.excludedGroups}</excludedGroups>
+ <!-- <argLine>-Xdebug -Xnoagent -Djava.compiler=NONE
+ -Xrunjdwp:transport=dt_socket,address=8787,server=y,suspend=y</argLine> -->
+ </configuration>
+ </plugin>
+
+ </plugins>
+ </build>
+
+ <profiles>
+
+ <profile>
+ <id>dev</id>
+
+ <properties>
+ <rhq.rootDir>../../..</rhq.rootDir>
+ <rhq.containerDir>${rhq.rootDir}/${rhq.defaultDevContainerPath}</rhq.containerDir>
+ <rhq.deploymentDir>${rhq.containerDir}/jbossas/server/default/deploy/${rhq.earName}/lib</rhq.deploymentDir>
+ </properties>
+
+ <build>
+ <plugins>
+
+ <plugin>
+ <artifactId>maven-antrun-plugin</artifactId>
+ <version>1.1</version>
+ <executions>
+
+ <execution>
+ <id>deploy</id>
+ <phase>compile</phase>
+ <configuration>
+ <tasks>
+ <mkdir dir="${rhq.deploymentDir}" />
+ <property name="deployment.file"
+ location="${rhq.deploymentDir}/${project.build.finalName}.jar" />
+ <echo>*** Updating
+ ${deployment.file}...</echo>
+ <jar destfile="${deployment.file}"
+ basedir="${project.build.outputDirectory}" />
+ </tasks>
+ </configuration>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ </execution>
+
+ <execution>
+ <id>undeploy</id>
+ <phase>clean</phase>
+ <configuration>
+ <tasks>
+ <property name="deployment.file"
+ location="${rhq.deploymentDir}/${project.build.finalName}.jar" />
+ <echo>*** Deleting
+ ${deployment.file}...</echo>
+ <delete file="${deployment.file}" />
+ </tasks>
+ </configuration>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ </execution>
+
+ </executions>
+ </plugin>
+
+ </plugins>
+ </build>
+ </profile>
+
+ <profile>
+ <id>cobertura-plugins</id>
+ <activation>
+ <activeByDefault>false</activeByDefault>
+ </activation>
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-antrun-plugin</artifactId>
+ <dependencies>
+ <dependency>
+ <groupId>net.sourceforge.cobertura</groupId>
+ <artifactId>cobertura</artifactId>
+ <version>1.9.4.1</version>
+ </dependency>
+ </dependencies>
+ <executions>
+ <execution>
+ <id>cobertura-instrument</id>
+ <phase>pre-integration-test</phase>
+ <configuration>
+ <tasks>
+ <!-- prepare directory structure
+ for cobertura -->
+ <mkdir dir="target/cobertura" />
+ <mkdir dir="target/cobertura/backup" />
+ <!-- backup all classes so that we
+ can instrument the original classes -->
+ <copy toDir="target/cobertura/backup"
+ verbose="true" overwrite="true">
+ <fileset dir="target/classes">
+ <include name="**/*.class" />
+ </fileset>
+ </copy>
+ <!-- create a properties file and
+ save there location of cobertura data file -->
+ <touch
+ file="target/classes/cobertura.properties" />
+ <echo
+ file="target/classes/cobertura.properties">net.sourceforge.cobertura.datafile=${project.build.directory}/cobertura/cobertura.ser</echo>
+ <taskdef
+ classpathref="maven.plugin.classpath"
+ resource="tasks.properties" />
+ <!-- instrument all classes in target/classes
+ directory -->
+ <cobertura-instrument
+ datafile="${project.build.directory}/cobertura/cobertura.ser"
+ todir="${project.build.directory}/classes">
+ <fileset
+ dir="${project.build.directory}/classes">
+ <include name="**/*.class" />
+ </fileset>
+ </cobertura-instrument>
+ </tasks>
+ </configuration>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ </execution>
+ <execution>
+ <id>cobertura-report</id>
+ <phase>post-integration-test</phase>
+ <configuration>
+ <tasks>
+ <taskdef
+ classpathref="maven.plugin.classpath"
+ resource="tasks.properties" />
+ <!-- prepare directory structure
+ for cobertura -->
+ <mkdir dir="target/cobertura" />
+ <mkdir dir="target/site/cobertura" />
+ <!-- restore classes from backup
+ folder to classes folder -->
+ <copy toDir="target/classes"
+ verbose="true" overwrite="true">
+ <fileset
+ dir="target/cobertura/backup">
+ <include name="**/*.class" />
+ </fileset>
+ </copy>
+ <!-- delete backup folder -->
+ <delete
+ dir="target/cobertura/backup" />
+ <!-- create a code coverage report -->
+ <cobertura-report
+ format="html"
+ datafile="${project.build.directory}/cobertura/cobertura.ser"
+ destdir="${project.build.directory}/site/cobertura">
+ <fileset
+ dir="${basedir}/src/main/java">
+ <include name="**/*.java" />
+ </fileset>
+ </cobertura-report>
+ <!-- delete cobertura.properties
+ file -->
+ <delete
+ file="target/classes/cobertura.properties" />
+ </tasks>
+ </configuration>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ </profiles>
</project>
\ No newline at end of file
diff --git a/modules/enterprise/server/plugins/alert-cli/pom.xml b/modules/enterprise/server/plugins/alert-cli/pom.xml
index 5349beb..7b71a2f 100644
--- a/modules/enterprise/server/plugins/alert-cli/pom.xml
+++ b/modules/enterprise/server/plugins/alert-cli/pom.xml
@@ -1,4 +1,5 @@
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>rhq-enterprise-server-plugins-parent</artifactId>
@@ -10,23 +11,238 @@
<version>4.0.0-SNAPSHOT</version>
<name>RHQ Enterprise Server CLI Script Alert Plugin</name>
<description>An alert sender able to execute an arbitrary CLI script as a response to an alert</description>
-
- <scm>
- <connection>scm:git:ssh://git.fedorahosted.org/git/rhq.git/modules/enterprise/server/...</connection>
- <developerConnection>scm:git:ssh://git.fedorahosted.org/git/rhq.git/modules/enterprise/server/...</developerConnection>
- </scm>
-
- <dependencies>
- <dependency>
- <groupId>org.rhq</groupId>
- <artifactId>rhq-server-client-api</artifactId>
- <version>4.0.0-SNAPSHOT</version>
- <type>jar</type>
- <scope>compile</scope>
- </dependency>
- </dependencies>
- <properties>
- <scm.module.path>modules/enterprise/server/plugins/alert-cli/</scm.module.path>
- </properties>
-
+
+ <properties>
+ <scm.module.path>modules/enterprise/server/plugins/alert-cli/</scm.module.path>
+ </properties>
+
+ <scm>
+ <connection>scm:git:ssh://git.fedorahosted.org/git/rhq.git/modules/enterprise/server/...</connection>
+ <developerConnection>scm:git:ssh://git.fedorahosted.org/git/rhq.git/modules/enterprise/server/...</developerConnection>
+ </scm>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-server-client-api</artifactId>
+ <version>4.0.0-SNAPSHOT</version>
+ <type>jar</type>
+ <scope>compile</scope>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+
+ <plugin>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <configuration>
+ <excludedGroups>${rhq.testng.excludedGroups}</excludedGroups>
+ <!-- <argLine>-Xdebug -Xnoagent -Djava.compiler=NONE
+ -Xrunjdwp:transport=dt_socket,address=8787,server=y,suspend=y</argLine> -->
+ </configuration>
+ </plugin>
+
+ </plugins>
+ </build>
+
+ <profiles>
+
+ <profile>
+ <id>dev</id>
+
+ <properties>
+ <rhq.rootDir>../../../../..</rhq.rootDir>
+ <rhq.containerDir>${rhq.rootDir}/${rhq.defaultDevContainerPath}</rhq.containerDir>
+ <rhq.deploymentDir>${rhq.containerDir}/jbossas/server/default/deploy/${rhq.earName}/rhq-serverplugins</rhq.deploymentDir>
+ </properties>
+
+ <build>
+ <plugins>
+
+ <plugin>
+ <artifactId>maven-antrun-plugin</artifactId>
+ <version>1.1</version>
+ <executions>
+
+ <execution>
+ <id>deploy</id>
+ <phase>compile</phase>
+ <configuration>
+ <tasks>
+ <mkdir dir="${rhq.deploymentDir}" />
+ <property name="deployment.file"
+ location="${rhq.deploymentDir}/${project.build.finalName}.jar" />
+ <echo>*** Updating
+ ${deployment.file}...</echo>
+ <jar destfile="${deployment.file}"
+ basedir="${project.build.outputDirectory}" />
+ </tasks>
+ </configuration>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ </execution>
+
+ <execution>
+ <id>undeploy</id>
+ <phase>clean</phase>
+ <configuration>
+ <tasks>
+ <property name="deployment.file"
+ location="${rhq.deploymentDir}/${project.build.finalName}.jar" />
+ <echo>*** Deleting
+ ${deployment.file}...</echo>
+ <delete file="${deployment.file}" />
+ </tasks>
+ </configuration>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ </execution>
+
+ <execution>
+ <id>deploy-jar-meta-inf</id>
+ <phase>package</phase>
+ <configuration>
+ <tasks>
+ <property name="deployment.file"
+ location="${rhq.deploymentDir}/${project.build.finalName}.jar" />
+ <echo>*** Updating META-INF dir
+ in ${deployment.file}...</echo>
+ <unjar
+ src="${project.build.directory}/${project.build.finalName}.jar"
+ dest="${project.build.outputDirectory}">
+ <patternset>
+ <include name="META-INF/**" />
+ </patternset>
+ </unjar>
+ <jar destfile="${deployment.file}"
+ manifest="${project.build.outputDirectory}/META-INF/MANIFEST.MF"
+ update="true">
+ </jar>
+ </tasks>
+ </configuration>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ </execution>
+
+ </executions>
+ </plugin>
+
+ </plugins>
+ </build>
+ </profile>
+
+ <profile>
+ <id>cobertura-plugins</id>
+ <activation>
+ <activeByDefault>false</activeByDefault>
+ </activation>
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-antrun-plugin</artifactId>
+ <dependencies>
+ <dependency>
+ <groupId>net.sourceforge.cobertura</groupId>
+ <artifactId>cobertura</artifactId>
+ <version>1.9.4.1</version>
+ </dependency>
+ </dependencies>
+ <executions>
+ <execution>
+ <id>cobertura-instrument</id>
+ <phase>pre-integration-test</phase>
+ <configuration>
+ <tasks>
+ <!-- prepare directory structure
+ for cobertura -->
+ <mkdir dir="target/cobertura" />
+ <mkdir dir="target/cobertura/backup" />
+ <!-- backup all classes so that we
+ can instrument the original classes -->
+ <copy toDir="target/cobertura/backup"
+ verbose="true" overwrite="true">
+ <fileset dir="target/classes">
+ <include name="**/*.class" />
+ </fileset>
+ </copy>
+ <!-- create a properties file and
+ save there location of cobertura data file -->
+ <touch
+ file="target/classes/cobertura.properties" />
+ <echo
+ file="target/classes/cobertura.properties">net.sourceforge.cobertura.datafile=${project.build.directory}/cobertura/cobertura.ser</echo>
+ <taskdef
+ classpathref="maven.plugin.classpath"
+ resource="tasks.properties" />
+ <!-- instrument all classes in target/classes
+ directory -->
+ <cobertura-instrument
+ datafile="${project.build.directory}/cobertura/cobertura.ser"
+ todir="${project.build.directory}/classes">
+ <fileset
+ dir="${project.build.directory}/classes">
+ <include name="**/*.class" />
+ </fileset>
+ </cobertura-instrument>
+ </tasks>
+ </configuration>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ </execution>
+ <execution>
+ <id>cobertura-report</id>
+ <phase>post-integration-test</phase>
+ <configuration>
+ <tasks>
+ <taskdef
+ classpathref="maven.plugin.classpath"
+ resource="tasks.properties" />
+ <!-- prepare directory structure
+ for cobertura -->
+ <mkdir dir="target/cobertura" />
+ <mkdir dir="target/site/cobertura" />
+ <!-- restore classes from backup
+ folder to classes folder -->
+ <copy toDir="target/classes"
+ verbose="true" overwrite="true">
+ <fileset
+ dir="target/cobertura/backup">
+ <include name="**/*.class" />
+ </fileset>
+ </copy>
+ <!-- delete backup folder -->
+ <delete
+ dir="target/cobertura/backup" />
+ <!-- create a code coverage report -->
+ <cobertura-report
+ format="html"
+ datafile="${project.build.directory}/cobertura/cobertura.ser"
+ destdir="${project.build.directory}/site/cobertura">
+ <fileset
+ dir="${basedir}/src/main/java">
+ <include name="**/*.java" />
+ </fileset>
+ </cobertura-report>
+ <!-- delete cobertura.properties
+ file -->
+ <delete
+ file="target/classes/cobertura.properties" />
+ </tasks>
+ </configuration>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ </profiles>
+
</project>
\ No newline at end of file
commit 31fada88661aba7a52d79519e32b9742224ffcb0
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Sat Jan 15 00:39:26 2011 +0100
Some initial code for the alert-cli plugin.
diff --git a/modules/enterprise/server/plugins/alert-cli/pom.xml b/modules/enterprise/server/plugins/alert-cli/pom.xml
index 55aa5d3..5349beb 100644
--- a/modules/enterprise/server/plugins/alert-cli/pom.xml
+++ b/modules/enterprise/server/plugins/alert-cli/pom.xml
@@ -16,6 +16,15 @@
<developerConnection>scm:git:ssh://git.fedorahosted.org/git/rhq.git/modules/enterprise/server/...</developerConnection>
</scm>
+ <dependencies>
+ <dependency>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-server-client-api</artifactId>
+ <version>4.0.0-SNAPSHOT</version>
+ <type>jar</type>
+ <scope>compile</scope>
+ </dependency>
+ </dependencies>
<properties>
<scm.module.path>modules/enterprise/server/plugins/alert-cli/</scm.module.path>
</properties>
diff --git a/modules/enterprise/server/plugins/alert-cli/src/main/java/org/rhq/enterprise/server/plugins/alertCli/CliSender.java b/modules/enterprise/server/plugins/alert-cli/src/main/java/org/rhq/enterprise/server/plugins/alertCli/CliSender.java
new file mode 100644
index 0000000..64d1a22
--- /dev/null
+++ b/modules/enterprise/server/plugins/alert-cli/src/main/java/org/rhq/enterprise/server/plugins/alertCli/CliSender.java
@@ -0,0 +1,112 @@
+/*
+ * 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 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.server.plugins.alertCli;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.Collections;
+
+import javax.script.ScriptEngine;
+import javax.script.ScriptException;
+
+import org.apache.commons.logging.LogFactory;
+
+import org.apache.commons.logging.Log;
+
+import org.rhq.bindings.ScriptEngineFactory;
+import org.rhq.bindings.StandardBindings;
+import org.rhq.bindings.util.PackageFinder;
+import org.rhq.core.domain.alert.Alert;
+import org.rhq.core.domain.alert.notification.SenderResult;
+import org.rhq.core.domain.auth.Subject;
+import org.rhq.core.domain.configuration.PropertySimple;
+import org.rhq.enterprise.client.LocalClient;
+import org.rhq.enterprise.server.plugin.pc.ServerPluginComponent;
+import org.rhq.enterprise.server.plugin.pc.alert.AlertSender;
+import org.rhq.enterprise.server.util.LookupUtil;
+
+/**
+ * Uses CLI to perform the alert notification.
+ *
+ * @author Lukas Krejci
+ */
+public class CliSender extends AlertSender<ServerPluginComponent> {
+ private static final Log LOG = LogFactory.getLog(CliSender.class);
+
+ public SenderResult send(Alert alert) {
+ SenderResult result = new SenderResult();
+ BufferedReader reader = null;
+ try {
+ ScriptEngine engine = getScriptEngine(alert);
+
+ PropertySimple packageIdProp = alertParameters.getSimple("packageId");
+
+ if (packageIdProp == null) {
+ return SenderResult.getSimpleFailure("The configuration doesn't contain the mandatory 'packageId' property. This should not happen.");
+ }
+
+ Integer packageId = packageIdProp.getIntegerValue();
+
+ if (packageId == null) {
+ return SenderResult.getSimpleFailure("No script defined.");
+ }
+
+ //TODO getting the package bits is going to require changes to the content manager
+ //this is gonna have to be asynchronous because the package bits are possibly
+ //only going to be downloaded.
+ InputStream packageBits = null;
+
+ reader = new BufferedReader(new InputStreamReader(packageBits));
+
+ Object ret = engine.eval(reader);
+
+ //TODO what to do with the return value, if any
+
+ return result;
+ } catch (Exception e) {
+ //TODO I don't like this
+ return SenderResult.getSimpleFailure(e.getMessage());
+ } finally {
+ if (reader != null) {
+ try {
+ reader.close();
+ } catch (IOException e) {
+ LOG.error("Failed to close the script reader.", e);
+ }
+ }
+ }
+ }
+
+ private ScriptEngine getScriptEngine(Alert alert) throws ScriptException, IOException {
+ Subject overlord = LookupUtil.getSubjectManager().getOverlord();
+
+ LocalClient client = new LocalClient(overlord);
+
+ //TODO define some meaningful printwriter
+ StandardBindings bindings = new StandardBindings(null, client);
+ bindings.put("alert", alert);
+
+ return ScriptEngineFactory.getScriptEngine("JavaScript", new PackageFinder(Collections.<File> emptyList()),
+ bindings);
+ }
+}
diff --git a/modules/enterprise/server/plugins/alert-cli/src/main/resources/META-INF/rhq-serverplugin.xml b/modules/enterprise/server/plugins/alert-cli/src/main/resources/META-INF/rhq-serverplugin.xml
new file mode 100644
index 0000000..ffcbb4b
--- /dev/null
+++ b/modules/enterprise/server/plugins/alert-cli/src/main/resources/META-INF/rhq-serverplugin.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<alert-plugin
+ name="alert-cli"
+ displayName="Alert:CLI"
+ xmlns="urn:xmlns:rhq-serverplugin.alert"
+ xmlns:c="urn:xmlns:rhq-configuration"
+ xmlns:serverplugin="urn:xmlns:rhq-serverplugin"
+ package="org.rhq.enterprise.server.plugins.alertCli"
+ description="Alert sender plugin that can execute a CLI script."
+ >
+
+ <serverplugin:help>
+ Used to execute a CLI script.
+ </serverplugin:help>
+
+ <!-- How does this sender show up in drop downs etc -->
+ <short-name>CLI Script</short-name>
+
+ <!-- Class that does the actual sending -->
+ <plugin-class>CliSender</plugin-class>
+
+ <alert-configuration>
+ <c:simple-property name="packageId" type="integer" required="true" description="The id of the package containing the script to execute."/>
+ </alert-configuration>
+</alert-plugin>
\ No newline at end of file
diff --git a/modules/enterprise/server/plugins/pom.xml b/modules/enterprise/server/plugins/pom.xml
index 29d09dd..86d8cfe 100644
--- a/modules/enterprise/server/plugins/pom.xml
+++ b/modules/enterprise/server/plugins/pom.xml
@@ -80,6 +80,7 @@
-->
<module>alert-snmp</module>
<module>alert-subject</module>
+ <module>alert-cli</module>
<module>cobbler</module>
<module>filetemplate-bundle</module>
<module>ant-bundle</module>
commit 85a908e58fd9f691c6e730ec7a358e3b97a9ca7c
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Sat Jan 15 00:37:43 2011 +0100
Defining a new implementation of the RhqFacade that uses the local SLSBs and created a new server/client-api module for it to be used for running the server-side CLI scripts.
diff --git a/modules/enterprise/binding/src/main/java/org/rhq/bindings/client/AbstractRhqFacadeProxy.java b/modules/enterprise/binding/src/main/java/org/rhq/bindings/client/AbstractRhqFacadeProxy.java
new file mode 100644
index 0000000..bacdafb
--- /dev/null
+++ b/modules/enterprise/binding/src/main/java/org/rhq/bindings/client/AbstractRhqFacadeProxy.java
@@ -0,0 +1,103 @@
+/*
+ * 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 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.bindings.client;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+
+import org.rhq.bindings.util.InterfaceSimplifier;
+import org.rhq.core.domain.auth.Subject;
+
+/**
+ * An abstract {@link InvocationHandler} to help the script users create proxies to actually call the
+ * correct methods on RHQ. This base implementation provides its inheritors with the facade impl and the concrete
+ * manager they should invoke the methods on and does the "de-simplification" of the arguments (i.e. the opposite of {@link InterfaceSimplifier#simplify(Class)}.
+ *
+ * @author Lukas Krejci
+ */
+public abstract class AbstractRhqFacadeProxy<T extends RhqFacade> implements InvocationHandler {
+
+ private T facade;
+ private RhqManagers manager;
+
+ protected AbstractRhqFacadeProxy(T facade, RhqManagers manager) {
+ this.facade = facade;
+ this.manager = manager;
+ }
+
+ protected T getRhqFacade() {
+ return facade;
+ }
+
+ protected RhqManagers getManager() {
+ return manager;
+ }
+
+ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+ Class<?>[] params = method.getParameterTypes();
+
+ try {
+ Class<?>[] interfaces = method.getDeclaringClass().getInterfaces();
+
+ Class<?> originalClass;
+ if (interfaces != null && interfaces.length > 0) {
+ originalClass = interfaces[0];
+ } else {
+ originalClass = method.getDeclaringClass();
+ }
+
+ // See if this method really exists or if its a simplified set of parameters
+ originalClass.getMethod(method.getName(), method.getParameterTypes());
+
+ } catch (Exception e) {
+ // If this was not in the original interface it must've been added in the Simplifier... add back the subject argument
+ int numArgs = (null == args) ? 0 : args.length;
+ Object[] newArgs = new Object[numArgs + 1];
+ if (numArgs > 0) {
+ System.arraycopy(args, 0, newArgs, 1, numArgs);
+ }
+ newArgs[0] = getRhqFacade().getSubject();
+ args = newArgs;
+
+ int numParams = (null == params) ? 0 : params.length;
+ Class<?>[] newParams = new Class[numParams + 1];
+ if (numParams > 0) {
+ System.arraycopy(params, 0, newParams, 1, numParams);
+ }
+ newParams[0] = Subject.class;
+ params = newParams;
+ }
+
+ return doInvoke(proxy, method, params, args);
+ }
+
+ /**
+ * This method actually calls the method according to the RhqFacade's implementation. The <code>argTypes</code>
+ * and <code>args</code> are de-simplified (and thus the method can't be supplied just as a simple {@link Method} instance).
+ *
+ * @param proxy the proxy the method is executing on
+ * @param method the original method
+ * @param argTypes the de-simplified argument types
+ * @param args the de-simplified argumens
+ * @return the result of the invocation
+ * @throws Throwable if invocation throws an error
+ */
+ protected abstract Object doInvoke(Object proxy, Method originalMethod, Class<?>[] argTypes, Object[] args) throws Throwable;
+}
diff --git a/modules/enterprise/remoting/client-api/src/main/java/org/rhq/enterprise/client/RemoteClientProxy.java b/modules/enterprise/remoting/client-api/src/main/java/org/rhq/enterprise/client/RemoteClientProxy.java
index 5e897cb..2d57488 100644
--- a/modules/enterprise/remoting/client-api/src/main/java/org/rhq/enterprise/client/RemoteClientProxy.java
+++ b/modules/enterprise/remoting/client-api/src/main/java/org/rhq/enterprise/client/RemoteClientProxy.java
@@ -18,18 +18,14 @@
*/
package org.rhq.enterprise.client;
-import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
import org.jboss.remoting.invocation.NameBasedInvocation;
+import org.rhq.bindings.client.AbstractRhqFacadeProxy;
import org.rhq.bindings.client.RhqManagers;
import org.rhq.bindings.util.InterfaceSimplifier;
-import org.rhq.core.domain.auth.Subject;
import org.rhq.core.server.ExternalizableStrategy;
/**
@@ -37,19 +33,16 @@ import org.rhq.core.server.ExternalizableStrategy;
* to SLSB Remotes over a remoting invoker.
*
* @author Greg Hinkle
+ * @author Lukas Krejci
*/
-public class RemoteClientProxy implements InvocationHandler {
- private RemoteClient client;
- private RhqManagers manager;
+public class RemoteClientProxy extends AbstractRhqFacadeProxy<RemoteClient> {
- // public RHQRemoteClientProxy(RHQRemoteClient client, Class targetClass) {
public RemoteClientProxy(RemoteClient client, RhqManagers manager) {
- this.client = client;
- this.manager = manager;
+ super(client, manager);
}
public Class<?> getRemoteInterface() {
- return this.manager.remote();
+ return this.getManager().remote();
}
@SuppressWarnings("unchecked")
@@ -57,7 +50,7 @@ public class RemoteClientProxy implements InvocationHandler {
try {
RemoteClientProxy gpc = new RemoteClientProxy(remoteClient, manager);
- Class<?> intf = InterfaceSimplifier.simplify(gpc.manager.remote());
+ Class<?> intf = InterfaceSimplifier.simplify(manager.remote());
return (T) Proxy
.newProxyInstance(Thread.currentThread().getContextClassLoader(), new Class<?>[] { intf }, gpc);
@@ -67,62 +60,32 @@ public class RemoteClientProxy implements InvocationHandler {
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
-
try {
- // make sure we're serializing in Remote Client mode for rich serialization
- ExternalizableStrategy.setStrategy(ExternalizableStrategy.Subsystem.REFLECTIVE_SERIALIZATION);
-
- String methodName = manager.beanName() + ":" + method.getName();
-
- Class<?>[] params = method.getParameterTypes();
-
- try {
- Class<?>[] interfaces = method.getDeclaringClass().getInterfaces();
-
- Class<?> originalClass;
- if (interfaces != null && interfaces.length > 0) {
- originalClass = interfaces[0];
- } else {
- originalClass = method.getDeclaringClass();
- }
-
- // See if this method really exists or if its a simplified set of parameters
- originalClass.getMethod(method.getName(), method.getParameterTypes());
+ return super.invoke(proxy, method, args);
+ } catch (Throwable t) {
+ t.printStackTrace();
+ throw t;
+ }
+ }
- } catch (Exception e) {
- // If this was not in the original interface it must've been added in the Simplifier... add back the subject argument
- int numArgs = (null == args) ? 0 : args.length;
- Object[] newArgs = new Object[numArgs + 1];
- if (numArgs > 0) {
- System.arraycopy(args, 0, newArgs, 1, numArgs);
- }
- newArgs[0] = client.getSubject();
- args = newArgs;
+ protected Object doInvoke(Object proxy, Method originalMethod, java.lang.Class<?>[] argTypes, Object[] args) throws Throwable {
+ ExternalizableStrategy.setStrategy(ExternalizableStrategy.Subsystem.REFLECTIVE_SERIALIZATION);
- int numParams = (null == params) ? 0 : params.length;
- Class<?>[] newParams = new Class[numParams + 1];
- if (numParams > 0) {
- System.arraycopy(params, 0, newParams, 1, numParams);
- }
- newParams[0] = Subject.class;
- params = newParams;
- }
+ String methodName = getManager().beanName() + ":" + originalMethod.getName();
- String[] paramSig = createParamSignature(params);
- NameBasedInvocation request = new NameBasedInvocation(methodName, args, paramSig);
+ String[] paramSig = createParamSignature(argTypes);
+
+ NameBasedInvocation request = new NameBasedInvocation(methodName, args, paramSig);
- Object response = client.getRemotingClient().invoke(request);
+ Object response = getRhqFacade().getRemotingClient().invoke(request);
- if (response instanceof Throwable) {
- throw (Throwable) response;
- }
- return response;
- } catch (Throwable t) {
- t.printStackTrace();
- throw t;
+ if (response instanceof Throwable) {
+ throw (Throwable) response;
}
+
+ return response;
}
-
+
private String[] createParamSignature(Class<?>[] types) {
String[] paramSig = new String[types.length];
for (int x = 0; x < types.length; x++) {
diff --git a/modules/enterprise/server/client-api/pom.xml b/modules/enterprise/server/client-api/pom.xml
new file mode 100644
index 0000000..47d1f6b
--- /dev/null
+++ b/modules/enterprise/server/client-api/pom.xml
@@ -0,0 +1,21 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <artifactId>rhq-enterprise-server-parent</artifactId>
+ <groupId>org.rhq</groupId>
+ <version>4.0.0-SNAPSHOT</version>
+ </parent>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-server-client-api</artifactId>
+ <version>4.0.0-SNAPSHOT</version>
+ <name>RHQ Enterprise Server Client API</name>
+ <description>The implementation of the client API when accessing the server locally</description>
+ <dependencies>
+ <dependency>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-script-bindings</artifactId>
+ <version>4.0.0-SNAPSHOT</version>
+ <scope>compile</scope>
+ </dependency>
+ </dependencies>
+</project>
\ No newline at end of file
diff --git a/modules/enterprise/server/client-api/src/main/java/org/rhq/enterprise/client/LocalClient.java b/modules/enterprise/server/client-api/src/main/java/org/rhq/enterprise/client/LocalClient.java
new file mode 100644
index 0000000..0462638
--- /dev/null
+++ b/modules/enterprise/server/client-api/src/main/java/org/rhq/enterprise/client/LocalClient.java
@@ -0,0 +1,223 @@
+/*
+ * 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 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.client;
+
+import java.lang.reflect.Method;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.rhq.bindings.client.RhqFacade;
+import org.rhq.bindings.client.RhqManagers;
+import org.rhq.core.domain.auth.Subject;
+import org.rhq.enterprise.server.alert.AlertDefinitionManagerRemote;
+import org.rhq.enterprise.server.alert.AlertManagerRemote;
+import org.rhq.enterprise.server.auth.SubjectManagerRemote;
+import org.rhq.enterprise.server.authz.RoleManagerRemote;
+import org.rhq.enterprise.server.bundle.BundleManagerRemote;
+import org.rhq.enterprise.server.configuration.ConfigurationManagerRemote;
+import org.rhq.enterprise.server.content.ContentManagerRemote;
+import org.rhq.enterprise.server.content.RepoManagerRemote;
+import org.rhq.enterprise.server.discovery.DiscoveryBossRemote;
+import org.rhq.enterprise.server.event.EventManagerRemote;
+import org.rhq.enterprise.server.install.remote.RemoteInstallManagerRemote;
+import org.rhq.enterprise.server.measurement.AvailabilityManagerRemote;
+import org.rhq.enterprise.server.measurement.CallTimeDataManagerRemote;
+import org.rhq.enterprise.server.measurement.MeasurementBaselineManagerRemote;
+import org.rhq.enterprise.server.measurement.MeasurementDataManagerRemote;
+import org.rhq.enterprise.server.measurement.MeasurementDefinitionManagerRemote;
+import org.rhq.enterprise.server.measurement.MeasurementScheduleManagerRemote;
+import org.rhq.enterprise.server.operation.OperationManagerRemote;
+import org.rhq.enterprise.server.report.DataAccessManagerRemote;
+import org.rhq.enterprise.server.resource.ResourceFactoryManagerRemote;
+import org.rhq.enterprise.server.resource.ResourceManagerRemote;
+import org.rhq.enterprise.server.resource.ResourceTypeManagerRemote;
+import org.rhq.enterprise.server.resource.group.ResourceGroupManagerRemote;
+import org.rhq.enterprise.server.search.SavedSearchManagerRemote;
+import org.rhq.enterprise.server.support.SupportManagerRemote;
+import org.rhq.enterprise.server.system.SystemManagerRemote;
+import org.rhq.enterprise.server.tagging.TagManagerRemote;
+import org.rhq.enterprise.server.util.LookupUtil;
+
+/**
+ *
+ *
+ * @author Lukas Krejci
+ */
+public class LocalClient implements RhqFacade {
+
+ private static final Log LOG = LogFactory.getLog(LocalClient.class);
+
+ private Subject subject;
+ private Map<String, Object> managers;
+
+ public LocalClient(Subject subject) {
+ this.subject = subject;
+ }
+
+ public Subject getSubject() {
+ return subject;
+ }
+
+ public Subject login(String user, String password) throws Exception {
+ return subject;
+ }
+
+ public void logout() {
+ }
+
+ public boolean isLoggedIn() {
+ return true;
+ }
+
+ public AlertManagerRemote getAlertManager() {
+ return getProxy(LookupUtil.getAlertManager(), AlertManagerRemote.class);
+ }
+
+ public AlertDefinitionManagerRemote getAlertDefinitionManager() {
+ return getProxy(LookupUtil.getAlertDefinitionManager(), AlertDefinitionManagerRemote.class);
+ }
+
+ public AvailabilityManagerRemote getAvailabilityManager() {
+ return getProxy(LookupUtil.getAvailabilityManager(), AvailabilityManagerRemote.class);
+ }
+
+ public BundleManagerRemote getBundleManager() {
+ return getProxy(LookupUtil.getBundleManager(), BundleManagerRemote.class);
+ }
+
+ public CallTimeDataManagerRemote getCallTimeDataManager() {
+ return getProxy(LookupUtil.getCallTimeDataManager(), CallTimeDataManagerRemote.class);
+ }
+
+ public RepoManagerRemote getRepoManager() {
+ return getProxy(LookupUtil.getRepoManagerLocal(), RepoManagerRemote.class);
+ }
+
+ public ConfigurationManagerRemote getConfigurationManager() {
+ return getProxy(LookupUtil.getConfigurationManager(), ConfigurationManagerRemote.class);
+ }
+
+ public ContentManagerRemote getContentManager() {
+ return getProxy(LookupUtil.getContentManager(), ContentManagerRemote.class);
+ }
+
+ public DataAccessManagerRemote getDataAccessManager() {
+ return getProxy(LookupUtil.getDataAccessManager(), DataAccessManagerRemote.class);
+ }
+
+ public DiscoveryBossRemote getDiscoveryBoss() {
+ return getProxy(LookupUtil.getDiscoveryBoss(), DiscoveryBossRemote.class);
+ }
+
+ public EventManagerRemote getEventManager() {
+ return getProxy(LookupUtil.getEventManager(), EventManagerRemote.class);
+ }
+
+ public MeasurementBaselineManagerRemote getMeasurementBaselineManager() {
+ return getProxy(LookupUtil.getMeasurementBaselineManager(), MeasurementBaselineManagerRemote.class);
+ }
+
+ public MeasurementDataManagerRemote getMeasurementDataManager() {
+ return getProxy(LookupUtil.getMeasurementDataManager(), MeasurementDataManagerRemote.class);
+ }
+
+ public MeasurementDefinitionManagerRemote getMeasurementDefinitionManager() {
+ return getProxy(LookupUtil.getMeasurementDefinitionManager(), MeasurementDefinitionManagerRemote.class);
+ }
+
+ public MeasurementScheduleManagerRemote getMeasurementScheduleManager() {
+ return getProxy(LookupUtil.getMeasurementScheduleManager(), MeasurementScheduleManagerRemote.class);
+ }
+
+ public OperationManagerRemote getOperationManager() {
+ return getProxy(LookupUtil.getOperationManager(), OperationManagerRemote.class);
+ }
+
+ public ResourceManagerRemote getResourceManager() {
+ return getProxy(LookupUtil.getResourceManager(), ResourceManagerRemote.class);
+ }
+
+ public ResourceFactoryManagerRemote getResourceFactoryManager() {
+ return getProxy(LookupUtil.getResourceFactoryManager(), ResourceFactoryManagerRemote.class);
+ }
+
+ public ResourceGroupManagerRemote getResourceGroupManager() {
+ return getProxy(LookupUtil.getResourceGroupManager(), ResourceGroupManagerRemote.class);
+ }
+
+ public ResourceTypeManagerRemote getResourceTypeManager() {
+ return getProxy(LookupUtil.getResourceTypeManager(), ResourceTypeManagerRemote.class);
+ }
+
+ public RoleManagerRemote getRoleManager() {
+ return getProxy(LookupUtil.getRoleManager(), RoleManagerRemote.class);
+ }
+
+ public SavedSearchManagerRemote getSavedSearchManager() {
+ return getProxy(LookupUtil.getSavedSearchManager(), SavedSearchManagerRemote.class);
+ }
+
+ public SubjectManagerRemote getSubjectManager() {
+ return getProxy(LookupUtil.getSubjectManager(), SubjectManagerRemote.class);
+ }
+
+ public SupportManagerRemote getSupportManager() {
+ return getProxy(LookupUtil.getSupportManager(), SupportManagerRemote.class);
+ }
+
+ public SystemManagerRemote getSystemManager() {
+ return getProxy(LookupUtil.getSystemManager(), SystemManagerRemote.class);
+ }
+
+ public RemoteInstallManagerRemote getRemoteInstallManager() {
+ return getProxy(LookupUtil.getRemoteInstallManager(), RemoteInstallManagerRemote.class);
+ }
+
+ public TagManagerRemote getTagManager() {
+ return getProxy(LookupUtil.getTagManager(), TagManagerRemote.class);
+ }
+
+ public Map<String, Object> getManagers() {
+ if (managers == null) {
+
+ managers = new HashMap<String, Object>();
+
+ for (RhqManagers manager : RhqManagers.values()) {
+ try {
+ Method m = getClass().getMethod("get" + manager.name());
+ managers.put(manager.name(), m.invoke(this));
+ } catch (Throwable e) {
+ LOG.error("Failed to load manager " + manager + " due to missing class.", e);
+ }
+ }
+ }
+
+ return managers;
+ }
+
+ private <T> T getProxy(Object slsb, Class<T> iface) {
+ RhqManagers manager = RhqManagers.forInterface(iface);
+
+ return iface.cast(new LocalClientProxy(slsb, this, manager));
+ }
+}
diff --git a/modules/enterprise/server/client-api/src/main/java/org/rhq/enterprise/client/LocalClientProxy.java b/modules/enterprise/server/client-api/src/main/java/org/rhq/enterprise/client/LocalClientProxy.java
new file mode 100644
index 0000000..5f3ff90
--- /dev/null
+++ b/modules/enterprise/server/client-api/src/main/java/org/rhq/enterprise/client/LocalClientProxy.java
@@ -0,0 +1,67 @@
+/*
+ * 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 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.client;
+
+import java.lang.reflect.Method;
+import java.util.Arrays;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.rhq.bindings.client.AbstractRhqFacadeProxy;
+import org.rhq.bindings.client.RhqManagers;
+
+/**
+ * This is a proxy interface that simply calls given (de-simplified) method on a provided object.
+ * The use-case here is to invoke a method from a remote interface on the local SLSB.
+ *
+ * @author Lukas Krejci
+ */
+public class LocalClientProxy extends AbstractRhqFacadeProxy<LocalClient> {
+
+ private static final Log LOG = LogFactory.getLog(LocalClientProxy.class);
+
+ private Object localSLSB;
+
+ public LocalClientProxy(Object localSLSB, LocalClient client, RhqManagers manager) {
+ super(client, manager);
+ this.localSLSB = localSLSB;
+ }
+
+ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+ try {
+ return super.invoke(proxy, method, args);
+ } catch (Throwable t) {
+ LOG.warn("Proxied invocation of method [" + method + "] on [" + getManager() + "] failed.", t);
+ throw t;
+ }
+ }
+
+ protected Object doInvoke(Object proxy, Method originalMethod, java.lang.Class<?>[] argTypes, Object[] args) throws Throwable {
+ try {
+ Method realMethod = localSLSB.getClass().getMethod(originalMethod.getName(), argTypes);
+
+ return realMethod.invoke(localSLSB, args);
+ } catch (NoSuchMethodException e) {
+ throw new IllegalArgumentException("Method [" + originalMethod + "] does not have a desimplified counterpart with arguments " + Arrays.asList(argTypes) + ".", e);
+ }
+ };
+
+}
commit f099315a543671acf0098838b6ccded98b591091
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Sat Jan 15 00:33:54 2011 +0100
remove unused imports
diff --git a/modules/enterprise/binding/src/main/java/org/rhq/bindings/ScriptEngineFactory.java b/modules/enterprise/binding/src/main/java/org/rhq/bindings/ScriptEngineFactory.java
index 0fdf46a..7472953 100644
--- a/modules/enterprise/binding/src/main/java/org/rhq/bindings/ScriptEngineFactory.java
+++ b/modules/enterprise/binding/src/main/java/org/rhq/bindings/ScriptEngineFactory.java
@@ -37,9 +37,7 @@ import org.apache.commons.logging.LogFactory;
import org.rhq.bindings.engine.JsEngineInitializer;
import org.rhq.bindings.engine.ScriptEngineInitializer;
-import org.rhq.bindings.export.Exporter;
import org.rhq.bindings.util.PackageFinder;
-import org.rhq.core.domain.util.PageControl;
/**
* This is RHQ specific imitation of ScriptEngineFactory.
commit a825962db3c7bacf83f3c7f5bf11f33dc8b2ebb1
Merge: c240a5c... 4d895c6...
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Fri Jan 14 14:26:22 2011 +0100
Merge branch 'master' into cli-alert-notifs
commit c240a5cdbf59e37c1d8d29fbb31e4c6343afa5d3
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Thu Jan 13 15:10:45 2011 +0100
unbreak the interactive configuration editors in the resource proxies.
diff --git a/modules/enterprise/binding/src/main/java/org/rhq/bindings/client/ResourceClientProxy.java b/modules/enterprise/binding/src/main/java/org/rhq/bindings/client/ResourceClientProxy.java
index b67acf1..13517df 100644
--- a/modules/enterprise/binding/src/main/java/org/rhq/bindings/client/ResourceClientProxy.java
+++ b/modules/enterprise/binding/src/main/java/org/rhq/bindings/client/ResourceClientProxy.java
@@ -560,12 +560,12 @@ public class ResourceClientProxy {
public Object invoke(Object proxy, Method method, Method proceedMethod, Object[] args) throws Throwable {
if (proceedMethod != null) {
- Method realMethod = ResourceClientProxy.class.getMethod(method.getName(), method.getParameterTypes());
+ Method realMethod = getResourceClientProxyClass().getMethod(method.getName(), method.getParameterTypes());
return realMethod.invoke(resourceClientProxy, args);
} else {
try {
- Method localMethod = ClientProxyMethodHandler.class.getDeclaredMethod(method.getName(), method
+ Method localMethod = getClass().getDeclaredMethod(method.getName(), method
.getParameterTypes());
return localMethod.invoke(this, args);
} catch (NoSuchMethodException nsme) {
@@ -592,6 +592,10 @@ public class ResourceClientProxy {
throw new RuntimeException("Can't find custom method: " + method);
}
}
+
+ protected Class<? extends ResourceClientProxy> getResourceClientProxyClass() {
+ return ResourceClientProxy.class;
+ }
}
diff --git a/modules/enterprise/remoting/cli/src/main/java/org/rhq/enterprise/client/proxy/EditableResourceClientProxy.java b/modules/enterprise/remoting/cli/src/main/java/org/rhq/enterprise/client/proxy/EditableResourceClientProxy.java
index 367a750..10fa51d 100644
--- a/modules/enterprise/remoting/cli/src/main/java/org/rhq/enterprise/client/proxy/EditableResourceClientProxy.java
+++ b/modules/enterprise/remoting/cli/src/main/java/org/rhq/enterprise/client/proxy/EditableResourceClientProxy.java
@@ -23,7 +23,6 @@ import org.rhq.bindings.client.ResourceClientProxy;
import org.rhq.bindings.client.RhqFacade;
import org.rhq.core.domain.configuration.Configuration;
import org.rhq.enterprise.client.ClientMain;
-import org.rhq.enterprise.client.RemoteClient;
/**
* Extends the {@link ResourceClientProxy} and provides the interactive configuration editing features.
@@ -63,5 +62,10 @@ public class EditableResourceClientProxy extends ResourceClientProxy {
updateResourceConfiguration(config);
}
}
+
+ @Override
+ protected Class<? extends ResourceClientProxy> getResourceClientProxyClass() {
+ return EditableResourceClientProxy.class;
+ }
}
}
commit 49cf35723fa3a6055d0fb3d9b89751c3f3ec41a8
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Thu Jan 13 14:33:26 2011 +0100
bind the controller's methods in the global scope of CLI
diff --git a/modules/enterprise/remoting/cli/src/main/java/org/rhq/enterprise/client/commands/ScriptCommand.java b/modules/enterprise/remoting/cli/src/main/java/org/rhq/enterprise/client/commands/ScriptCommand.java
index 8f64679..dfc2b4c 100644
--- a/modules/enterprise/remoting/cli/src/main/java/org/rhq/enterprise/client/commands/ScriptCommand.java
+++ b/modules/enterprise/remoting/cli/src/main/java/org/rhq/enterprise/client/commands/ScriptCommand.java
@@ -184,7 +184,7 @@ public class ScriptCommand implements ClientCommand {
ScriptEngineFactory.injectStandardBindings(jsEngine, bindings);
ScriptEngineFactory.bindIndirectionMethods(jsEngine, "configurationEditor", bindings.get("configurationEditor"));
- ScriptEngineFactory.bindIndirectionMethods(jsEngine, "configurationEditor", bindings.get("configurationEditor"));
+ ScriptEngineFactory.bindIndirectionMethods(jsEngine, "rhq", bindings.get("rhq"));
}
private void executeUtilScripts() {
commit 06c19e276a98d7c5f56284494b2fe85001abe382
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Tue Jan 11 14:35:23 2011 +0100
adding the test-jar dependency on core.domain to make the tests work again.
diff --git a/modules/enterprise/binding/pom.xml b/modules/enterprise/binding/pom.xml
index 65aec88..661af79 100644
--- a/modules/enterprise/binding/pom.xml
+++ b/modules/enterprise/binding/pom.xml
@@ -31,122 +31,130 @@
</exclusions>
</dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>rhq-enterprise-server</artifactId>
- <version>${project.version}</version>
- <type>ejb-client</type>
- <exclusions>
- <exclusion>
- <groupId>ant</groupId>
- <artifactId>ant</artifactId>
- </exclusion>
- <exclusion>
- <groupId>commons-beanutils</groupId>
- <artifactId>commons-beanutils</artifactId>
- </exclusion>
- <exclusion>
- <groupId>commons-collections</groupId>
- <artifactId>commons-collections</artifactId>
- </exclusion>
- <exclusion>
- <groupId>commons-httpclient</groupId>
- <artifactId>commons-httpclient</artifactId>
- </exclusion>
- <exclusion>
- <groupId>commons-lang</groupId>
- <artifactId>commons-lang</artifactId>
- </exclusion>
- <exclusion>
- <groupId>commons-validator</groupId>
- <artifactId>commons-validator</artifactId>
- </exclusion>
- <exclusion>
- <groupId>dom4j</groupId>
- <artifactId>dom4j</artifactId>
- </exclusion>
- <exclusion>
- <groupId>gnu-getopt</groupId>
- <artifactId>getopt</artifactId>
- </exclusion>
- <exclusion>
- <groupId>jboss</groupId>
- <artifactId>jboss-cache</artifactId>
- </exclusion>
- <exclusion>
- <groupId>jboss</groupId>
- <artifactId>jbpm</artifactId>
- </exclusion>
- <exclusion>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- </exclusion>
- <exclusion>
- <groupId>org.rhq</groupId>
- <artifactId>rhq-core-client-api</artifactId>
- </exclusion>
- <exclusion>
- <groupId>org.rhq</groupId>
- <artifactId>rhq-core-dbutils</artifactId>
- </exclusion>
- <exclusion>
- <groupId>org.rhq</groupId>
- <artifactId>rhq-enterprise-server-xml-schemas</artifactId>
- </exclusion>
- <exclusion>
- <groupId>org.rhq</groupId>
- <artifactId>safe-invoker</artifactId>
- </exclusion>
- <exclusion>
- <groupId>org.rhq</groupId>
- <artifactId>test-utils</artifactId>
- </exclusion>
- <exclusion>
- <groupId>org.snmp4j</groupId>
- <artifactId>snmp4j</artifactId>
- </exclusion>
- <exclusion>
- <groupId>oswego-concurrent</groupId>
- <artifactId>concurrent</artifactId>
- </exclusion>
- <exclusion>
- <groupId>postgresql</groupId>
- <artifactId>postgresql</artifactId>
- </exclusion>
- <exclusion>
- <groupId>rss4j</groupId>
- <artifactId>rss4j</artifactId>
- </exclusion>
- <exclusion>
- <groupId>jboss</groupId>
- <artifactId>jboss-common</artifactId>
- </exclusion>
- <exclusion>
- <groupId>jboss</groupId>
- <artifactId>jboss-jmx</artifactId>
- </exclusion>
- <exclusion>
- <groupId>jboss</groupId>
- <artifactId>jboss-remoting</artifactId>
- </exclusion>
- <exclusion>
- <groupId>jboss</groupId>
- <artifactId>jboss-serialization</artifactId>
- </exclusion>
- <exclusion>
- <groupId>org.antlr</groupId>
- <artifactId>antlr</artifactId>
- </exclusion>
- <exclusion>
- <groupId>com.jcraft</groupId>
- <artifactId>jsch</artifactId>
- </exclusion>
- <exclusion>
- <groupId>org.rhq</groupId>
- <artifactId>rhq-enterprise-comm</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
+ <dependency>
+ <groupId>${groupId}</groupId>
+ <artifactId>rhq-core-domain</artifactId>
+ <version>${project.version}</version>
+ <type>test-jar</type>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>rhq-enterprise-server</artifactId>
+ <version>${project.version}</version>
+ <type>ejb-client</type>
+ <exclusions>
+ <exclusion>
+ <groupId>ant</groupId>
+ <artifactId>ant</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>commons-beanutils</groupId>
+ <artifactId>commons-beanutils</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>commons-collections</groupId>
+ <artifactId>commons-collections</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>commons-httpclient</groupId>
+ <artifactId>commons-httpclient</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>commons-lang</groupId>
+ <artifactId>commons-lang</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>commons-validator</groupId>
+ <artifactId>commons-validator</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>dom4j</groupId>
+ <artifactId>dom4j</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>gnu-getopt</groupId>
+ <artifactId>getopt</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>jboss</groupId>
+ <artifactId>jboss-cache</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>jboss</groupId>
+ <artifactId>jbpm</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-core-client-api</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-core-dbutils</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-enterprise-server-xml-schemas</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.rhq</groupId>
+ <artifactId>safe-invoker</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.rhq</groupId>
+ <artifactId>test-utils</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.snmp4j</groupId>
+ <artifactId>snmp4j</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>oswego-concurrent</groupId>
+ <artifactId>concurrent</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>postgresql</groupId>
+ <artifactId>postgresql</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>rss4j</groupId>
+ <artifactId>rss4j</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>jboss</groupId>
+ <artifactId>jboss-common</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>jboss</groupId>
+ <artifactId>jboss-jmx</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>jboss</groupId>
+ <artifactId>jboss-remoting</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>jboss</groupId>
+ <artifactId>jboss-serialization</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.antlr</groupId>
+ <artifactId>antlr</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>com.jcraft</groupId>
+ <artifactId>jsch</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-enterprise-comm</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
<dependency>
<groupId>commons-lang</groupId>
commit 3d4f4eda2afd62d322671ae629bfbda8635f0ce3
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Tue Jan 11 13:50:53 2011 +0100
don't blow up on the pretty printing of empty property lists
diff --git a/modules/enterprise/binding/src/main/java/org/rhq/bindings/output/TabularWriter.java b/modules/enterprise/binding/src/main/java/org/rhq/bindings/output/TabularWriter.java
index 5e24f53..382ce8c 100644
--- a/modules/enterprise/binding/src/main/java/org/rhq/bindings/output/TabularWriter.java
+++ b/modules/enterprise/binding/src/main/java/org/rhq/bindings/output/TabularWriter.java
@@ -446,7 +446,7 @@ public class TabularWriter {
public void print(PropertyList p, int depth) {
out.println(indent(depth) + p.getName() + " [" + p.getList().size() + "] {");
- if (p.getList().get(0) instanceof PropertyMap) {
+ if (p.getList().size() > 0 && p.getList().get(0) instanceof PropertyMap) {
consistentMaps(p.getList());
} else {
commit 4ab19328ee3e10690a7499140ff316b7bff337e4
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Tue Jan 11 13:50:03 2011 +0100
The scripting engine can now be initialized with the standard bindings in a reusable way without being tied to remoting and CLI "user interface".
diff --git a/modules/enterprise/binding/pom.xml b/modules/enterprise/binding/pom.xml
index 8523c1d..65aec88 100644
--- a/modules/enterprise/binding/pom.xml
+++ b/modules/enterprise/binding/pom.xml
@@ -1,59 +1,192 @@
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <artifactId>rhq-enterprise-parent</artifactId>
- <groupId>org.rhq</groupId>
- <version>4.0.0-SNAPSHOT</version>
- </parent>
- <groupId>org.rhq</groupId>
- <artifactId>rhq-script-bindings</artifactId>
- <version>4.0.0-SNAPSHOT</version>
- <name>RHQ Script Bindings</name>
- <description>Abstraction of different facilities and default configurations for script bindings</description>
-
- <properties>
- <persistence-api.version>1.0</persistence-api.version>
- <opencsv.version>1.8</opencsv.version>
- </properties>
-
- <dependencies>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>rhq-core-domain</artifactId>
- <version>${project.version}</version>
- <exclusions>
- <exclusion>
- <groupId>hibernate</groupId>
- <artifactId>hibernate3</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
-
- <dependency>
- <groupId>commons-lang</groupId>
- <artifactId>commons-lang</artifactId>
- <version>2.4</version>
- <scope>test</scope>
- </dependency>
-
- <dependency>
- <groupId>javax.persistence</groupId>
- <artifactId>persistence-api</artifactId>
- <version>${persistence-api.version}</version>
- <scope>test</scope>
- </dependency>
-
- <dependency>
- <groupId>org.testng</groupId>
- <artifactId>testng</artifactId>
- <version>${testng.version}</version>
- <scope>test</scope>
- </dependency>
-
- <dependency>
- <groupId>net.sf.opencsv</groupId>
- <artifactId>opencsv</artifactId>
- <version>${opencsv.version}</version>
- </dependency>
- </dependencies>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <artifactId>rhq-enterprise-parent</artifactId>
+ <groupId>org.rhq</groupId>
+ <version>4.0.0-SNAPSHOT</version>
+ </parent>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-script-bindings</artifactId>
+ <version>4.0.0-SNAPSHOT</version>
+ <name>RHQ Script Bindings</name>
+ <description>Abstraction of different facilities and default configurations for script bindings</description>
+
+ <properties>
+ <persistence-api.version>1.0</persistence-api.version>
+ <opencsv.version>1.8</opencsv.version>
+ </properties>
+
+ <dependencies>
+
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>rhq-core-domain</artifactId>
+ <version>${project.version}</version>
+ <exclusions>
+ <exclusion>
+ <groupId>hibernate</groupId>
+ <artifactId>hibernate3</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>rhq-enterprise-server</artifactId>
+ <version>${project.version}</version>
+ <type>ejb-client</type>
+ <exclusions>
+ <exclusion>
+ <groupId>ant</groupId>
+ <artifactId>ant</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>commons-beanutils</groupId>
+ <artifactId>commons-beanutils</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>commons-collections</groupId>
+ <artifactId>commons-collections</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>commons-httpclient</groupId>
+ <artifactId>commons-httpclient</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>commons-lang</groupId>
+ <artifactId>commons-lang</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>commons-validator</groupId>
+ <artifactId>commons-validator</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>dom4j</groupId>
+ <artifactId>dom4j</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>gnu-getopt</groupId>
+ <artifactId>getopt</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>jboss</groupId>
+ <artifactId>jboss-cache</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>jboss</groupId>
+ <artifactId>jbpm</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-core-client-api</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-core-dbutils</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-enterprise-server-xml-schemas</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.rhq</groupId>
+ <artifactId>safe-invoker</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.rhq</groupId>
+ <artifactId>test-utils</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.snmp4j</groupId>
+ <artifactId>snmp4j</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>oswego-concurrent</groupId>
+ <artifactId>concurrent</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>postgresql</groupId>
+ <artifactId>postgresql</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>rss4j</groupId>
+ <artifactId>rss4j</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>jboss</groupId>
+ <artifactId>jboss-common</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>jboss</groupId>
+ <artifactId>jboss-jmx</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>jboss</groupId>
+ <artifactId>jboss-remoting</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>jboss</groupId>
+ <artifactId>jboss-serialization</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.antlr</groupId>
+ <artifactId>antlr</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>com.jcraft</groupId>
+ <artifactId>jsch</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-enterprise-comm</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+
+ <dependency>
+ <groupId>commons-lang</groupId>
+ <artifactId>commons-lang</artifactId>
+ <version>2.4</version>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>javax.persistence</groupId>
+ <artifactId>persistence-api</artifactId>
+ <version>${persistence-api.version}</version>
+ <scope>provided</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>hibernate-annotations</groupId>
+ <artifactId>hibernate-annotations</artifactId>
+ <!-- NOTE: The version is defined in the root POM's dependencyManagement
+ section. -->
+ <scope>provided</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.testng</groupId>
+ <artifactId>testng</artifactId>
+ <version>${testng.version}</version>
+ <scope>compile</scope> <!-- yes, this is meant to be in compile, because we're providing assertions
+ to the scripts -->
+ </dependency>
+
+ <dependency>
+ <groupId>net.sf.opencsv</groupId>
+ <artifactId>opencsv</artifactId>
+ <version>${opencsv.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>jboss</groupId>
+ <artifactId>javassist</artifactId>
+ </dependency>
+ </dependencies>
</project>
\ No newline at end of file
diff --git a/modules/enterprise/binding/src/main/java/org/rhq/bindings/ScriptEngineFactory.java b/modules/enterprise/binding/src/main/java/org/rhq/bindings/ScriptEngineFactory.java
index 4179dbe..0fdf46a 100644
--- a/modules/enterprise/binding/src/main/java/org/rhq/bindings/ScriptEngineFactory.java
+++ b/modules/enterprise/binding/src/main/java/org/rhq/bindings/ScriptEngineFactory.java
@@ -19,13 +19,22 @@
package org.rhq.bindings;
+import java.beans.BeanInfo;
+import java.beans.IntrospectionException;
+import java.beans.Introspector;
+import java.beans.MethodDescriptor;
import java.io.IOException;
+import java.lang.reflect.Method;
+import java.util.Map;
import javax.script.Bindings;
import javax.script.ScriptContext;
import javax.script.ScriptEngine;
import javax.script.ScriptException;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
import org.rhq.bindings.engine.JsEngineInitializer;
import org.rhq.bindings.engine.ScriptEngineInitializer;
import org.rhq.bindings.export.Exporter;
@@ -46,7 +55,8 @@ import org.rhq.core.domain.util.PageControl;
* @author Lukas Krejci
*/
public class ScriptEngineFactory {
-
+ private static final Log LOG = LogFactory.getLog(ScriptEngineFactory.class);
+
private static final ScriptEngineInitializer[] KNOWN_ENGINES = {new JsEngineInitializer()};
private ScriptEngineFactory() {
@@ -63,7 +73,7 @@ public class ScriptEngineFactory {
* @throws ScriptException on error during initialization of the script environment
* @throws IOException if the package finder fails to find the packages
*/
- public static ScriptEngine getScriptEngine(String language, PackageFinder packageFinder) throws ScriptException, IOException {
+ public static ScriptEngine getScriptEngine(String language, PackageFinder packageFinder, StandardBindings bindings) throws ScriptException, IOException {
ScriptEngineInitializer initializer = getInitializer(language);
if (initializer == null) {
@@ -72,25 +82,50 @@ public class ScriptEngineFactory {
ScriptEngine engine = initializer.instantiate(packageFinder.findPackages("org.rhq.core.domain"));
- injectStandardBindings(engine);
+ injectStandardBindings(engine, bindings);
return engine;
}
- public static void injectStandardBindings(ScriptEngine engine) {
- Bindings bindings = engine.getBindings(ScriptContext.ENGINE_SCOPE);
- PageControl pc = new PageControl();
- pc.setPageNumber(-1);
- bindings.put("unlimitedPC", pc);
- bindings.put("pageControl", PageControl.getUnlimitedInstance());
- bindings.put("exporter", new Exporter());
+ public static void injectStandardBindings(ScriptEngine engine, StandardBindings bindings) {
+ bindings.preInject(engine);
+
+ Bindings engineBindings = engine.getBindings(ScriptContext.ENGINE_SCOPE);
+
+ for(Map.Entry<String, Object> entry : bindings.entrySet()) {
+ engineBindings.put(entry.getKey(), entry.getValue());
+ }
+
+ engine.setBindings(engineBindings, ScriptContext.ENGINE_SCOPE);
- engine.setBindings(bindings, ScriptContext.ENGINE_SCOPE);
+ bindings.postInject(engine);
}
- private static ScriptEngineInitializer getInitializer(String language) {
+ public static void bindIndirectionMethods(ScriptEngine scriptEngine, String bindingName, Object object) {
+ ScriptEngineInitializer initializer = getInitializer(scriptEngine.getFactory().getLanguageName());
+ try {
+ BeanInfo beanInfo = Introspector.getBeanInfo(object.getClass(), Object.class);
+ MethodDescriptor[] methodDescriptors = beanInfo.getMethodDescriptors();
+
+ for (MethodDescriptor methodDescriptor : methodDescriptors) {
+ Method method = methodDescriptor.getMethod();
+ try {
+ String methodDef = initializer.generateIndirectionMethod(bindingName, method);
+ scriptEngine.eval(methodDef);
+ } catch (ScriptException e) {
+ LOG.warn("Unable to bind global function " + method.getName(), e);
+ }
+ }
+ } catch (IntrospectionException e) {
+ // TODO Should we altogether remove the object from the script engine bindings?
+ LOG.warn("Could not bind " + object.getClass().getName() + " into script engine.");
+ }
+ }
+
+
+ public static ScriptEngineInitializer getInitializer(String language) {
for (ScriptEngineInitializer i : KNOWN_ENGINES) {
- if (i.getEngineName().equals(language)) {
+ if (i.implementsLanguage(language)) {
return i;
}
}
diff --git a/modules/enterprise/binding/src/main/java/org/rhq/bindings/StandardBindings.java b/modules/enterprise/binding/src/main/java/org/rhq/bindings/StandardBindings.java
new file mode 100644
index 0000000..2977023
--- /dev/null
+++ b/modules/enterprise/binding/src/main/java/org/rhq/bindings/StandardBindings.java
@@ -0,0 +1,178 @@
+/*
+ * 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 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.bindings;
+
+import java.io.PrintWriter;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.script.ScriptContext;
+import javax.script.ScriptEngine;
+
+import org.rhq.bindings.client.ResourceClientFactory;
+import org.rhq.bindings.client.RhqFacade;
+import org.rhq.bindings.export.Exporter;
+import org.rhq.bindings.output.TabularWriter;
+import org.rhq.bindings.util.ScriptAssert;
+import org.rhq.bindings.util.ScriptUtil;
+import org.rhq.core.domain.auth.Subject;
+import org.rhq.core.domain.util.PageControl;
+
+/**
+ * This class encapsulates the standard set of data inserted in the {@link ScriptContext#ENGINE_SCOPE} of the
+ * script engines.
+ * <p>
+ * Upon instantiation this class has all the properties initialized with the default values so that a common base
+ * is available for all the users of this class. The user is however able to later modify these defaults to provide
+ * use-case specific overrides (for example the CLI might want to supply impls that hook into the console to provide
+ * interactivity with user in some workflows, which, generically, is not possible in a common case).
+ *
+ * @author Lukas Krejci
+ */
+public class StandardBindings extends HashMap<String, Object> {
+
+ private static final long serialVersionUID = 1L;
+
+ public static final String UNLIMITED_PC = "unlimitedPC";
+ public static final String PAGE_CONTROL = "pageControl";
+ public static final String EXPORTER = "exporter";
+ public static final String SUBJECT = "subject";
+ public static final String PRETTY = "pretty";
+ public static final String SCRIPT_UTIL = "scriptUtil";
+ public static final String PROXY_FACTORY = "ProxyFactory";
+ public static final String ASSERT = "Assert";
+
+ private Map<String, Object> managers;
+
+ private static class CastingEntry<T> implements Map.Entry<String, T> {
+
+ private Map.Entry<String, Object> inner;
+ private Class<T> clazz;
+
+ public CastingEntry(Map.Entry<String, Object> inner, Class<T> clazz) {
+ this.inner = inner;
+ this.clazz = clazz;
+ }
+
+ public String getKey() {
+ return inner.getKey();
+ }
+
+ public T getValue() {
+ return clazz.cast(inner.getValue());
+ }
+
+ public T setValue(T value) {
+ return clazz.cast(inner.setValue(value));
+ }
+
+ }
+
+ public StandardBindings(PrintWriter output, RhqFacade rhqFacade) {
+ PageControl pc = new PageControl();
+ pc.setPageNumber(-1);
+
+ managers = rhqFacade.getManagers();
+
+ put(UNLIMITED_PC, pc);
+ put(PAGE_CONTROL, PageControl.getUnlimitedInstance());
+ put(EXPORTER, new Exporter());
+ put(SUBJECT, rhqFacade.getSubject());
+ put(PRETTY, new TabularWriter(output));
+ put(SCRIPT_UTIL, new ScriptUtil(rhqFacade));
+ put(PROXY_FACTORY, new ResourceClientFactory(rhqFacade, output));
+ put(ASSERT, new ScriptAssert());
+
+ putAll(managers);
+
+ //I don't think these should belong in the standard bindings
+ //because all the controller does is "login/logout" as methods
+ //of the "rhq" object. ConfigurationEditor is interactive and
+ //thus unusable outside of console bound CLI.
+
+ //(the below were originally defined in the ScriptCommand)
+ //bindObjectAndGlobalFuctions(new Controller(client), "rhq");
+ //bindObjectAndGlobalFuctions(new ConfigurationEditor(client), "configurationEditor");
+ }
+
+ public void preInject(ScriptEngine scriptEngine) {
+ ((ScriptUtil) get(SCRIPT_UTIL)).init(scriptEngine);
+ ((ScriptAssert) get(ASSERT)).init(scriptEngine);
+ }
+
+ public void postInject(ScriptEngine scriptEngine) {
+ ScriptEngineFactory.bindIndirectionMethods(scriptEngine, SCRIPT_UTIL, get(SCRIPT_UTIL));
+ ScriptEngineFactory.bindIndirectionMethods(scriptEngine, ASSERT, get(ASSERT));
+ }
+
+ public Map.Entry<String, PageControl> getUnlimitedPC() {
+ return castEntry(UNLIMITED_PC, PageControl.class);
+ }
+
+ public Map.Entry<String, PageControl> getPageControl() {
+ return castEntry(PAGE_CONTROL, PageControl.class);
+ }
+
+ public Map.Entry<String, Exporter> getExporter() {
+ return castEntry(EXPORTER, Exporter.class);
+ }
+
+ public Map.Entry<String, Subject> getSubject() {
+ return castEntry(SUBJECT, Subject.class);
+ }
+
+ public Map.Entry<String, TabularWriter> getPretty() {
+ return castEntry(PRETTY, TabularWriter.class);
+ }
+
+ public Map.Entry<String, ScriptUtil> getScriptUtil() {
+ return castEntry(SCRIPT_UTIL, ScriptUtil.class);
+ }
+
+ public Map.Entry<String, ResourceClientFactory> getProxyFactory() {
+ return castEntry(PROXY_FACTORY, ResourceClientFactory.class);
+ }
+
+ public Map<String, Object> getManagers() {
+ //XXX ideally this should be a projection into our map
+ return managers;
+ }
+
+ private Map.Entry<String, Object> getEntry(String key) {
+ for (Map.Entry<String, Object> entry : entrySet()) {
+ if (key == null && entry.getKey() == null) {
+ return entry;
+ } else if (key.equals(entry.getKey())) {
+ return entry;
+ }
+ }
+
+ return null;
+ }
+
+ private <T> Map.Entry<String, T> castEntry(String key, Class<T> clazz) {
+ Map.Entry<String, Object> entry = getEntry(key);
+ if (entry == null) {
+ return null;
+ }
+
+ return new CastingEntry<T>(entry, clazz);
+ }
+}
diff --git a/modules/enterprise/binding/src/main/java/org/rhq/bindings/client/ResourceClientFactory.java b/modules/enterprise/binding/src/main/java/org/rhq/bindings/client/ResourceClientFactory.java
new file mode 100644
index 0000000..2112073
--- /dev/null
+++ b/modules/enterprise/binding/src/main/java/org/rhq/bindings/client/ResourceClientFactory.java
@@ -0,0 +1,170 @@
+package org.rhq.bindings.client;
+
+import java.io.PrintWriter;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+
+import javassist.ClassPool;
+import javassist.CtNewMethod;
+import javassist.bytecode.ParameterAnnotationsAttribute;
+import javassist.util.proxy.MethodHandler;
+
+import org.rhq.bindings.util.ConfigurationClassBuilder;
+import org.rhq.core.domain.resource.ResourceCreationDataType;
+
+/**
+ *
+ * @author Greg Hinkle
+ * @author Lukas Krejci
+ */
+public class ResourceClientFactory {
+
+ private org.rhq.bindings.client.RhqFacade rhqFacade;
+ private PrintWriter outputWriter;
+
+ public ResourceClientFactory(org.rhq.bindings.client.RhqFacade remoteClient, PrintWriter outputWriter) {
+ this.rhqFacade = remoteClient;
+ this.outputWriter = outputWriter;
+ }
+
+ private static java.util.concurrent.atomic.AtomicInteger classIndex = new java.util.concurrent.atomic.AtomicInteger();
+
+ public org.rhq.bindings.client.RhqFacade getRemoteClient() {
+ return rhqFacade;
+ }
+
+ public PrintWriter getOutputWriter() {
+ return outputWriter;
+ }
+
+ public org.rhq.bindings.client.ResourceClientProxy getResource(int resourceId) {
+
+ org.rhq.bindings.client.ResourceClientProxy proxy = new org.rhq.bindings.client.ResourceClientProxy(this, resourceId);
+ java.lang.Class<?> customInterface = null;
+ try {
+ // define the dynamic class
+ javassist.ClassPool pool = ClassPool.getDefault();
+ javassist.CtClass customClass = pool.makeInterface(org.rhq.bindings.client.ResourceClientProxy.class.getName() + "__Custom__"
+ + classIndex.getAndIncrement());
+
+ for (java.lang.String key : proxy.allProperties.keySet()) {
+ java.lang.Object prop = proxy.allProperties.get(key);
+
+ if (prop instanceof org.rhq.bindings.client.ResourceClientProxy.Measurement) {
+ org.rhq.bindings.client.ResourceClientProxy.Measurement m = (org.rhq.bindings.client.ResourceClientProxy.Measurement) prop;
+ java.lang.String name = org.rhq.bindings.client.ResourceClientProxy.getterName(key);
+
+ try {
+ org.rhq.bindings.client.ResourceClientProxy.class.getMethod(name);
+ } catch (java.lang.NoSuchMethodException nsme) {
+ javassist.CtMethod method = CtNewMethod.abstractMethod(pool.get(org.rhq.bindings.client.ResourceClientProxy.Measurement.class.getName()),
+ org.rhq.bindings.client.ResourceClientProxy.getterName(key), new javassist.CtClass[0], new javassist.CtClass[0], customClass);
+ customClass.addMethod(method);
+ }
+ } else if (prop instanceof org.rhq.bindings.client.ResourceClientProxy.Operation) {
+ org.rhq.bindings.client.ResourceClientProxy.Operation o = (org.rhq.bindings.client.ResourceClientProxy.Operation) prop;
+
+ java.util.LinkedHashMap<java.lang.String, javassist.CtClass> types = ConfigurationClassBuilder.translateParameters(o
+ .getDefinition().getParametersConfigurationDefinition());
+
+ javassist.CtClass[] params = new javassist.CtClass[types.size()];
+ int x = 0;
+ for (java.lang.String param : types.keySet()) {
+ params[x++] = types.get(param);
+ }
+
+ javassist.CtMethod method = CtNewMethod.abstractMethod(ConfigurationClassBuilder.translateConfiguration(o
+ .getDefinition().getResultsConfigurationDefinition()), org.rhq.bindings.client.ResourceClientProxy.simpleName(key), params,
+ new javassist.CtClass[0], customClass);
+
+ // Setup @WebParam annotations so the signatures have the config prop names
+ javassist.bytecode.annotation.Annotation[][] newAnnotations = new javassist.bytecode.annotation.Annotation[params.length][1];
+ int i = 0;
+ for (java.lang.String paramName : types.keySet()) {
+ newAnnotations[i] = new javassist.bytecode.annotation.Annotation[1];
+
+ newAnnotations[i][0] = new javassist.bytecode.annotation.Annotation(javax.jws.WebParam.class.getName(), method.getMethodInfo()
+ .getConstPool());
+ newAnnotations[i][0].addMemberValue("name", new javassist.bytecode.annotation.StringMemberValue(paramName, method
+ .getMethodInfo().getConstPool()));
+ i++;
+ }
+
+ javassist.bytecode.ParameterAnnotationsAttribute newAnnotationsAttribute = new javassist.bytecode.ParameterAnnotationsAttribute(
+ method.getMethodInfo().getConstPool(), ParameterAnnotationsAttribute.visibleTag);
+ newAnnotationsAttribute.setAnnotations(newAnnotations);
+ method.getMethodInfo().addAttribute(newAnnotationsAttribute);
+
+ customClass.addMethod(method);
+ }
+ }
+
+ customInterface = customClass.toClass();
+ } catch (javassist.NotFoundException e) {
+ e.printStackTrace();
+ } catch (javassist.CannotCompileException e) {
+ e.printStackTrace();
+ } catch (java.lang.Exception e) {
+ e.printStackTrace();
+ }
+
+ if (customInterface != null) {
+
+ java.util.List<java.lang.Class<?>> interfaces = new java.util.ArrayList<java.lang.Class<?>>();
+ interfaces.add(customInterface);
+ if (proxy.resourceConfigurationDefinition != null) {
+ interfaces.add(getResourceConfigurableInterface());
+ }
+ if (proxy.pluginConfigurationDefinition != null) {
+ interfaces.add(getPluginConfigurableInterface());
+ }
+
+ if (proxy.getResourceType().getCreationDataType() == ResourceCreationDataType.CONTENT) {
+ interfaces.add(getContentBackedInterface());
+ }
+
+ interfaces.addAll(getAdditionalInterfaces(proxy));
+
+ javassist.util.proxy.ProxyFactory proxyFactory = new javassist.util.proxy.ProxyFactory();
+ proxyFactory.setInterfaces(interfaces.toArray(new java.lang.Class[interfaces.size()]));
+ proxyFactory.setSuperclass(org.rhq.bindings.client.ResourceClientProxy.class);
+ org.rhq.bindings.client.ResourceClientProxy proxied = null;
+ try {
+ proxied = (org.rhq.bindings.client.ResourceClientProxy) proxyFactory.create(new java.lang.Class[]{}, new java.lang.Object[]{},
+ instantiateMethodHandler(proxy, interfaces, rhqFacade));
+ } catch (java.lang.InstantiationException e) {
+ e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
+ } catch (java.lang.IllegalAccessException e) {
+ e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
+ } catch (java.lang.NoSuchMethodException e) {
+ e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
+ } catch (java.lang.reflect.InvocationTargetException e) {
+ e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
+ }
+ return proxied;
+ }
+ return proxy;
+
+ }
+
+ protected Class<?> getResourceConfigurableInterface() {
+ return org.rhq.bindings.client.ResourceClientProxy.ResourceConfigurable.class;
+ }
+
+ protected Class<?> getPluginConfigurableInterface() {
+ return org.rhq.bindings.client.ResourceClientProxy.PluginConfigurable.class;
+ }
+
+ protected Class<?> getContentBackedInterface() {
+ return org.rhq.bindings.client.ResourceClientProxy.ContentBackedResource.class;
+ }
+
+ protected Set<Class<?>> getAdditionalInterfaces(ResourceClientProxy proxy) {
+ return Collections.emptySet();
+ }
+
+ protected MethodHandler instantiateMethodHandler(ResourceClientProxy proxy, List<Class<?>> interfaces, org.rhq.bindings.client.RhqFacade remoteClient) {
+ return new org.rhq.bindings.client.ResourceClientProxy.ClientProxyMethodHandler(proxy, remoteClient);
+ }
+}
diff --git a/modules/enterprise/binding/src/main/java/org/rhq/bindings/client/ResourceClientProxy.java b/modules/enterprise/binding/src/main/java/org/rhq/bindings/client/ResourceClientProxy.java
new file mode 100644
index 0000000..b67acf1
--- /dev/null
+++ b/modules/enterprise/binding/src/main/java/org/rhq/bindings/client/ResourceClientProxy.java
@@ -0,0 +1,637 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2008 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.bindings.client;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javassist.util.proxy.MethodHandler;
+
+import org.rhq.bindings.util.ConfigurationClassBuilder;
+import org.rhq.bindings.util.LazyLoadScenario;
+import org.rhq.bindings.util.ScriptUtil;
+import org.rhq.bindings.util.ShortOutput;
+import org.rhq.core.domain.configuration.Configuration;
+import org.rhq.core.domain.configuration.PluginConfigurationUpdate;
+import org.rhq.core.domain.configuration.ResourceConfigurationUpdate;
+import org.rhq.core.domain.configuration.definition.ConfigurationDefinition;
+import org.rhq.core.domain.content.InstalledPackage;
+import org.rhq.core.domain.content.PackageType;
+import org.rhq.core.domain.content.PackageVersion;
+import org.rhq.core.domain.criteria.MeasurementDefinitionCriteria;
+import org.rhq.core.domain.criteria.OperationDefinitionCriteria;
+import org.rhq.core.domain.criteria.PackageVersionCriteria;
+import org.rhq.core.domain.criteria.ResourceCriteria;
+import org.rhq.core.domain.criteria.ResourceOperationHistoryCriteria;
+import org.rhq.core.domain.measurement.DataType;
+import org.rhq.core.domain.measurement.MeasurementCategory;
+import org.rhq.core.domain.measurement.MeasurementData;
+import org.rhq.core.domain.measurement.MeasurementDefinition;
+import org.rhq.core.domain.measurement.MeasurementUnits;
+import org.rhq.core.domain.operation.OperationDefinition;
+import org.rhq.core.domain.operation.OperationRequestStatus;
+import org.rhq.core.domain.operation.ResourceOperationHistory;
+import org.rhq.core.domain.operation.bean.ResourceOperationSchedule;
+import org.rhq.core.domain.resource.Resource;
+import org.rhq.core.domain.resource.ResourceType;
+import org.rhq.core.domain.util.PageList;
+import org.rhq.core.domain.util.PageOrdering;
+import org.rhq.core.domain.util.Summary;
+import org.rhq.core.server.MeasurementConverter;
+import org.rhq.enterprise.server.content.ContentManagerRemote;
+import org.rhq.enterprise.server.resource.ResourceTypeNotFoundException;
+
+/**
+ * Implements a local object that exposes resource related data as
+ * if it were local.
+ *
+ * @author Greg Hinkle
+ * @author Lukas Krejci
+ */
+public class ResourceClientProxy {
+
+ private ResourceClientFactory proxyFactory;
+ private RhqFacade remoteClient;
+ private int resourceId;
+ private Resource resource;
+
+ Map<String, Object> allProperties = new HashMap<String, Object>();
+
+ // Metadata
+ private List<MeasurementDefinition> measurementDefinitions;
+ private Map<String, Measurement> measurementMap = new HashMap<String, Measurement>();
+
+ private List<OperationDefinition> operationDefinitions;
+ private Map<String, Operation> operationMap = new HashMap<String, Operation>();
+
+ private Map<String, ContentType> contentTypes = new HashMap<String, ContentType>();
+
+ private List<ResourceClientProxy> children;
+ ConfigurationDefinition resourceConfigurationDefinition;
+ ConfigurationDefinition pluginConfigurationDefinition;
+
+ public ResourceClientProxy() {
+ }
+
+ public ResourceClientProxy(ResourceClientProxy parentProxy) {
+ this.proxyFactory = parentProxy.proxyFactory;
+ this.remoteClient = parentProxy.remoteClient;
+ this.resourceId = parentProxy.resourceId;
+ this.resource = parentProxy.resource;
+ this.allProperties = parentProxy.allProperties;
+ this.measurementDefinitions = parentProxy.measurementDefinitions;
+ this.measurementMap = parentProxy.measurementMap;
+ this.children = parentProxy.children;
+
+ }
+
+ public ResourceClientProxy(ResourceClientFactory factory, int resourceId) {
+ this.proxyFactory = factory;
+ this.remoteClient = factory.getRemoteClient();
+ this.resourceId = resourceId;
+
+ init();
+ }
+
+ @Summary(index = 0)
+ public int getId() {
+ return resourceId;
+ }
+
+ @Summary(index = 1)
+ public String getName() {
+ return resource.getName();
+ }
+
+ public String getDescription() {
+ return resource.getDescription();
+ }
+
+ @Summary(index = 2)
+ public String getVersion() {
+ return resource.getVersion();
+ }
+
+ @Summary(index = 3)
+ public ResourceType getResourceType() {
+ return resource.getResourceType();
+ }
+
+ public Date getCreatedDate() {
+ return new Date(resource.getCtime());
+ }
+
+ public Date getModifiedDate() {
+ return new Date(resource.getCtime());
+ }
+
+ public Measurement getMeasurement(String name) {
+ return this.measurementMap.get(name);
+ }
+
+ public Measurement[] getMeasurements() {
+ return this.measurementMap.values().toArray(new Measurement[this.measurementMap.size()]);
+ }
+
+ public Operation[] getOperations() {
+ return this.operationMap.values().toArray(new Operation[this.operationMap.size()]);
+ }
+
+ public Map<String, ContentType> getContentTypes() {
+ return contentTypes;
+ }
+
+ public ResourceClientProxy[] getChildren() {
+ if (children == null && LazyLoadScenario.isShouldLoad()) {
+ children = new ArrayList<ResourceClientProxy>();
+
+ initChildren();
+
+ }
+ return children.toArray(new ResourceClientProxy[children.size()]);
+ }
+
+ public ResourceClientProxy getChild(String name) {
+ for (ResourceClientProxy child : getChildren()) {
+ if (name.equals(child.getName()))
+ return child;
+ }
+ return null;
+ }
+
+ public String toString() {
+ return "[" + resourceId + "] " + resource.getName() + " (" + resource.getResourceType().getName() + "::"
+ + resource.getResourceType().getPlugin() + ")";
+ }
+
+ public void init() {
+
+ this.resource = remoteClient.getResourceManager().getResource(remoteClient.getSubject(), resourceId);
+
+ // Lazy init children, not here
+ initMeasurements();
+ initOperations();
+ initConfigDefs();
+ initContent();
+ }
+
+ private void initConfigDefs() {
+ this.resourceConfigurationDefinition = remoteClient.getConfigurationManager()
+ .getResourceConfigurationDefinitionWithTemplatesForResourceType(remoteClient.getSubject(),
+ resource.getResourceType().getId());
+ this.pluginConfigurationDefinition = remoteClient.getConfigurationManager()
+ .getPluginConfigurationDefinitionForResourceType(remoteClient.getSubject(),
+ resource.getResourceType().getId());
+ }
+
+ private void initChildren() {
+ ResourceCriteria criteria = new ResourceCriteria();
+ criteria.addFilterParentResourceId(resourceId);
+ PageList<Resource> childResources = remoteClient.getResourceManager().findResourcesByCriteria(
+ remoteClient.getSubject(), criteria);
+
+ for (Resource child : childResources) {
+ this.children.add(proxyFactory.getResource(child.getId()));
+ }
+ }
+
+ private void initMeasurements() {
+ MeasurementDefinitionCriteria criteria = new MeasurementDefinitionCriteria();
+ criteria.addFilterResourceTypeId(resource.getResourceType().getId());
+// criteria.addFilterResourceTypeName(resource.getResourceType().getName());
+// criteria.setStrict(true);
+
+ this.measurementDefinitions = remoteClient.getMeasurementDefinitionManager()
+ .findMeasurementDefinitionsByCriteria(remoteClient.getSubject(), criteria);
+
+ this.measurementMap = new HashMap<String, Measurement>();
+ for (MeasurementDefinition def : measurementDefinitions) {
+ Measurement m = new Measurement(def);
+
+ String name = def.getDisplayName().replaceAll("\\W", "");
+ name = decapitalize(name);
+
+ this.measurementMap.put(name, m);
+ this.allProperties.put(name, m);
+ }
+ }
+
+ public void initOperations() {
+ OperationDefinitionCriteria criteria = new OperationDefinitionCriteria();
+ criteria.addFilterResourceIds(resourceId);
+ criteria.fetchParametersConfigurationDefinition(true);
+ criteria.fetchResultsConfigurationDefinition(true);
+
+ this.operationDefinitions = remoteClient.getOperationManager().findOperationDefinitionsByCriteria(
+ remoteClient.getSubject(), criteria);
+
+ for (OperationDefinition def : operationDefinitions) {
+ Operation o = new Operation(def);
+ this.operationMap.put(o.getName(), o);
+ this.allProperties.put(o.getName(), o);
+ }
+ }
+
+ private void initContent() {
+ ContentManagerRemote contentManager = remoteClient.getContentManager();
+ List<PackageType> types = null;
+ try {
+ types = contentManager.findPackageTypes(remoteClient.getSubject(), resource.getResourceType().getName(),
+ resource.getResourceType().getPlugin());
+
+ for (PackageType packageType : types) {
+ contentTypes.put(packageType.getName(), new ContentType(packageType));
+ }
+ } catch (ResourceTypeNotFoundException e) {
+ e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
+ }
+
+ }
+
+ public class ContentType {
+
+ private PackageType packageType;
+
+ public ContentType(PackageType packageType) {
+ this.packageType = packageType;
+ }
+
+ public PackageType getPackageType() {
+ return this.packageType;
+ }
+
+ public List<PackageVersion> getInstalledPackages() {
+ ContentManagerRemote contentManager = remoteClient.getContentManager();
+
+ PackageVersionCriteria criteria = new PackageVersionCriteria();
+ criteria.addFilterResourceId(resourceId);
+ // criteria.addFilterPackageTypeId() TODO ADD this when the filter is added
+
+ return contentManager.findPackageVersionsByCriteria(remoteClient.getSubject(), criteria);
+ }
+
+ public String toString() {
+ return this.packageType.getDisplayName();
+ }
+
+ }
+
+ public class Measurement implements ShortOutput {
+
+ MeasurementDefinition definition;
+
+ public Measurement(MeasurementDefinition definition) {
+ this.definition = definition;
+ }
+
+ @Summary(index = 0)
+ public String getName() {
+ return definition.getDisplayName();
+ }
+
+ @Summary(index = 1)
+ public String getDisplayValue() {
+ Object val = getValue();
+ if (val instanceof Number) {
+ return MeasurementConverter.format(((Number) val).doubleValue(), getUnits(), true);
+ } else {
+ return String.valueOf(val);
+ }
+ }
+
+ @Summary(index = 2)
+ public String getDescription() {
+ return definition.getDescription();
+ }
+
+ public DataType getDataType() {
+ return definition.getDataType();
+ }
+
+ public MeasurementCategory getCategory() {
+ return definition.getCategory();
+ }
+
+ public MeasurementUnits getUnits() {
+ return definition.getUnits();
+ }
+
+ public Object getValue() {
+ try {
+ Set<MeasurementData> d = remoteClient.getMeasurementDataManager().findLiveData(
+ remoteClient.getSubject(), resourceId, new int[] { definition.getId() });
+ MeasurementData data = d.iterator().next();
+ return data.getValue();
+ } catch (Exception e) {
+ return "?";
+ }
+ }
+
+ public String toString() {
+ return getName();
+ }
+ public String getShortOutput() {
+ return getDisplayValue();
+ }
+ }
+
+ public class Operation {
+ OperationDefinition definition;
+
+ public Operation(OperationDefinition definition) {
+ this.definition = definition;
+ }
+
+ @Summary(index = 0)
+ public String getName() {
+ return simpleName(this.definition.getDisplayName());
+ }
+
+ @Summary(index = 1)
+ public String getDescription() {
+ return this.definition.getDescription();
+ }
+
+ public OperationDefinition getDefinition() {
+ return definition;
+ }
+
+ public Object invoke(Object[] args) throws Exception {
+ if (!LazyLoadScenario.isShouldLoad())
+ return null;
+
+ Configuration parameters = ConfigurationClassBuilder.translateParametersToConfig(definition
+ .getParametersConfigurationDefinition(), args);
+
+ ResourceOperationSchedule schedule = remoteClient.getOperationManager().scheduleResourceOperation(
+ remoteClient.getSubject(), resourceId, definition.getName(), 0, 0, 0, 30000, parameters,
+ "Executed from commandline");
+
+ ResourceOperationHistoryCriteria criteria = new ResourceOperationHistoryCriteria();
+ criteria.addFilterJobId(schedule.getJobId());
+ criteria.addFilterResourceIds(resourceId);
+ criteria.addSortStartTime(PageOrdering.DESC); // put most recent at top of results
+ criteria.setPaging(0, 1); // only return one result, in effect the latest
+ criteria.fetchOperationDefinition(true);
+ criteria.fetchParameters(true);
+ criteria.fetchResults(true);
+
+ int retries = 10;
+ ResourceOperationHistory history = null;
+ while (history == null && retries-- > 0) {
+ Thread.sleep(1000);
+ PageList<ResourceOperationHistory> histories = remoteClient.getOperationManager()
+ .findResourceOperationHistoriesByCriteria(remoteClient.getSubject(), criteria);
+ if (histories.size() > 0 && histories.get(0).getStatus() != OperationRequestStatus.INPROGRESS) {
+ history = histories.get(0);
+ }
+ }
+
+ Configuration result = (history != null ? history.getResults() : null);
+
+ Object returnResults = ConfigurationClassBuilder.translateResults(definition
+ .getResultsConfigurationDefinition(), result);
+
+ return returnResults;
+ }
+
+ @Override
+ public String toString() {
+ return getName();
+ }
+ }
+
+ public static class ClientProxyMethodHandler implements MethodHandler, ContentBackedResource, PluginConfigurable,
+ ResourceConfigurable {
+
+ ResourceClientProxy resourceClientProxy;
+ RhqFacade remoteClient;
+
+ public ClientProxyMethodHandler(ResourceClientProxy resourceClientProxy, RhqFacade remoteClient) {
+ this.resourceClientProxy = resourceClientProxy;
+ this.remoteClient = remoteClient;
+ }
+
+ // ------------------------------------------------------------------------------------------------------
+ // Methods here are optional and only accessible if their declared on the custom resource interface class
+
+ public Configuration getPluginConfiguration() {
+ if (!LazyLoadScenario.isShouldLoad())
+ return null;
+ return remoteClient.getConfigurationManager().getPluginConfiguration(remoteClient.getSubject(),
+ resourceClientProxy.resourceId);
+ }
+
+ public ConfigurationDefinition getPluginConfigurationDefinition() {
+ return resourceClientProxy.pluginConfigurationDefinition;
+ }
+
+ public PluginConfigurationUpdate updatePluginConfiguration(Configuration configuration) {
+ PluginConfigurationUpdate update =
+ remoteClient.getConfigurationManager().updatePluginConfiguration(
+ remoteClient.getSubject(),
+ resourceClientProxy.getId(),
+ configuration);
+
+ return update;
+ }
+
+ public Configuration getResourceConfiguration() {
+ if (!LazyLoadScenario.isShouldLoad())
+ return null;
+
+ return remoteClient.getConfigurationManager().getResourceConfiguration(remoteClient.getSubject(),
+ resourceClientProxy.resourceId);
+ }
+
+ public ConfigurationDefinition getResourceConfigurationDefinition() {
+ return resourceClientProxy.resourceConfigurationDefinition;
+ }
+
+ public ResourceConfigurationUpdate updateResourceConfiguration(Configuration configuration) {
+ ResourceConfigurationUpdate update =
+ remoteClient.getConfigurationManager().updateResourceConfiguration(
+ remoteClient.getSubject(),
+ resourceClientProxy.getId(),
+ configuration);
+
+ return update;
+
+ }
+
+ public InstalledPackage getBackingContent() {
+
+ return remoteClient.getContentManager().getBackingPackageForResource(remoteClient.getSubject(), resourceClientProxy.resourceId);
+ }
+
+ public void updateBackingContent(String filename) {
+ File file = new File(filename);
+ if (!file.exists()) {
+ throw new IllegalArgumentException("File not found: " + file.getAbsolutePath());
+ }
+ if (file.isDirectory()) {
+ throw new IllegalArgumentException("File expected, found directory: " + file.getAbsolutePath());
+ }
+
+
+ InstalledPackage oldPackage = getBackingContent();
+
+
+ String oldVersion = oldPackage.getPackageVersion().getVersion();
+ String newVersion = "1.0";
+ if (oldVersion != null && oldVersion.length() != 0) {
+ String[] parts = oldVersion.split("[^a-zA-Z0-9]");
+ String lastPart = parts[parts.length-1];
+ try {
+ int lastNumber = Integer.parseInt(lastPart);
+ newVersion = oldVersion.substring(0, oldVersion.length() - lastPart.length()) + (lastNumber + 1);
+ } catch (NumberFormatException nfe) {
+ newVersion = oldVersion + ".1";
+ }
+ }
+
+ byte[] fileContents = new ScriptUtil(remoteClient).getFileBytes(filename);
+
+
+ PackageVersion pv =
+ remoteClient.getContentManager().createPackageVersion(
+ remoteClient.getSubject(),
+ oldPackage.getPackageVersion().getGeneralPackage().getName(),
+ oldPackage.getPackageVersion().getGeneralPackage().getPackageType().getId(),
+ newVersion,
+ oldPackage.getPackageVersion().getArchitecture().getId(),
+ fileContents);
+
+ remoteClient.getContentManager().deployPackages(
+ remoteClient.getSubject(),
+ new int[] { resourceClientProxy.getId()},
+ new int[] {pv.getId()});
+
+
+ }
+
+ public void retrieveBackingContent(String fileName) throws IOException {
+
+ InstalledPackage installedPackage = getBackingContent();
+
+ if (fileName == null )
+ fileName = installedPackage.getPackageVersion().getFileName();
+
+ File file = new File(fileName);
+
+ byte[] data =
+ remoteClient.getContentManager().getPackageBytes(
+ remoteClient.getSubject(), resourceClientProxy.resourceId, installedPackage.getId());
+
+ FileOutputStream fos = new FileOutputStream(file);
+ fos.write(data);
+ fos.close();
+
+ }
+
+ // ------------------------------------------------------------------------------------------------------
+
+
+
+ public Object invoke(Object proxy, Method method, Method proceedMethod, Object[] args) throws Throwable {
+
+ if (proceedMethod != null) {
+ Method realMethod = ResourceClientProxy.class.getMethod(method.getName(), method.getParameterTypes());
+ return realMethod.invoke(resourceClientProxy, args);
+ } else {
+
+ try {
+ Method localMethod = ClientProxyMethodHandler.class.getDeclaredMethod(method.getName(), method
+ .getParameterTypes());
+ return localMethod.invoke(this, args);
+ } catch (NoSuchMethodException nsme) {
+
+ String name = method.getName();
+ Object key = resourceClientProxy.allProperties.get(name);
+ if (key == null) {
+ name = decapitalize(method.getName().substring(3, method.getName().length()));
+ key = resourceClientProxy.allProperties.get(name);
+ }
+
+ if (key != null) {
+ if (key instanceof Measurement) {
+ return key;
+ } else if (key instanceof Operation) {
+ resourceClientProxy.proxyFactory.getOutputWriter().println("Invoking operation " + ((Operation) key).getName());
+
+ return ((Operation) key).invoke(args);
+
+ }
+ }
+ }
+
+ throw new RuntimeException("Can't find custom method: " + method);
+ }
+ }
+ }
+
+
+ static String simpleName(String name) {
+ return decapitalize(name.replaceAll("\\W", ""));
+ }
+
+ private static String decapitalize(String name) {
+ return Character.toLowerCase(name.charAt(0)) + name.substring(1, name.length());
+ }
+
+ static String getterName(String name) {
+ return "get" + Character.toUpperCase(name.charAt(0)) + name.substring(1, name.length());
+ }
+
+ public static interface PluginConfigurable {
+ public Configuration getPluginConfiguration();
+
+ public ConfigurationDefinition getPluginConfigurationDefinition();
+
+ public PluginConfigurationUpdate updatePluginConfiguration(Configuration configuration);
+ }
+
+ public static interface ResourceConfigurable {
+ public Configuration getResourceConfiguration();
+
+ public ConfigurationDefinition getResourceConfigurationDefinition();
+
+ public ResourceConfigurationUpdate updateResourceConfiguration(Configuration configuration);
+ }
+
+ public static interface ContentBackedResource {
+
+ public InstalledPackage getBackingContent();
+
+
+ public void updateBackingContent(String fileName);
+
+
+ public void retrieveBackingContent(String fileName) throws IOException;
+
+ }
+}
diff --git a/modules/enterprise/binding/src/main/java/org/rhq/bindings/client/RhqFacade.java b/modules/enterprise/binding/src/main/java/org/rhq/bindings/client/RhqFacade.java
new file mode 100644
index 0000000..24fbc3b
--- /dev/null
+++ b/modules/enterprise/binding/src/main/java/org/rhq/bindings/client/RhqFacade.java
@@ -0,0 +1,132 @@
+/*
+ * 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 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.bindings.client;
+
+import java.util.Map;
+
+import org.rhq.core.domain.auth.Subject;
+import org.rhq.enterprise.server.alert.AlertDefinitionManagerRemote;
+import org.rhq.enterprise.server.alert.AlertManagerRemote;
+import org.rhq.enterprise.server.auth.SubjectManagerRemote;
+import org.rhq.enterprise.server.authz.RoleManagerRemote;
+import org.rhq.enterprise.server.bundle.BundleManagerRemote;
+import org.rhq.enterprise.server.configuration.ConfigurationManagerRemote;
+import org.rhq.enterprise.server.content.ContentManagerRemote;
+import org.rhq.enterprise.server.content.RepoManagerRemote;
+import org.rhq.enterprise.server.discovery.DiscoveryBossRemote;
+import org.rhq.enterprise.server.event.EventManagerRemote;
+import org.rhq.enterprise.server.install.remote.RemoteInstallManagerRemote;
+import org.rhq.enterprise.server.measurement.AvailabilityManagerRemote;
+import org.rhq.enterprise.server.measurement.CallTimeDataManagerRemote;
+import org.rhq.enterprise.server.measurement.MeasurementBaselineManagerRemote;
+import org.rhq.enterprise.server.measurement.MeasurementDataManagerRemote;
+import org.rhq.enterprise.server.measurement.MeasurementDefinitionManagerRemote;
+import org.rhq.enterprise.server.measurement.MeasurementScheduleManagerRemote;
+import org.rhq.enterprise.server.operation.OperationManagerRemote;
+import org.rhq.enterprise.server.report.DataAccessManagerRemote;
+import org.rhq.enterprise.server.resource.ResourceFactoryManagerRemote;
+import org.rhq.enterprise.server.resource.ResourceManagerRemote;
+import org.rhq.enterprise.server.resource.ResourceTypeManagerRemote;
+import org.rhq.enterprise.server.resource.group.ResourceGroupManagerRemote;
+import org.rhq.enterprise.server.search.SavedSearchManagerRemote;
+import org.rhq.enterprise.server.support.SupportManagerRemote;
+import org.rhq.enterprise.server.system.SystemManagerRemote;
+import org.rhq.enterprise.server.tagging.TagManagerRemote;
+
+/**
+ * This is an interface through which the script can communicate with RHQ server.
+ *
+ * @author Lukas Krejci
+ */
+public interface RhqFacade {
+
+ /**
+ * @return the user the facade is authenticated as
+ */
+ Subject getSubject();
+
+ Subject login(String user, String password) throws Exception;
+
+ void logout();
+
+ boolean isLoggedIn();
+
+ AlertManagerRemote getAlertManager();
+
+ AlertDefinitionManagerRemote getAlertDefinitionManager();
+
+ AvailabilityManagerRemote getAvailabilityManager();
+
+ BundleManagerRemote getBundleManager();
+
+ CallTimeDataManagerRemote getCallTimeDataManager();
+
+ RepoManagerRemote getRepoManager();
+
+ ConfigurationManagerRemote getConfigurationManager();
+
+ ContentManagerRemote getContentManager();
+
+ DataAccessManagerRemote getDataAccessManager();
+
+ DiscoveryBossRemote getDiscoveryBoss();
+
+ EventManagerRemote getEventManager();
+
+ MeasurementBaselineManagerRemote getMeasurementBaselineManager();
+
+ MeasurementDataManagerRemote getMeasurementDataManager();
+
+ MeasurementDefinitionManagerRemote getMeasurementDefinitionManager();
+
+ MeasurementScheduleManagerRemote getMeasurementScheduleManager();
+
+ OperationManagerRemote getOperationManager();
+
+ ResourceManagerRemote getResourceManager();
+
+ ResourceFactoryManagerRemote getResourceFactoryManager();
+
+ ResourceGroupManagerRemote getResourceGroupManager();
+
+ ResourceTypeManagerRemote getResourceTypeManager();
+
+ RoleManagerRemote getRoleManager();
+
+ SavedSearchManagerRemote getSavedSearchManager();
+
+ SubjectManagerRemote getSubjectManager();
+
+ SupportManagerRemote getSupportManager();
+
+ SystemManagerRemote getSystemManager();
+
+ RemoteInstallManagerRemote getRemoteInstallManager();
+
+ TagManagerRemote getTagManager();
+
+ /**
+ * This map is constructed using all the elements in the {@link RhqManagers} enum which are then proxied
+ * using this instance.
+ *
+ * @return a map of all available proxied managers keyed by their names.
+ */
+ Map<String, Object> getManagers();
+}
diff --git a/modules/enterprise/binding/src/main/java/org/rhq/bindings/client/RhqManagers.java b/modules/enterprise/binding/src/main/java/org/rhq/bindings/client/RhqManagers.java
new file mode 100644
index 0000000..b4e6f21
--- /dev/null
+++ b/modules/enterprise/binding/src/main/java/org/rhq/bindings/client/RhqManagers.java
@@ -0,0 +1,116 @@
+/*
+ * 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 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.bindings.client;
+
+import org.rhq.enterprise.server.alert.AlertDefinitionManagerRemote;
+import org.rhq.enterprise.server.alert.AlertManagerRemote;
+import org.rhq.enterprise.server.auth.SubjectManagerRemote;
+import org.rhq.enterprise.server.authz.RoleManagerRemote;
+import org.rhq.enterprise.server.bundle.BundleManagerRemote;
+import org.rhq.enterprise.server.configuration.ConfigurationManagerRemote;
+import org.rhq.enterprise.server.content.ContentManagerRemote;
+import org.rhq.enterprise.server.content.RepoManagerRemote;
+import org.rhq.enterprise.server.discovery.DiscoveryBossRemote;
+import org.rhq.enterprise.server.event.EventManagerRemote;
+import org.rhq.enterprise.server.install.remote.RemoteInstallManagerRemote;
+import org.rhq.enterprise.server.measurement.AvailabilityManagerRemote;
+import org.rhq.enterprise.server.measurement.CallTimeDataManagerRemote;
+import org.rhq.enterprise.server.measurement.MeasurementBaselineManagerRemote;
+import org.rhq.enterprise.server.measurement.MeasurementDataManagerRemote;
+import org.rhq.enterprise.server.measurement.MeasurementDefinitionManagerRemote;
+import org.rhq.enterprise.server.measurement.MeasurementScheduleManagerRemote;
+import org.rhq.enterprise.server.operation.OperationManagerRemote;
+import org.rhq.enterprise.server.report.DataAccessManagerRemote;
+import org.rhq.enterprise.server.resource.ResourceFactoryManagerRemote;
+import org.rhq.enterprise.server.resource.ResourceManagerRemote;
+import org.rhq.enterprise.server.resource.ResourceTypeManagerRemote;
+import org.rhq.enterprise.server.resource.group.ResourceGroupManagerRemote;
+import org.rhq.enterprise.server.search.SavedSearchManagerRemote;
+import org.rhq.enterprise.server.support.SupportManagerRemote;
+import org.rhq.enterprise.server.system.SystemManagerRemote;
+import org.rhq.enterprise.server.tagging.TagManagerRemote;
+
+/**
+ * An enumeration of all remote SLSBs of the RHQ server.
+ *
+ * @author Lukas Krejci
+ * @author Greg Hinkle
+ */
+public enum RhqManagers {
+ AlertManager(AlertManagerRemote.class), //
+ AlertDefinitionManager(AlertDefinitionManagerRemote.class), //
+ AvailabilityManager(AvailabilityManagerRemote.class), //
+ BundleManager(BundleManagerRemote.class), //
+ CallTimeDataManager(CallTimeDataManagerRemote.class), //
+ RepoManager(RepoManagerRemote.class), //
+ ConfigurationManager(ConfigurationManagerRemote.class), //
+ ContentManager(ContentManagerRemote.class), //
+ DataAccessManager(DataAccessManagerRemote.class), //
+ DiscoveryBoss(DiscoveryBossRemote.class), //
+ EventManager(EventManagerRemote.class), //
+ MeasurementBaselineManager(MeasurementBaselineManagerRemote.class), //
+ MeasurementDataManager(MeasurementDataManagerRemote.class), //
+ MeasurementDefinitionManager(MeasurementDefinitionManagerRemote.class), //
+ MeasurementScheduleManager(MeasurementScheduleManagerRemote.class), //
+ OperationManager(OperationManagerRemote.class), //
+ ResourceManager(ResourceManagerRemote.class), //
+ ResourceFactoryManager(ResourceFactoryManagerRemote.class), //
+ ResourceGroupManager(ResourceGroupManagerRemote.class), //
+ ResourceTypeManager(ResourceTypeManagerRemote.class), //
+ RoleManager(RoleManagerRemote.class), //
+ SavedSearchManager(SavedSearchManagerRemote.class), //
+ SubjectManager(SubjectManagerRemote.class), //
+ SupportManager(SupportManagerRemote.class), //
+ SystemManager(SystemManagerRemote.class), //
+ RemoteInstallManager(RemoteInstallManagerRemote.class), //
+ TagManager(TagManagerRemote.class);
+
+ private Class<?> remote;
+ private String remoteName;
+ private String beanName;
+
+ private RhqManagers(Class<?> remote) {
+ this.remote = remote;
+ this.beanName = this.name() + "Bean";
+ this.remoteName = this.name() + "Remote";
+ }
+
+ public static RhqManagers forInterface(Class<?> iface) {
+ for (RhqManagers m : values()) {
+ if (m.remote().equals(iface)) {
+ return m;
+ }
+ }
+
+ return null;
+ }
+
+ public Class<?> remote() {
+ return this.remote;
+ }
+
+ public String beanName() {
+ return this.beanName;
+ }
+
+ public String remoteName() {
+ return this.remoteName;
+ }
+}
\ No newline at end of file
diff --git a/modules/enterprise/binding/src/main/java/org/rhq/bindings/engine/JsEngineInitializer.java b/modules/enterprise/binding/src/main/java/org/rhq/bindings/engine/JsEngineInitializer.java
index 8186831..30b79e1 100644
--- a/modules/enterprise/binding/src/main/java/org/rhq/bindings/engine/JsEngineInitializer.java
+++ b/modules/enterprise/binding/src/main/java/org/rhq/bindings/engine/JsEngineInitializer.java
@@ -19,6 +19,7 @@
package org.rhq.bindings.engine;
+import java.lang.reflect.Method;
import java.util.List;
import javax.script.ScriptEngine;
@@ -32,13 +33,13 @@ import javax.script.ScriptException;
*/
public class JsEngineInitializer implements ScriptEngineInitializer {
- public String getEngineName() {
- return "JavaScript";
+ public boolean implementsLanguage(String language) {
+ return language != null && ("JavaScript".equals(language) || "ECMAScript".equals(language));
}
public ScriptEngine instantiate(List<String> packages) throws ScriptException {
ScriptEngineManager sem = new ScriptEngineManager();
- ScriptEngine eng = sem.getEngineByName(getEngineName());
+ ScriptEngine eng = sem.getEngineByName("JavaScript");
for(String pkg : packages) {
eng.eval("importPackage(" + pkg + ")");
@@ -47,4 +48,25 @@ public class JsEngineInitializer implements ScriptEngineInitializer {
return eng;
}
+ public String generateIndirectionMethod(String boundObjectName, Method method) {
+ String methodName = method.getName();
+ int argCount = method.getParameterTypes().length;
+
+ StringBuilder functionBuilder = new StringBuilder();
+ functionBuilder.append(methodName).append("(");
+ for (int i = 0; i < argCount; ++i) {
+ if (i != 0) {
+ functionBuilder.append(", ");
+ }
+ functionBuilder.append("arg_" + i);
+ }
+ functionBuilder.append(")");
+ String functionFragment = functionBuilder.toString();
+ boolean returnsVoid = method.getReturnType().equals(Void.TYPE);
+
+ String functionDefinition = "function " + functionFragment + " { " + (returnsVoid ? "" : "return ")
+ + boundObjectName + "." + functionFragment + "; }";
+
+ return functionDefinition;
+ }
}
diff --git a/modules/enterprise/binding/src/main/java/org/rhq/bindings/engine/ScriptEngineInitializer.java b/modules/enterprise/binding/src/main/java/org/rhq/bindings/engine/ScriptEngineInitializer.java
index bc76433..d938589 100644
--- a/modules/enterprise/binding/src/main/java/org/rhq/bindings/engine/ScriptEngineInitializer.java
+++ b/modules/enterprise/binding/src/main/java/org/rhq/bindings/engine/ScriptEngineInitializer.java
@@ -19,20 +19,41 @@
package org.rhq.bindings.engine;
+import java.lang.reflect.Method;
import java.util.List;
import javax.script.ScriptEngine;
import javax.script.ScriptException;
/**
- * Is able to instatiate a script engine and import packages into the context
+ * Is able to instantiate a script engine and import packages into the context
* of the engine.
*
* @author Lukas Krejci
*/
public interface ScriptEngineInitializer {
- String getEngineName();
+ boolean implementsLanguage(String language);
ScriptEngine instantiate(List<String> packages) throws ScriptException;
+
+ /**
+ * This function returns a definition string in the script engine's language
+ * that provides an indirection to calling the method on the bound object.
+ *
+ * for example for parameters:
+ * <ul>
+ * <li> <code>boundObjectName = foo</code>
+ * <li> <code> method = <int bar(int)></code>
+ * </ul>
+ * The method would generate this javascript:<br/>
+ * <code>
+ * function bar(arg) { return foo.bar(arg); }
+ * </code>
+ *
+ * @param boundObjectName
+ * @param method
+ * @return a string with method definition in the scripting language
+ */
+ String generateIndirectionMethod(String boundObjectName, Method method);
}
diff --git a/modules/enterprise/binding/src/main/java/org/rhq/bindings/util/ConfigurationClassBuilder.java b/modules/enterprise/binding/src/main/java/org/rhq/bindings/util/ConfigurationClassBuilder.java
new file mode 100644
index 0000000..29bd4a6
--- /dev/null
+++ b/modules/enterprise/binding/src/main/java/org/rhq/bindings/util/ConfigurationClassBuilder.java
@@ -0,0 +1,158 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2008 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.bindings.util;
+
+import java.util.LinkedHashMap;
+
+import javassist.ClassPool;
+import javassist.CtClass;
+import javassist.NotFoundException;
+
+import org.rhq.core.domain.configuration.Configuration;
+import org.rhq.core.domain.configuration.PropertySimple;
+import org.rhq.core.domain.configuration.definition.ConfigurationDefinition;
+import org.rhq.core.domain.configuration.definition.PropertyDefinition;
+import org.rhq.core.domain.configuration.definition.PropertyDefinitionSimple;
+
+/**
+ * @author Greg Hinkle
+ */
+public class ConfigurationClassBuilder {
+
+ public static LinkedHashMap<String, CtClass> translateParameters(ConfigurationDefinition def)
+ throws NotFoundException {
+ LinkedHashMap<String, CtClass> result = new LinkedHashMap<String, CtClass>();
+ if (def == null || def.getPropertyDefinitions() == null) {
+ return result;
+ }
+
+ for (PropertyDefinition pd : def.getPropertyDefinitions().values()) {
+ if (pd instanceof PropertyDefinitionSimple) {
+ PropertyDefinitionSimple simple = (PropertyDefinitionSimple) pd;
+ String name = simpleName(simple.getDisplayName());
+ CtClass paramType = getSimpleTypeClass(simple);
+ result.put(name, paramType);
+ }
+ }
+ return result;
+ }
+
+ private static CtClass getSimpleTypeClass(PropertyDefinitionSimple simple) throws NotFoundException {
+ Class<?> paramType = null;
+ switch (simple.getType()) {
+ case STRING:
+ case LONG_STRING:
+ case PASSWORD:
+ case FILE:
+ case DIRECTORY:
+ paramType = String.class;
+ break;
+ case BOOLEAN:
+ paramType = Boolean.TYPE;
+ break;
+ case INTEGER:
+ paramType = Integer.TYPE;
+ break;
+ case LONG:
+ paramType = Long.TYPE;
+ break;
+ case FLOAT:
+ paramType = Float.TYPE;
+ break;
+ case DOUBLE:
+ paramType = Double.TYPE;
+ break;
+ }
+ return ClassPool.getDefault().get(paramType.getName());
+ }
+
+ public static CtClass translateConfiguration(ConfigurationDefinition def) throws NotFoundException {
+ if (def == null) {
+ return CtClass.voidType;
+ } else if (def.getPropertyDefinitionSimple("operationResult") != null) {
+ // Its a simple type
+ return getSimpleTypeClass(def.getPropertyDefinitionSimple("operationResult"));
+ } else {
+
+ // TODO GH: Build a custom type?
+ return ClassPool.getDefault().get(Configuration.class.getName());
+ }
+ }
+
+ private static String simpleName(String name) {
+ return decapitalize(name.replaceAll("\\W", ""));
+ }
+
+ private static String decapitalize(String name) {
+ return Character.toLowerCase(name.charAt(0)) + name.substring(1, name.length());
+ }
+
+ public static Configuration translateParametersToConfig(ConfigurationDefinition parametersConfigurationDefinition,
+ Object[] args) throws NotFoundException {
+ LinkedHashMap<String, CtClass> translateParameters = translateParameters(parametersConfigurationDefinition);
+ Configuration config = new Configuration();
+
+ int index = 0;
+ for (String key : translateParameters.keySet()) {
+ config.put(new PropertySimple(key, args[index++]));
+
+ }
+ return config;
+
+ }
+
+ public static Object translateResults(ConfigurationDefinition resultsConfigurationDefinition, Configuration result)
+ throws NotFoundException {
+
+ CtClass expectedReturn = translateConfiguration(resultsConfigurationDefinition);
+
+ if (expectedReturn.equals(ClassPool.getDefault().get(Configuration.class.getName()))) {
+ return result;
+ } else {
+ //bail on translation if Configuration passed in is null
+ if (result == null)
+ return result;
+ PropertySimple simple = result.getSimple("operationResult");
+ if (simple != null) {
+ if (expectedReturn.getName().equals(String.class.getName())) {
+ return simple.getStringValue();
+ } else if (expectedReturn.getName().equals(Boolean.class.getName())
+ || expectedReturn.getName().equals(Boolean.TYPE.getName())) {
+ return simple.getBooleanValue();
+ } else if (expectedReturn.getName().equals(Integer.class.getName())
+ || expectedReturn.getName().equals(Integer.TYPE.getName())) {
+ return simple.getIntegerValue();
+ } else if (expectedReturn.getName().equals(Long.class.getName())
+ || expectedReturn.getName().equals(Long.TYPE.getName())) {
+ return simple.getLongValue();
+ } else if (expectedReturn.getName().equals(Float.class.getName())
+ || expectedReturn.getName().equals(Float.TYPE.getName())) {
+ return simple.getFloatValue();
+ } else if (expectedReturn.getName().equals(Double.class.getName())
+ || expectedReturn.getName().equals(Double.TYPE.getName())) {
+ return simple.getDoubleValue();
+ } else if (expectedReturn.getName().equals(Boolean.class.getName())
+ || expectedReturn.getName().equals(Boolean.TYPE.getName())) {
+ return simple.getBooleanValue();
+ }
+ }
+ }
+ return null;
+ }
+}
diff --git a/modules/enterprise/binding/src/main/java/org/rhq/bindings/util/InterfaceSimplifier.java b/modules/enterprise/binding/src/main/java/org/rhq/bindings/util/InterfaceSimplifier.java
new file mode 100644
index 0000000..fba954a
--- /dev/null
+++ b/modules/enterprise/binding/src/main/java/org/rhq/bindings/util/InterfaceSimplifier.java
@@ -0,0 +1,128 @@
+/*
+ * 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 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.bindings.util;
+
+import javassist.CannotCompileException;
+import javassist.ClassPool;
+import javassist.CtClass;
+import javassist.CtMethod;
+import javassist.CtNewMethod;
+import javassist.NotFoundException;
+import javassist.bytecode.ParameterAnnotationsAttribute;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.rhq.core.domain.auth.Subject;
+
+/**
+ * The scripts can use simplified interfaces that omit the first "Subject" argument
+ * to most methods. This helper class prepares such simplified interfaces.
+ *
+ * @author Greg Hinkle
+ * @author Lukas Krejci
+ */
+public class InterfaceSimplifier {
+ private static final Log LOG = LogFactory.getLog(InterfaceSimplifier.class);
+
+ private InterfaceSimplifier() {
+
+ }
+
+ public static Class<?> simplify(Class<?> intf) {
+ try {
+ ClassPool cp = ClassPool.getDefault();
+
+ String simpleName = intf.getName() + "Simple";
+
+ try {
+ CtClass cached = cp.get(simpleName);
+ return Class.forName(simpleName, false, cp.getClassLoader());
+
+ } catch (NotFoundException e) {
+ // ok... load it
+ } catch (ClassNotFoundException e) {
+ LOG.debug("Class [" + simpleName + "] not found - cause: " + e);
+ }
+
+ CtClass cc = cp.get(intf.getName());
+
+ CtClass cz = cp.getAndRename(intf.getName(), simpleName);
+ // CtClass cz = cp.makeInterface(simpleName, cc);
+
+ cz.defrost();
+
+ cz.setSuperclass(cc);
+
+ CtMethod[] methods = cc.getMethods();
+
+ for (CtMethod originalMethod : methods) {
+
+ CtClass[] params = originalMethod.getParameterTypes();
+ if (params.length > 0 && params[0].getName().equals(Subject.class.getName())) {
+
+ CtClass[] simpleParams = new CtClass[params.length - 1];
+
+ System.arraycopy(params, 1, simpleParams, 0, params.length - 1);
+ cz.defrost();
+
+ CtMethod newMethod = CtNewMethod.abstractMethod(originalMethod.getReturnType(), originalMethod
+ .getName(), simpleParams, null, cz);
+
+ ParameterAnnotationsAttribute originalAnnotationsAttribute = (ParameterAnnotationsAttribute) originalMethod
+ .getMethodInfo().getAttribute(ParameterAnnotationsAttribute.visibleTag);
+
+ // If there are any parameter annotations, copy the one's we're keeping
+ if (originalAnnotationsAttribute != null) {
+
+ javassist.bytecode.annotation.Annotation[][] originalAnnotations = originalAnnotationsAttribute
+ .getAnnotations();
+ javassist.bytecode.annotation.Annotation[][] newAnnotations = new javassist.bytecode.annotation.Annotation[originalAnnotations.length - 1][];
+
+ for (int i = 1; i < originalAnnotations.length; i++) {
+ newAnnotations[i - 1] = new javassist.bytecode.annotation.Annotation[originalAnnotations[i].length];
+ System.arraycopy(originalAnnotations[i], 0, newAnnotations[i - 1], 0,
+ originalAnnotations[i].length);
+ }
+
+ ParameterAnnotationsAttribute newAnnotationsAttribute = new ParameterAnnotationsAttribute(
+ newMethod.getMethodInfo().getConstPool(), ParameterAnnotationsAttribute.visibleTag);
+
+ newAnnotationsAttribute.setAnnotations(newAnnotations);
+
+ newMethod.getMethodInfo().addAttribute(newAnnotationsAttribute);
+
+ }
+
+ cz.addMethod(newMethod);
+ }
+ }
+
+ return cz.toClass();
+
+ } catch (NotFoundException e) {
+ LOG.debug("Failed to simplify " + intf + " - cause: " + e);
+ } catch (CannotCompileException e) {
+ LOG.error("Failed to simplify " + intf + ".", e);
+ }
+ return intf;
+ }
+
+}
diff --git a/modules/enterprise/binding/src/main/java/org/rhq/bindings/util/PackageFinder.java b/modules/enterprise/binding/src/main/java/org/rhq/bindings/util/PackageFinder.java
index d48382f..d1ba40c 100644
--- a/modules/enterprise/binding/src/main/java/org/rhq/bindings/util/PackageFinder.java
+++ b/modules/enterprise/binding/src/main/java/org/rhq/bindings/util/PackageFinder.java
@@ -44,14 +44,7 @@ public class PackageFinder {
}
public List<String> findPackages(String packageRoot) throws IOException {
- ArrayList<String> found = new ArrayList<String>();
-
-//TODO this is where the original package finder used to look for the jars.
-//update the code somewhere in the CLI client to supply this dir to this
-//new style impl.
-// String cwd = System.getProperty("user.dir");
-// File libDir = new File(cwd, "lib");
-
+ ArrayList<String> found = new ArrayList<String>();
List<File> jars = new ArrayList<File>();
diff --git a/modules/enterprise/binding/src/main/java/org/rhq/bindings/util/ScriptAssert.java b/modules/enterprise/binding/src/main/java/org/rhq/bindings/util/ScriptAssert.java
new file mode 100644
index 0000000..6d68608
--- /dev/null
+++ b/modules/enterprise/binding/src/main/java/org/rhq/bindings/util/ScriptAssert.java
@@ -0,0 +1,421 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2008 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.bindings.util;
+
+import java.util.Collection;
+
+import javax.script.ScriptEngine;
+
+import org.testng.Assert;
+
+public class ScriptAssert {
+
+ private ScriptEngine scriptEngine;
+
+ public ScriptAssert() {
+
+ }
+
+ public ScriptAssert(ScriptEngine scriptEngine) {
+ this.scriptEngine = scriptEngine;
+ }
+
+ public void init(ScriptEngine engine) {
+ this.scriptEngine = engine;
+ }
+
+ public void assertTrue(boolean condition, String msg) {
+ try {
+ Assert.assertTrue(condition, msg);
+ } catch (AssertionError e) {
+ throw new ScriptAssertionException(e);
+ }
+ }
+
+ public void assertTrue(boolean condition) {
+ try {
+ Assert.assertTrue(condition);
+ } catch (AssertionError e) {
+ throw new ScriptAssertionException(e);
+ }
+ }
+
+ public void assertFalse(boolean condition, String msg) {
+ try {
+ Assert.assertFalse(condition, msg);
+ } catch (AssertionError e) {
+ throw new ScriptAssertionException(e);
+ }
+ }
+
+ public void assertFalse(boolean condition) {
+ try {
+ Assert.assertFalse(condition);
+ } catch (AssertionError e) {
+ throw new ScriptAssertionException(e);
+ }
+ }
+
+ public void fail(String msg, Throwable throwable) {
+ try {
+ Assert.fail(msg, throwable);
+ } catch (AssertionError e) {
+ throw new ScriptAssertionException(e);
+ }
+ }
+
+ public void fail(String msg) {
+ try {
+ Assert.fail(msg);
+ } catch (AssertionError e) {
+ throw new ScriptAssertionException(e);
+ }
+ }
+
+ public void fail() {
+ throw new ScriptAssertionException(new AssertionError());
+ }
+
+ public void assertEquals(Object actual, Object expected, String msg) {
+ try {
+ Assert.assertEquals(actual, expected, msg);
+ } catch (AssertionError e) {
+ throw new ScriptAssertionException(e);
+ }
+ }
+
+ public void assertEquals(Object actual, Object expected) {
+ try {
+ Assert.assertEquals(actual, expected);
+ } catch (AssertionError e) {
+ throw new ScriptAssertionException(e);
+ }
+ }
+
+ public void assertEquals(String actual, String expected, String msg) {
+ try {
+ Assert.assertEquals(actual, expected, msg);
+ } catch (AssertionError e) {
+ throw new ScriptAssertionException(e);
+ }
+ }
+
+ public void assertEquals(String actual, String expected) {
+ try {
+ Assert.assertEquals(actual, expected);
+ } catch (AssertionError e) {
+ throw new ScriptAssertionException(e);
+ }
+ }
+
+ public void assertEquals(double actual, double expected, double delta, String msg) {
+ try {
+ Assert.assertEquals(actual, expected, delta, msg);
+ } catch (AssertionError e) {
+ throw new ScriptAssertionException(e);
+ }
+ }
+
+ public void assertEquals(double actual, double expected, double delta) {
+ try {
+ Assert.assertEquals(actual, expected, delta);
+ } catch (AssertionError e) {
+ throw new ScriptAssertionException(e);
+ }
+ }
+
+ public void assertEquals(float actual, float expected, float delta, String msg) {
+ try {
+ Assert.assertEquals(actual, expected, delta, msg);
+ } catch (AssertionError e) {
+ throw new ScriptAssertionException(e);
+ }
+ }
+
+ public void assertEquals(float actual, float expected, float delta) {
+ try {
+ Assert.assertEquals(actual, expected, delta);
+ } catch (AssertionError e) {
+ throw new ScriptAssertionException(e);
+ }
+ }
+
+ public void assertEquals(long actual, long expected, String msg) {
+ try {
+ Assert.assertEquals(actual, expected, msg);
+ } catch (AssertionError e) {
+ throw new ScriptAssertionException(e);
+ }
+ }
+
+ public void assertEquals(long actual, long expected) {
+ try {
+ Assert.assertEquals(actual, expected);
+ } catch (AssertionError e) {
+ throw new ScriptAssertionException(e);
+ }
+ }
+
+ public void assertEquals(boolean actual, boolean expected, String msg) {
+ try {
+ Assert.assertEquals(actual, expected, msg);
+ } catch (AssertionError e) {
+ throw new ScriptAssertionException(e);
+ }
+ }
+
+ public void assertEquals(boolean actual, boolean expected) {
+ try {
+ Assert.assertEquals(actual, expected);
+ } catch (AssertionError e) {
+ throw new ScriptAssertionException(e);
+ }
+ }
+
+ public void assertEquals(byte actual, byte expected, String msg) {
+ try {
+ Assert.assertEquals(actual, expected, msg);
+ } catch (AssertionError e) {
+ throw new ScriptAssertionException(e);
+ }
+ }
+
+ public void assertEquals(byte actual, byte expected) {
+ try {
+ Assert.assertEquals(actual, expected);
+ } catch (AssertionError e) {
+ throw new ScriptAssertionException(e);
+ }
+ }
+
+ public void assertEquals(char actual, char expected, String msg) {
+ try {
+ Assert.assertEquals(actual, expected, msg);
+ } catch (AssertionError e) {
+ throw new ScriptAssertionException(e);
+ }
+ }
+
+ public void assertEquals(char actual, char expected) {
+ try {
+ Assert.assertEquals(actual, expected);
+ } catch (AssertionError e) {
+ throw new ScriptAssertionException(e);
+ }
+ }
+
+ public void assertEquals(short actual, short expected, String msg) {
+ try {
+ Assert.assertEquals(actual, expected, msg);
+ } catch(AssertionError e) {
+ throw new ScriptAssertionException(e);
+ }
+ }
+
+ public void assertEquals(short actual, short expected) {
+ try {
+ Assert.assertEquals(actual, expected);
+ } catch (AssertionError e) {
+ throw new ScriptAssertionException(e);
+ }
+ }
+
+ public void assertEquals(int actual, int expected, String msg) {
+ try {
+ Assert.assertEquals(actual, expected, msg);
+ } catch (AssertionError e) {
+ throw new ScriptAssertionException(e);
+ }
+ }
+
+ public void assertEquals(int actual, int expected) {
+ try {
+ Assert.assertEquals(actual, expected);
+ } catch (AssertionError e) {
+ throw new ScriptAssertionException(e);
+ }
+ }
+
+ public void assertNotNull(Object object) {
+ try {
+ Assert.assertNotNull(object);
+ } catch (AssertionError e) {
+ throw new ScriptAssertionException(e);
+ }
+ }
+
+ public void assertNotNull(Object object, String msg) {
+ try {
+ Assert.assertNotNull(object, msg);
+ } catch (AssertionError e) {
+ throw new ScriptAssertionException(e);
+ }
+ }
+
+ public void assertNull(Object object) {
+ try {
+ Assert.assertNull(object);
+ } catch (AssertionError e) {
+ throw new ScriptAssertionException(e);
+ }
+ }
+
+ public void assertNull(Object object, String msg) {
+ try {
+ Assert.assertNull(object, msg);
+ } catch (AssertionError e) {
+ throw new ScriptAssertionException(e);
+ }
+ }
+
+ public void assertSame(Object actual, Object expected, String msg) {
+ try {
+ Assert.assertSame(actual, expected, msg);
+ } catch (AssertionError e) {
+ throw new ScriptAssertionException(e);
+ }
+ }
+
+ public void assertSame(Object actual, Object expected) {
+ try {
+ Assert.assertSame(actual, expected);
+ } catch (AssertionError e) {
+ throw new ScriptAssertionException(e);
+ }
+ }
+
+ public void assertNotSame(Object actual, Object expected, String msg) {
+ try {
+ Assert.assertNotSame(actual, expected, msg);
+ } catch (AssertionError e) {
+ throw new ScriptAssertionException(e);
+ }
+ }
+
+ public void assertNotSame(Object actual, Object expected) {
+ try {
+ Assert.assertNotSame(actual, expected);
+ } catch (AssertionError e) {
+ throw new ScriptAssertionException(e);
+ }
+ }
+
+ public void assertEquals(Collection actual, Collection expected) {
+ try {
+ Assert.assertEquals(actual, expected);
+ } catch (AssertionError e) {
+ throw new ScriptAssertionException(e);
+ }
+ }
+
+ public void assertEquals(Collection actual, Collection expected, String msg) {
+ try {
+ Assert.assertEquals(actual, expected, msg);
+ } catch (AssertionError e) {
+ throw new ScriptAssertionException(e);
+ }
+ }
+
+ public void assertEquals(Object[] actual, Object[] expected, String msg) {
+ try {
+ Assert.assertEquals(actual, expected, msg);
+ } catch (AssertionError e) {
+ throw new ScriptAssertionException(e);
+ }
+ }
+
+ public void assertEqualsNoOrder(Object[] actual, Object[] expected, String msg) {
+ try {
+ Assert.assertEqualsNoOrder(actual, expected, msg);
+ } catch (AssertionError e) {
+ throw new ScriptAssertionException(e);
+ }
+ }
+
+ public void assertEquals(Object[] actual, Object[] expected) {
+ try {
+ Assert.assertEquals(actual, expected);
+ } catch (AssertionError e) {
+ throw new ScriptAssertionException(e);
+ }
+ }
+
+ public void assertEqualsNoOrder(Object[] actual, Object[] expected) {
+ try {
+ Assert.assertEqualsNoOrder(actual, expected);
+ } catch (AssertionError e) {
+ throw new ScriptAssertionException(e);
+ }
+ }
+
+ public void assertEquals(byte[] actual, byte[] expected) {
+ try {
+ Assert.assertEquals(actual, expected);
+ } catch (AssertionError e) {
+ throw new ScriptAssertionException(e);
+ }
+ }
+
+ public void assertEquals(byte[] actual, byte[] expected, String msg) {
+ try {
+ Assert.assertEquals(actual, expected, msg);
+ } catch (AssertionError e) {
+ throw new ScriptAssertionException(e);
+ }
+ }
+
+ public void assertExists(String identifier) {
+ assertNotNull(scriptEngine.get(identifier), identifier + " is not defined");
+ }
+
+ /**
+ * JavaScript has only a single numeric type such that <code>x = 1</code> and <code>y = 1.0</code> are considered to
+ * be of the same type. From within a (JavaScript) script if you were to call <code>assertEquals(x, y)</code>, you
+ * would get an exception that looks something like,
+ *
+ * <pre>
+ * Caused by: javax.script.ScriptException: sun.org.mozilla.javascript.internal.EvaluatorException: The choice of
+ * Java constructor assertEquals matching JavaScript argument types (number,number,string) is ambiguous;
+ * candidate constructors are:
+ * void assertEquals(java.lang.String,java.lang.String,java.lang.String)
+ * void assertEquals(double,double,double)
+ * void assertEquals(float,float,float)
+ * void assertEquals(long,long,java.lang.String)
+ * void assertEquals(byte,byte,java.lang.String)
+ * void assertEquals(char,char,java.lang.String)
+ * void assertEquals(short,short,java.lang.String)
+ * void assertEquals(int,int,java.lang.String) (<Unknown source>#1) in <Unknown source> at line number 1
+ </pre>
+ *
+ * To avoid the ambiguity when comparing numbers in JavaScript scripts, it is recommended to use this method.
+ *
+ * @param actual The actual value
+ * @param expected The expected value
+ * @param msg A useful, meaningful error message
+ */
+ public void assertNumberEqualsJS(double actual, double expected, String msg) {
+ assertEquals(actual, expected, msg);
+ }
+
+}
diff --git a/modules/enterprise/binding/src/main/java/org/rhq/bindings/util/ScriptAssertionException.java b/modules/enterprise/binding/src/main/java/org/rhq/bindings/util/ScriptAssertionException.java
new file mode 100644
index 0000000..f0305f3
--- /dev/null
+++ b/modules/enterprise/binding/src/main/java/org/rhq/bindings/util/ScriptAssertionException.java
@@ -0,0 +1,57 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2008 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.bindings.util;
+
+import javax.script.ScriptException;
+
+/**
+ * This is a wrapper exception class for {@link java.lang.AssertionError}. The default (i.e., rhino) scripting engine
+ * catches any exception, checked or unchecked, thrown from a script and wraps it in an instance of
+ * {@link javax.script.ScriptException}. ScriptException provides useful context information such as the script name
+ * and line number on which the exception occurred. For reasons unknown instances of {@link Error} are not caught and
+ * wrapped in a ScriptException; consequently, no context information is provided about the error, particularly, a line
+ * number.
+ */
+public class ScriptAssertionException extends RuntimeException {
+
+// public ScriptAssertionException() {
+// super();
+// }
+//
+// public ScriptAssertionException(String message) {
+// super(message);
+// }
+//
+// public ScriptAssertionException(String message, Throwable cause) {
+// super(message, cause);
+// }
+//
+// public ScriptAssertionException(Throwable cause) {
+// super(cause);
+// }
+
+ public ScriptAssertionException(AssertionError error) {
+ super(new ScriptException(error.getMessage()));
+ }
+}
diff --git a/modules/enterprise/binding/src/main/java/org/rhq/bindings/util/ScriptUtil.java b/modules/enterprise/binding/src/main/java/org/rhq/bindings/util/ScriptUtil.java
new file mode 100644
index 0000000..4e81e30
--- /dev/null
+++ b/modules/enterprise/binding/src/main/java/org/rhq/bindings/util/ScriptUtil.java
@@ -0,0 +1,181 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2009 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.bindings.util;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import javax.script.Bindings;
+import javax.script.ScriptContext;
+import javax.script.ScriptEngine;
+
+import org.rhq.bindings.StandardBindings;
+import org.rhq.bindings.client.RhqFacade;
+import org.rhq.core.domain.auth.Subject;
+import org.rhq.core.domain.criteria.ResourceCriteria;
+import org.rhq.core.domain.criteria.ResourceOperationHistoryCriteria;
+import org.rhq.core.domain.operation.OperationRequestStatus;
+import org.rhq.core.domain.operation.ResourceOperationHistory;
+import org.rhq.core.domain.operation.bean.ResourceOperationSchedule;
+import org.rhq.core.domain.resource.Resource;
+import org.rhq.core.domain.util.PageList;
+import org.rhq.core.domain.util.PageOrdering;
+import org.rhq.enterprise.server.resource.ResourceManagerRemote;
+
+/**
+ * Instance of this class is injected into the script engine scope.
+ *
+ * @author Lukas Krejci
+ */
+public class ScriptUtil {
+
+ private RhqFacade remoteClient;
+ private ScriptEngine scriptEngine;
+
+ public ScriptUtil(RhqFacade remoteClient) {
+ this.remoteClient = remoteClient;
+ }
+
+ /**
+ * This method is called before the instance is inserted into the script engine scope.
+ *
+ * @param scriptEngine the script engine this instance is to be injected in
+ */
+ public void init(ScriptEngine scriptEngine) {
+ this.scriptEngine = scriptEngine;
+ }
+
+ public PageList<Resource> findResources(String string) {
+ ResourceManagerRemote resourceManager = remoteClient.getResourceManager();
+
+ ResourceCriteria criteria = new ResourceCriteria();
+ criteria.addFilterName(string);
+ return resourceManager.findResourcesByCriteria(getSubjectFromEngine(), criteria);
+ }
+
+
+ public byte[] getFileBytes(String fileName) {
+ File file = new File(fileName);
+ long length = file.length();
+
+ if (length > Integer.MAX_VALUE) {
+ throw new IllegalArgumentException("Can not read file larger than " + Integer.MAX_VALUE + " byte: "
+ + fileName);
+ }
+
+ byte[] bytes;
+ InputStream is = null;
+ try {
+ bytes = new byte[(int) length];
+ is = new FileInputStream(file);
+
+ int offset = 0, bytesRead = 0;
+ for (offset = 0, bytesRead = 0; offset < bytes.length && bytesRead >= 0; offset += bytesRead) {
+ bytesRead = is.read(bytes, offset, bytes.length - offset);
+ }
+
+ if (offset < bytes.length) {
+ throw new RuntimeException("Could not read entire file " + file.getName() + ", only " + offset + " of "
+ + bytes.length + " bytes read");
+ }
+ } catch (IOException ioe) {
+ throw new RuntimeException("Error reading file: " + ioe.getMessage());
+ } finally {
+ try {
+ if (is != null) {
+ is.close();
+ }
+ } catch (IOException ioe) {
+ throw new RuntimeException("Error closing file: " + ioe.getMessage());
+ }
+ }
+ return bytes;
+ }
+
+ public void sleep(long millis) {
+ try {
+ Thread.sleep(millis);
+ } catch (InterruptedException ie) {
+ throw new RuntimeException(ie);
+ }
+ }
+
+ public ResourceOperationHistory waitForScheduledOperationToComplete(ResourceOperationSchedule schedule)
+ throws InterruptedException{
+
+ return waitForScheduledOperationToComplete(schedule, 1000L, 10);
+ }
+
+ public ResourceOperationHistory waitForScheduledOperationToComplete(ResourceOperationSchedule schedule,
+ long intervalDuration,
+ int maxIntervals) throws InterruptedException {
+ ResourceOperationHistoryCriteria criteria = new ResourceOperationHistoryCriteria();
+ criteria.addFilterJobId(schedule.getJobId());
+ criteria.addFilterResourceIds(schedule.getResource().getId());
+ criteria.addSortStartTime(PageOrdering.DESC);
+ criteria.setPaging(0, 1);
+ criteria.fetchOperationDefinition(true);
+ criteria.fetchParameters(true);
+ criteria.fetchResults(true);
+
+ ResourceOperationHistory history = null;
+
+ int i = 0;
+
+ while(history == null && i < maxIntervals) {
+ Thread.sleep(intervalDuration);
+ PageList<ResourceOperationHistory> histories = remoteClient.getOperationManager()
+ .findResourceOperationHistoriesByCriteria(remoteClient.getSubject(), criteria);
+ if (histories.size() > 0 && histories.get(0).getStatus() != OperationRequestStatus.INPROGRESS) {
+ history = histories.get(0);
+ }
+ ++i;
+ }
+
+ return history;
+ }
+
+ public boolean isDefined(String identifier) {
+ Bindings engineBindings = scriptEngine.getBindings(ScriptContext.ENGINE_SCOPE);
+ Bindings globalBindings = scriptEngine.getBindings(ScriptContext.GLOBAL_SCOPE);
+
+ return engineBindings.containsKey(identifier) || globalBindings.containsKey(identifier);
+ }
+
+ private Subject getSubjectFromEngine() {
+ return (Subject) findBinding(StandardBindings.SUBJECT);
+ }
+
+ private Object findBinding(String identifier) {
+ Bindings engineBindings = scriptEngine.getBindings(ScriptContext.ENGINE_SCOPE);
+ Bindings globalBindings = scriptEngine.getBindings(ScriptContext.GLOBAL_SCOPE);
+
+ if (engineBindings.containsKey(identifier)) {
+ return engineBindings.get(identifier);
+ } else {
+ return globalBindings.get(identifier);
+ }
+ }
+}
diff --git a/modules/enterprise/gui/base-perspective-jar/src/main/java/org/rhq/enterprise/server/perspective/AbstractPerspectiveResourceUIBean.java b/modules/enterprise/gui/base-perspective-jar/src/main/java/org/rhq/enterprise/server/perspective/AbstractPerspectiveResourceUIBean.java
index b6ea66c..9b18acb 100644
--- a/modules/enterprise/gui/base-perspective-jar/src/main/java/org/rhq/enterprise/server/perspective/AbstractPerspectiveResourceUIBean.java
+++ b/modules/enterprise/gui/base-perspective-jar/src/main/java/org/rhq/enterprise/server/perspective/AbstractPerspectiveResourceUIBean.java
@@ -37,7 +37,7 @@ public class AbstractPerspectiveResourceUIBean extends AbstractPerspectiveUIBean
Subject subject = this.perspectiveClient.getSubject();
// ***NOTE***: The javassist.NotFoundException stack traces that are logged by this call can be ignored.
- ResourceManagerRemote resourceManager = remoteClient.getResourceManagerRemote();
+ ResourceManagerRemote resourceManager = remoteClient.getResourceManager();
ResourceCriteria resourceCriteria = new ResourceCriteria();
resourceCriteria.addFilterId(this.rhqResourceId);
PageList<Resource> resources = resourceManager.findResourcesByCriteria(subject, resourceCriteria);
diff --git a/modules/enterprise/gui/base-perspective-jar/src/main/java/org/rhq/enterprise/server/perspective/PerspectiveClientUIBean.java b/modules/enterprise/gui/base-perspective-jar/src/main/java/org/rhq/enterprise/server/perspective/PerspectiveClientUIBean.java
index 45437d7..9f91c88 100644
--- a/modules/enterprise/gui/base-perspective-jar/src/main/java/org/rhq/enterprise/server/perspective/PerspectiveClientUIBean.java
+++ b/modules/enterprise/gui/base-perspective-jar/src/main/java/org/rhq/enterprise/server/perspective/PerspectiveClientUIBean.java
@@ -87,7 +87,7 @@ public class PerspectiveClientUIBean {
if (subject == null) {
RemoteClient remoteClient = getRemoteClient();
// ***NOTE***: The javassist.NotFoundException stack traces that are logged by this call can be ignored.
- SubjectManagerRemote subjectManager = remoteClient.getSubjectManagerRemote();
+ SubjectManagerRemote subjectManager = remoteClient.getSubjectManager();
if (this.rhqSessionId != null) {
log.info("Retrieving subject for user [" + getUsername() + "] and sessionId [" + this.rhqSessionId
+ "]...");
@@ -108,7 +108,7 @@ public class PerspectiveClientUIBean {
if (this.coreGuiBaseUrl == null) {
RemoteClient remoteClient = getRemoteClient();
Subject subject = getSubject();
- PerspectiveManagerRemote perspectiveManager = remoteClient.getPerspectiveManagerRemote();
+ PerspectiveManagerRemote perspectiveManager = remoteClient.getPerspectiveManager();
this.coreGuiBaseUrl = perspectiveManager.getRootUrl(subject, true, false);
}
return this.coreGuiBaseUrl;
diff --git a/modules/enterprise/pom.xml b/modules/enterprise/pom.xml
index 7e20613..bfd912f 100644
--- a/modules/enterprise/pom.xml
+++ b/modules/enterprise/pom.xml
@@ -71,6 +71,7 @@
<module>server/jar</module>
<module>server/safe-invoker</module>
<module>server/sars</module>
+ <module>binding</module>
<module>remoting</module>
<module>gui</module>
<module>server/plugins</module>
diff --git a/modules/enterprise/remoting/cli/pom.xml b/modules/enterprise/remoting/cli/pom.xml
index cab4a8c..f55dbb4 100644
--- a/modules/enterprise/remoting/cli/pom.xml
+++ b/modules/enterprise/remoting/cli/pom.xml
@@ -33,7 +33,13 @@
<artifactId>rhq-remoting-client-api</artifactId>
<version>${project.version}</version>
</dependency>
-
+
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>rhq-script-bindings</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
<dependency>
<groupId>${groupId}</groupId>
<artifactId>rhq-core-domain</artifactId>
diff --git a/modules/enterprise/remoting/cli/src/main/java/org/rhq/enterprise/client/commands/LoginCommand.java b/modules/enterprise/remoting/cli/src/main/java/org/rhq/enterprise/client/commands/LoginCommand.java
index d8344ff..95b1a8f 100644
--- a/modules/enterprise/remoting/cli/src/main/java/org/rhq/enterprise/client/commands/LoginCommand.java
+++ b/modules/enterprise/remoting/cli/src/main/java/org/rhq/enterprise/client/commands/LoginCommand.java
@@ -27,6 +27,7 @@ import org.apache.commons.logging.LogFactory;
import org.rhq.core.domain.auth.Subject;
import org.rhq.enterprise.client.ClientMain;
import org.rhq.enterprise.client.RemoteClient;
+import org.rhq.enterprise.server.system.ServerVersion;
/**
* @author Greg Hinkle
@@ -103,6 +104,8 @@ public class LoginCommand implements ClientCommand {
client.setPass(password);
Subject subject = remoteClient.login(username, password);
+ ServerVersion version = remoteClient.getSystemManager().getServerVersion(subject);
+ client.getPrintWriter().println("Remote server version is: " + version);
client.setRemoteClient(remoteClient);
client.setSubject(subject);
diff --git a/modules/enterprise/remoting/cli/src/main/java/org/rhq/enterprise/client/commands/ScriptCommand.java b/modules/enterprise/remoting/cli/src/main/java/org/rhq/enterprise/client/commands/ScriptCommand.java
index ca3a185..8f64679 100644
--- a/modules/enterprise/remoting/cli/src/main/java/org/rhq/enterprise/client/commands/ScriptCommand.java
+++ b/modules/enterprise/remoting/cli/src/main/java/org/rhq/enterprise/client/commands/ScriptCommand.java
@@ -18,53 +18,47 @@
*/
package org.rhq.enterprise.client.commands;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.util.Arrays;
+
+import javax.script.ScriptContext;
+import javax.script.ScriptEngine;
+import javax.script.ScriptException;
+
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-import org.rhq.bindings.export.Exporter;
+import org.rhq.bindings.ScriptEngineFactory;
+import org.rhq.bindings.StandardBindings;
+import org.rhq.bindings.client.RhqManagers;
import org.rhq.bindings.output.TabularWriter;
import org.rhq.bindings.util.PackageFinder;
-import org.rhq.core.domain.util.PageControl;
import org.rhq.enterprise.client.ClientMain;
import org.rhq.enterprise.client.Controller;
-import org.rhq.enterprise.client.RemoteClient;
-import org.rhq.enterprise.client.proxy.ResourceClientFactory;
import org.rhq.enterprise.client.proxy.ConfigurationEditor;
+import org.rhq.enterprise.client.proxy.EditableResourceClientFactory;
import org.rhq.enterprise.client.script.CLIScriptException;
import org.rhq.enterprise.client.script.CmdLineParser;
import org.rhq.enterprise.client.script.CommandLineParseException;
import org.rhq.enterprise.client.script.NamedScriptArg;
import org.rhq.enterprise.client.script.ScriptArg;
import org.rhq.enterprise.client.script.ScriptCmdLine;
-import org.rhq.enterprise.client.utility.ScriptAssert;
-import org.rhq.enterprise.client.utility.ScriptUtil;
-
-import javax.script.ScriptContext;
-import javax.script.ScriptEngine;
-import javax.script.ScriptEngineManager;
-import javax.script.ScriptException;
-import java.beans.BeanInfo;
-import java.beans.IntrospectionException;
-import java.beans.Introspector;
-import java.beans.MethodDescriptor;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileReader;
-import java.io.InputStream;
-import java.io.Reader;
-import java.io.InputStreamReader;
-import java.lang.reflect.Method;
-import java.util.Arrays;
-import java.util.List;
/**
* @author Greg Hinkle
+ * @author Lukas Krejci
*/
public class ScriptCommand implements ClientCommand {
- private ScriptEngineManager sem;
private ScriptEngine jsEngine;
-
+ private StandardBindings bindings;
+
private final Log log = LogFactory.getLog(ScriptCommand.class);
private StringBuilder script = new StringBuilder();
@@ -72,37 +66,6 @@ public class ScriptCommand implements ClientCommand {
private boolean isMultilineScript = false;
private boolean inMultilineScript = false;
- public ScriptCommand() {
- sem = new ScriptEngineManager();
- PageControl pc = new PageControl();
- pc.setPageNumber(-1);
- sem.getBindings().put("unlimitedPC", pc);
- sem.getBindings().put("pageControl", PageControl.getUnlimitedInstance());
- sem.put("exporter", new Exporter());
- jsEngine = sem.getEngineByName("JavaScript");
- try {
- jsEngine.eval("1+1");
- } catch (ScriptException e) {
- e.printStackTrace();
- }
- importRecursive(jsEngine);
- }
-
- private void importRecursive(ScriptEngine jsEngine) {
-
- try {
-
- List<String> packages = new PackageFinder().findPackages("org.rhq.core.domain");
-
- for (String pkg : packages) {
- jsEngine.eval("importPackage(" + pkg + ")");
- }
- } catch (ScriptException e) {
- e.printStackTrace();
- }
-
- }
-
public ScriptEngine getScriptEngine() {
return jsEngine;
}
@@ -197,60 +160,31 @@ public class ScriptCommand implements ClientCommand {
}
public void initBindings(ClientMain client) {
- // These are prepared on every call in case the user logs out and logs into another server
- if (client.getSubject() != null) {
- jsEngine.put("subject", client.getSubject());
- sem.getBindings().putAll(client.getRemoteClient().getManagers());
- }
- TabularWriter tw = new TabularWriter(client.getPrintWriter());
- tw.setWidth(client.getConsoleWidth());
- sem.getBindings().put("pretty", tw);
-
- sem.getBindings().put("ProxyFactory", new ResourceClientFactory(client));
-
- bindObjectAndGlobalFuctions(new Controller(client), "rhq");
- bindObjectAndGlobalFuctions(new ScriptUtil(client), "scriptUtil");
- bindObjectAndGlobalFuctions(new ConfigurationEditor(client), "configurationEditor");
- bindObjectAndGlobalFuctions(new ScriptAssert(jsEngine), "Assert");
- }
-
- private void bindObjectAndGlobalFuctions(Object object, String bindingName) {
- jsEngine.put(bindingName, object);
- try {
- BeanInfo beanInfo = Introspector.getBeanInfo(object.getClass(),Object.class);
- MethodDescriptor[] methodDescriptors = beanInfo.getMethodDescriptors();
-
- for (MethodDescriptor methodDescriptor : methodDescriptors) {
- Method method = methodDescriptor.getMethod();
- String methodName = method.getName();
- int argCount = method.getParameterTypes().length;
-
- StringBuilder functionBuilder = new StringBuilder();
- functionBuilder.append(methodName).append("(");
- for (int i = 0; i < argCount; ++i) {
- if (i != 0) {
- functionBuilder.append(", ");
- }
- functionBuilder.append("arg_" + i);
- }
- functionBuilder.append(")");
- String functionFragment = functionBuilder.toString();
- boolean returnsVoid = method.getReturnType().equals(Void.TYPE);
-
- String functionDefinition = "function " + functionFragment + " { " + (returnsVoid ? "" : "return ")
- + bindingName + "." + functionFragment + "; }";
-
- log.info("Binding global function --> " + functionDefinition);
- try {
- jsEngine.eval(functionDefinition);
- } catch (ScriptException e) {
- log.warn("Unable to bind global function " + functionFragment, e);
- }
+ if (jsEngine == null) {
+ bindings = new StandardBindings(client.getPrintWriter(), client.getRemoteClient());
+
+ try {
+ jsEngine = ScriptEngineFactory.getScriptEngine("JavaScript", new PackageFinder(Arrays.asList(getLibDir())), bindings);
+ jsEngine.eval("1+1");
+ } catch (ScriptException e) {
+ e.printStackTrace();
+ } catch (IOException e) {
+ e.printStackTrace();
}
- } catch (IntrospectionException e) {
- // TODO Should we altogether remove the object from the script engine bindings?
- log.warn("Could not bind " + object.getClass().getName() + " into script engine.");
}
+
+ bindings.getSubject().setValue(client.getSubject());
+ bindings.getPretty().getValue().setWidth(client.getConsoleWidth());
+ bindings.getProxyFactory().setValue(new EditableResourceClientFactory(client));
+
+ //non-standard bindings
+ bindings.put("configurationEditor", new ConfigurationEditor(client));
+ bindings.put("rhq", new Controller(client));
+
+ ScriptEngineFactory.injectStandardBindings(jsEngine, bindings);
+
+ ScriptEngineFactory.bindIndirectionMethods(jsEngine, "configurationEditor", bindings.get("configurationEditor"));
+ ScriptEngineFactory.bindIndirectionMethods(jsEngine, "configurationEditor", bindings.get("configurationEditor"));
}
private void executeUtilScripts() {
@@ -337,11 +271,15 @@ public class ScriptCommand implements ClientCommand {
public String getDetailedHelp() {
return "Execute a statement or a script. The following services managers are available: " +
- RemoteClient.Manager.values();
+ RhqManagers.values();
}
public ScriptContext getContext() {
return jsEngine.getContext();
}
+ private File getLibDir() {
+ String cwd = System.getProperty("user.dir");
+ return new File(cwd, "lib");
+ }
}
diff --git a/modules/enterprise/remoting/cli/src/main/java/org/rhq/enterprise/client/proxy/EditableResourceClientFactory.java b/modules/enterprise/remoting/cli/src/main/java/org/rhq/enterprise/client/proxy/EditableResourceClientFactory.java
new file mode 100644
index 0000000..1027878
--- /dev/null
+++ b/modules/enterprise/remoting/cli/src/main/java/org/rhq/enterprise/client/proxy/EditableResourceClientFactory.java
@@ -0,0 +1,61 @@
+/*
+ * 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 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.client.proxy;
+
+import java.util.List;
+
+import javassist.util.proxy.MethodHandler;
+
+import org.rhq.bindings.client.ResourceClientFactory;
+import org.rhq.bindings.client.ResourceClientProxy;
+import org.rhq.bindings.client.RhqFacade;
+import org.rhq.enterprise.client.ClientMain;
+
+/**
+ * This is a specialization of the {@link ResourceClientFactory} class that provides the interactive
+ * configuration editing features.
+ *
+ * @author Lukas Krejci
+ */
+public class EditableResourceClientFactory extends ResourceClientFactory {
+
+ private ClientMain client;
+
+ public EditableResourceClientFactory(ClientMain client) {
+ super(client.getRemoteClient(), client.getPrintWriter());
+ this.client = client;
+ }
+
+ @Override
+ protected Class<?> getPluginConfigurableInterface() {
+ return org.rhq.enterprise.client.proxy.EditableResourceClientProxy.EditablePluginConfigurable.class;
+ }
+
+ @Override
+ protected Class<?> getResourceConfigurableInterface() {
+ return org.rhq.enterprise.client.proxy.EditableResourceClientProxy.EditableResourceConfigurable.class;
+ }
+
+ @Override
+ protected MethodHandler instantiateMethodHandler(ResourceClientProxy proxy, List<Class<?>> interfaces,
+ RhqFacade remoteClient) {
+ return new EditableResourceClientProxy.MethodHandler(proxy, remoteClient, client);
+ }
+}
diff --git a/modules/enterprise/remoting/cli/src/main/java/org/rhq/enterprise/client/proxy/EditableResourceClientProxy.java b/modules/enterprise/remoting/cli/src/main/java/org/rhq/enterprise/client/proxy/EditableResourceClientProxy.java
new file mode 100644
index 0000000..367a750
--- /dev/null
+++ b/modules/enterprise/remoting/cli/src/main/java/org/rhq/enterprise/client/proxy/EditableResourceClientProxy.java
@@ -0,0 +1,67 @@
+/*
+ * 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 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.client.proxy;
+
+import org.rhq.bindings.client.ResourceClientProxy;
+import org.rhq.bindings.client.RhqFacade;
+import org.rhq.core.domain.configuration.Configuration;
+import org.rhq.enterprise.client.ClientMain;
+import org.rhq.enterprise.client.RemoteClient;
+
+/**
+ * Extends the {@link ResourceClientProxy} and provides the interactive configuration editing features.
+ *
+ * @author Lukas Krejci
+ */
+public class EditableResourceClientProxy extends ResourceClientProxy {
+
+ public interface EditableResourceConfigurable extends ResourceClientProxy.ResourceConfigurable {
+ void editResourceConfiguration();
+ }
+
+ public interface EditablePluginConfigurable extends ResourceClientProxy.PluginConfigurable {
+ public void editPluginConfiguration();
+ }
+
+ public static class MethodHandler extends ResourceClientProxy.ClientProxyMethodHandler implements EditableResourceConfigurable, EditablePluginConfigurable {
+
+ private ClientMain client;
+ public MethodHandler(ResourceClientProxy resourceClientProxy, RhqFacade remoteClient, ClientMain client) {
+ super(resourceClientProxy, remoteClient);
+ this.client = client;
+ }
+
+ public void editPluginConfiguration() {
+ ConfigurationEditor editor = new ConfigurationEditor(client);
+ Configuration config = editor.editConfiguration(getPluginConfigurationDefinition(), getPluginConfiguration());
+ if (config != null) {
+ updatePluginConfiguration(config);
+ }
+ }
+
+ public void editResourceConfiguration() {
+ ConfigurationEditor editor = new ConfigurationEditor(client);
+ Configuration config = editor.editConfiguration(getResourceConfigurationDefinition(), getResourceConfiguration());
+ if (config != null) {
+ updateResourceConfiguration(config);
+ }
+ }
+ }
+}
diff --git a/modules/enterprise/remoting/cli/src/main/java/org/rhq/enterprise/client/proxy/ResourceClientFactory.java b/modules/enterprise/remoting/cli/src/main/java/org/rhq/enterprise/client/proxy/ResourceClientFactory.java
deleted file mode 100644
index bbde2ed..0000000
--- a/modules/enterprise/remoting/cli/src/main/java/org/rhq/enterprise/client/proxy/ResourceClientFactory.java
+++ /dev/null
@@ -1,134 +0,0 @@
-package org.rhq.enterprise.client.proxy;
-
-import javassist.ClassPool;
-import javassist.CtNewMethod;
-import javassist.bytecode.ParameterAnnotationsAttribute;
-import org.rhq.enterprise.client.ClientMain;
-import org.rhq.enterprise.client.utility.ConfigurationClassBuilder;
-import org.rhq.core.domain.resource.ResourceCreationDataType;
-
-/**
- *
- * @author Greg Hinkle
- */
-public class ResourceClientFactory {
-
- private ClientMain clientMain;
-
- private org.rhq.enterprise.client.RemoteClient remoteClient;
-
- public ResourceClientFactory(ClientMain clientMain) {
- this.clientMain = clientMain;
- this.remoteClient = clientMain.getRemoteClient();
- }
-
- private static java.util.concurrent.atomic.AtomicInteger classIndex = new java.util.concurrent.atomic.AtomicInteger();
-
- public org.rhq.enterprise.client.proxy.ResourceClientProxy getResource(int resourceId) {
-
- org.rhq.enterprise.client.proxy.ResourceClientProxy proxy = new org.rhq.enterprise.client.proxy.ResourceClientProxy(clientMain, resourceId);
- java.lang.Class customInterface = null;
- try {
- // define the dynamic class
- javassist.ClassPool pool = ClassPool.getDefault();
- javassist.CtClass customClass = pool.makeInterface(org.rhq.enterprise.client.proxy.ResourceClientProxy.class.getName() + "__Custom__"
- + classIndex.getAndIncrement());
-
- for (java.lang.String key : proxy.allProperties.keySet()) {
- java.lang.Object prop = proxy.allProperties.get(key);
-
- if (prop instanceof org.rhq.enterprise.client.proxy.ResourceClientProxy.Measurement) {
- org.rhq.enterprise.client.proxy.ResourceClientProxy.Measurement m = (org.rhq.enterprise.client.proxy.ResourceClientProxy.Measurement) prop;
- java.lang.String name = org.rhq.enterprise.client.proxy.ResourceClientProxy.getterName(key);
-
- try {
- org.rhq.enterprise.client.proxy.ResourceClientProxy.class.getMethod(name);
- } catch (java.lang.NoSuchMethodException nsme) {
- javassist.CtMethod method = CtNewMethod.abstractMethod(pool.get(org.rhq.enterprise.client.proxy.ResourceClientProxy.Measurement.class.getName()),
- org.rhq.enterprise.client.proxy.ResourceClientProxy.getterName(key), new javassist.CtClass[0], new javassist.CtClass[0], customClass);
- customClass.addMethod(method);
- }
- } else if (prop instanceof org.rhq.enterprise.client.proxy.ResourceClientProxy.Operation) {
- org.rhq.enterprise.client.proxy.ResourceClientProxy.Operation o = (org.rhq.enterprise.client.proxy.ResourceClientProxy.Operation) prop;
-
- java.util.LinkedHashMap<java.lang.String, javassist.CtClass> types = ConfigurationClassBuilder.translateParameters(o
- .getDefinition().getParametersConfigurationDefinition());
-
- javassist.CtClass[] params = new javassist.CtClass[types.size()];
- int x = 0;
- for (java.lang.String param : types.keySet()) {
- params[x++] = types.get(param);
- }
-
- javassist.CtMethod method = CtNewMethod.abstractMethod(ConfigurationClassBuilder.translateConfiguration(o
- .getDefinition().getResultsConfigurationDefinition()), org.rhq.enterprise.client.proxy.ResourceClientProxy.simpleName(key), params,
- new javassist.CtClass[0], customClass);
-
- // Setup @WebParam annotations so the signatures have the config prop names
- javassist.bytecode.annotation.Annotation[][] newAnnotations = new javassist.bytecode.annotation.Annotation[params.length][1];
- int i = 0;
- for (java.lang.String paramName : types.keySet()) {
- newAnnotations[i] = new javassist.bytecode.annotation.Annotation[1];
-
- newAnnotations[i][0] = new javassist.bytecode.annotation.Annotation(javax.jws.WebParam.class.getName(), method.getMethodInfo()
- .getConstPool());
- newAnnotations[i][0].addMemberValue("name", new javassist.bytecode.annotation.StringMemberValue(paramName, method
- .getMethodInfo().getConstPool()));
- i++;
- }
-
- javassist.bytecode.ParameterAnnotationsAttribute newAnnotationsAttribute = new javassist.bytecode.ParameterAnnotationsAttribute(
- method.getMethodInfo().getConstPool(), ParameterAnnotationsAttribute.visibleTag);
- newAnnotationsAttribute.setAnnotations(newAnnotations);
- method.getMethodInfo().addAttribute(newAnnotationsAttribute);
-
- customClass.addMethod(method);
- }
- }
-
- customInterface = customClass.toClass();
- } catch (javassist.NotFoundException e) {
- e.printStackTrace();
- } catch (javassist.CannotCompileException e) {
- e.printStackTrace();
- } catch (java.lang.Exception e) {
- e.printStackTrace();
- }
-
- if (customInterface != null) {
-
- java.util.List<java.lang.Class> interfaces = new java.util.ArrayList<java.lang.Class>();
- interfaces.add(customInterface);
- if (proxy.resourceConfigurationDefinition != null) {
- interfaces.add(org.rhq.enterprise.client.proxy.ResourceClientProxy.ResourceConfigurable.class);
- }
- if (proxy.pluginConfigurationDefinition != null) {
- interfaces.add(org.rhq.enterprise.client.proxy.ResourceClientProxy.PluginConfigurable.class);
- }
-
- if (proxy.getResourceType().getCreationDataType() == ResourceCreationDataType.CONTENT) {
- interfaces.add(org.rhq.enterprise.client.proxy.ResourceClientProxy.ContentBackedResource.class);
- }
-
- javassist.util.proxy.ProxyFactory proxyFactory = new javassist.util.proxy.ProxyFactory();
- proxyFactory.setInterfaces(interfaces.toArray(new java.lang.Class[interfaces.size()]));
- proxyFactory.setSuperclass(org.rhq.enterprise.client.proxy.ResourceClientProxy.class);
- org.rhq.enterprise.client.proxy.ResourceClientProxy proxied = null;
- try {
- proxied = (org.rhq.enterprise.client.proxy.ResourceClientProxy) proxyFactory.create(new java.lang.Class[]{}, new java.lang.Object[]{},
- new org.rhq.enterprise.client.proxy.ResourceClientProxy.ClientProxyMethodHandler(proxy, remoteClient));
- } catch (java.lang.InstantiationException e) {
- e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
- } catch (java.lang.IllegalAccessException e) {
- e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
- } catch (java.lang.NoSuchMethodException e) {
- e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
- } catch (java.lang.reflect.InvocationTargetException e) {
- e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
- }
- return proxied;
- }
- return proxy;
-
- }
-}
diff --git a/modules/enterprise/remoting/cli/src/main/java/org/rhq/enterprise/client/proxy/ResourceClientProxy.java b/modules/enterprise/remoting/cli/src/main/java/org/rhq/enterprise/client/proxy/ResourceClientProxy.java
deleted file mode 100644
index 5b21a94..0000000
--- a/modules/enterprise/remoting/cli/src/main/java/org/rhq/enterprise/client/proxy/ResourceClientProxy.java
+++ /dev/null
@@ -1,669 +0,0 @@
-/*
- * RHQ Management Platform
- * Copyright (C) 2005-2008 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.client.proxy;
-
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-
-import javassist.util.proxy.MethodHandler;
-
-import org.rhq.bindings.util.LazyLoadScenario;
-import org.rhq.bindings.util.ShortOutput;
-import org.rhq.core.domain.configuration.Configuration;
-import org.rhq.core.domain.configuration.ResourceConfigurationUpdate;
-import org.rhq.core.domain.configuration.PluginConfigurationUpdate;
-import org.rhq.core.domain.configuration.definition.ConfigurationDefinition;
-import org.rhq.core.domain.content.InstalledPackage;
-import org.rhq.core.domain.content.PackageType;
-import org.rhq.core.domain.content.PackageVersion;
-import org.rhq.core.domain.criteria.MeasurementDefinitionCriteria;
-import org.rhq.core.domain.criteria.OperationDefinitionCriteria;
-import org.rhq.core.domain.criteria.PackageVersionCriteria;
-import org.rhq.core.domain.criteria.ResourceCriteria;
-import org.rhq.core.domain.criteria.ResourceOperationHistoryCriteria;
-import org.rhq.core.domain.measurement.DataType;
-import org.rhq.core.domain.measurement.MeasurementCategory;
-import org.rhq.core.domain.measurement.MeasurementData;
-import org.rhq.core.domain.measurement.MeasurementDefinition;
-import org.rhq.core.domain.measurement.MeasurementUnits;
-import org.rhq.core.domain.operation.OperationDefinition;
-import org.rhq.core.domain.operation.OperationRequestStatus;
-import org.rhq.core.domain.operation.ResourceOperationHistory;
-import org.rhq.core.domain.resource.Resource;
-import org.rhq.core.domain.resource.ResourceType;
-import org.rhq.core.domain.util.PageList;
-import org.rhq.core.domain.util.PageOrdering;
-import org.rhq.core.domain.util.Summary;
-import org.rhq.core.server.MeasurementConverter;
-import org.rhq.enterprise.client.RemoteClient;
-import org.rhq.enterprise.client.ClientMain;
-import org.rhq.enterprise.client.utility.ConfigurationClassBuilder;
-import org.rhq.enterprise.client.utility.ScriptUtil;
-import org.rhq.enterprise.server.content.ContentManagerRemote;
-import org.rhq.core.domain.operation.bean.ResourceOperationSchedule;
-import org.rhq.enterprise.server.resource.ResourceTypeNotFoundException;
-
-/**
- * Implements a local object that exposes resource related data as
- * if it were local.
- *
- * @author Greg Hinkle
- */
-public class ResourceClientProxy {
-
- private ClientMain client;
- private RemoteClient remoteClient;
- private int resourceId;
- private Resource resource;
-
- Map<String, Object> allProperties = new HashMap<String, Object>();
-
- // Metadata
- private List<MeasurementDefinition> measurementDefinitions;
- private Map<String, Measurement> measurementMap = new HashMap<String, Measurement>();
-
- private List<OperationDefinition> operationDefinitions;
- private Map<String, Operation> operationMap = new HashMap<String, Operation>();
-
- private Map<String, ContentType> contentTypes = new HashMap<String, ContentType>();
-
- private List<ResourceClientProxy> children;
- ConfigurationDefinition resourceConfigurationDefinition;
- ConfigurationDefinition pluginConfigurationDefinition;
-
- public ResourceClientProxy() {
- }
-
- public ResourceClientProxy(ResourceClientProxy parentProxy) {
- this.client = parentProxy.client;
- this.remoteClient = parentProxy.remoteClient;
- this.resourceId = parentProxy.resourceId;
- this.resource = parentProxy.resource;
- this.allProperties = parentProxy.allProperties;
- this.measurementDefinitions = parentProxy.measurementDefinitions;
- this.measurementMap = parentProxy.measurementMap;
- this.children = parentProxy.children;
-
- }
-
- public ResourceClientProxy(ClientMain clientMain, int resourceId) {
- this.client = clientMain;
- this.remoteClient = client.getRemoteClient();
- this.resourceId = resourceId;
-
- init();
- }
-
- @Summary(index = 0)
- public int getId() {
- return resourceId;
- }
-
- @Summary(index = 1)
- public String getName() {
- return resource.getName();
- }
-
- public String getDescription() {
- return resource.getDescription();
- }
-
- @Summary(index = 2)
- public String getVersion() {
- return resource.getVersion();
- }
-
- @Summary(index = 3)
- public ResourceType getResourceType() {
- return resource.getResourceType();
- }
-
- public Date getCreatedDate() {
- return new Date(resource.getCtime());
- }
-
- public Date getModifiedDate() {
- return new Date(resource.getCtime());
- }
-
- public Measurement getMeasurement(String name) {
- return this.measurementMap.get(name);
- }
-
- public Measurement[] getMeasurements() {
- return this.measurementMap.values().toArray(new Measurement[this.measurementMap.size()]);
- }
-
- public Operation[] getOperations() {
- return this.operationMap.values().toArray(new Operation[this.operationMap.size()]);
- }
-
- public Map<String, ContentType> getContentTypes() {
- return contentTypes;
- }
-
- public ResourceClientProxy[] getChildren() {
- if (children == null && LazyLoadScenario.isShouldLoad()) {
- children = new ArrayList<ResourceClientProxy>();
-
- initChildren();
-
- }
- return children.toArray(new ResourceClientProxy[children.size()]);
- }
-
- public ResourceClientProxy getChild(String name) {
- for (ResourceClientProxy child : getChildren()) {
- if (name.equals(child.getName()))
- return child;
- }
- return null;
- }
-
- public String toString() {
- return "[" + resourceId + "] " + resource.getName() + " (" + resource.getResourceType().getName() + "::"
- + resource.getResourceType().getPlugin() + ")";
- }
-
- public void init() {
-
- this.resource = remoteClient.getResourceManagerRemote().getResource(remoteClient.getSubject(), resourceId);
-
- // Lazy init children, not here
- initMeasurements();
- initOperations();
- initConfigDefs();
- initContent();
- }
-
- private void initConfigDefs() {
- this.resourceConfigurationDefinition = remoteClient.getConfigurationManagerRemote()
- .getResourceConfigurationDefinitionWithTemplatesForResourceType(remoteClient.getSubject(),
- resource.getResourceType().getId());
- this.pluginConfigurationDefinition = remoteClient.getConfigurationManagerRemote()
- .getPluginConfigurationDefinitionForResourceType(remoteClient.getSubject(),
- resource.getResourceType().getId());
- }
-
- private void initChildren() {
- ResourceCriteria criteria = new ResourceCriteria();
- criteria.addFilterParentResourceId(resourceId);
- PageList<Resource> childResources = remoteClient.getResourceManagerRemote().findResourcesByCriteria(
- remoteClient.getSubject(), criteria);
-
- for (Resource child : childResources) {
- this.children.add(new ResourceClientFactory(client).getResource(child.getId()));
- }
- }
-
- private void initMeasurements() {
- MeasurementDefinitionCriteria criteria = new MeasurementDefinitionCriteria();
- criteria.addFilterResourceTypeId(resource.getResourceType().getId());
-// criteria.addFilterResourceTypeName(resource.getResourceType().getName());
-// criteria.setStrict(true);
-
- this.measurementDefinitions = remoteClient.getMeasurementDefinitionManagerRemote()
- .findMeasurementDefinitionsByCriteria(remoteClient.getSubject(), criteria);
-
- this.measurementMap = new HashMap<String, Measurement>();
- for (MeasurementDefinition def : measurementDefinitions) {
- Measurement m = new Measurement(def);
-
- String name = def.getDisplayName().replaceAll("\\W", "");
- name = decapitalize(name);
-
- this.measurementMap.put(name, m);
- this.allProperties.put(name, m);
- }
- }
-
- public void initOperations() {
- OperationDefinitionCriteria criteria = new OperationDefinitionCriteria();
- criteria.addFilterResourceIds(resourceId);
- criteria.fetchParametersConfigurationDefinition(true);
- criteria.fetchResultsConfigurationDefinition(true);
-
- this.operationDefinitions = remoteClient.getOperationManagerRemote().findOperationDefinitionsByCriteria(
- remoteClient.getSubject(), criteria);
-
- for (OperationDefinition def : operationDefinitions) {
- Operation o = new Operation(def);
- this.operationMap.put(o.getName(), o);
- this.allProperties.put(o.getName(), o);
- }
- }
-
- private void initContent() {
- ContentManagerRemote contentManager = remoteClient.getContentManagerRemote();
- List<PackageType> types = null;
- try {
- types = contentManager.findPackageTypes(remoteClient.getSubject(), resource.getResourceType().getName(),
- resource.getResourceType().getPlugin());
-
- for (PackageType packageType : types) {
- contentTypes.put(packageType.getName(), new ContentType(packageType));
- }
- } catch (ResourceTypeNotFoundException e) {
- e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
- }
-
- }
-
- public class ContentType {
-
- private PackageType packageType;
-
- public ContentType(PackageType packageType) {
- this.packageType = packageType;
- }
-
- public PackageType getPackageType() {
- return this.packageType;
- }
-
- public List<PackageVersion> getInstalledPackages() {
- ContentManagerRemote contentManager = remoteClient.getContentManagerRemote();
-
- PackageVersionCriteria criteria = new PackageVersionCriteria();
- criteria.addFilterResourceId(resourceId);
- // criteria.addFilterPackageTypeId() TODO ADD this when the filter is added
-
- return contentManager.findPackageVersionsByCriteria(remoteClient.getSubject(), criteria);
- }
-
- public String toString() {
- return this.packageType.getDisplayName();
- }
-
- }
-
- public class Measurement implements ShortOutput {
-
- MeasurementDefinition definition;
-
- public Measurement(MeasurementDefinition definition) {
- this.definition = definition;
- }
-
- @Summary(index = 0)
- public String getName() {
- return definition.getDisplayName();
- }
-
- @Summary(index = 1)
- public String getDisplayValue() {
- Object val = getValue();
- if (val instanceof Number) {
- return MeasurementConverter.format(((Number) val).doubleValue(), getUnits(), true);
- } else {
- return String.valueOf(val);
- }
- }
-
- @Summary(index = 2)
- public String getDescription() {
- return definition.getDescription();
- }
-
- public DataType getDataType() {
- return definition.getDataType();
- }
-
- public MeasurementCategory getCategory() {
- return definition.getCategory();
- }
-
- public MeasurementUnits getUnits() {
- return definition.getUnits();
- }
-
- public Object getValue() {
- try {
- Set<MeasurementData> d = remoteClient.getMeasurementDataManagerRemote().findLiveData(
- remoteClient.getSubject(), resourceId, new int[] { definition.getId() });
- MeasurementData data = d.iterator().next();
- return data.getValue();
- } catch (Exception e) {
- return "?";
- }
- }
-
- public String toString() {
- return getName();
- }
- public String getShortOutput() {
- return getDisplayValue();
- }
- }
-
- public class Operation {
- OperationDefinition definition;
-
- public Operation(OperationDefinition definition) {
- this.definition = definition;
- }
-
- @Summary(index = 0)
- public String getName() {
- return simpleName(this.definition.getDisplayName());
- }
-
- @Summary(index = 1)
- public String getDescription() {
- return this.definition.getDescription();
- }
-
- public OperationDefinition getDefinition() {
- return definition;
- }
-
- public Object invoke(Object[] args) throws Exception {
- if (!LazyLoadScenario.isShouldLoad())
- return null;
-
- Configuration parameters = ConfigurationClassBuilder.translateParametersToConfig(definition
- .getParametersConfigurationDefinition(), args);
-
- ResourceOperationSchedule schedule = remoteClient.getOperationManagerRemote().scheduleResourceOperation(
- remoteClient.getSubject(), resourceId, definition.getName(), 0, 0, 0, 30000, parameters,
- "Executed from commandline");
-
- ResourceOperationHistoryCriteria criteria = new ResourceOperationHistoryCriteria();
- criteria.addFilterJobId(schedule.getJobId());
- criteria.addFilterResourceIds(resourceId);
- criteria.addSortStartTime(PageOrdering.DESC); // put most recent at top of results
- criteria.setPaging(0, 1); // only return one result, in effect the latest
- criteria.fetchOperationDefinition(true);
- criteria.fetchParameters(true);
- criteria.fetchResults(true);
-
- int retries = 10;
- ResourceOperationHistory history = null;
- while (history == null && retries-- > 0) {
- Thread.sleep(1000);
- PageList<ResourceOperationHistory> histories = remoteClient.getOperationManagerRemote()
- .findResourceOperationHistoriesByCriteria(remoteClient.getSubject(), criteria);
- if (histories.size() > 0 && histories.get(0).getStatus() != OperationRequestStatus.INPROGRESS) {
- history = histories.get(0);
- }
- }
-
- Configuration result = (history != null ? history.getResults() : null);
-
- Object returnResults = ConfigurationClassBuilder.translateResults(definition
- .getResultsConfigurationDefinition(), result);
-
- return returnResults;
- }
- }
-
- public static class ClientProxyMethodHandler implements MethodHandler, ContentBackedResource, PluginConfigurable,
- ResourceConfigurable {
-
- ResourceClientProxy resourceClientProxy;
- RemoteClient remoteClient;
-
- public ClientProxyMethodHandler(ResourceClientProxy resourceClientProxy, RemoteClient remoteClient) {
- this.resourceClientProxy = resourceClientProxy;
- this.remoteClient = remoteClient;
- }
-
- // ------------------------------------------------------------------------------------------------------
- // Methods here are optional and only accessible if their declared on the custom resource interface class
-
- public Configuration getPluginConfiguration() {
- if (!LazyLoadScenario.isShouldLoad())
- return null;
- return remoteClient.getConfigurationManagerRemote().getPluginConfiguration(remoteClient.getSubject(),
- resourceClientProxy.resourceId);
- }
-
- public ConfigurationDefinition getPluginConfigurationDefinition() {
- return resourceClientProxy.pluginConfigurationDefinition;
- }
-
- public PluginConfigurationUpdate updatePluginConfiguration(Configuration configuration) {
- PluginConfigurationUpdate update =
- remoteClient.getConfigurationManagerRemote().updatePluginConfiguration(
- remoteClient.getSubject(),
- resourceClientProxy.getId(),
- configuration);
-
- return update;
- }
-
- public void editPluginConfiguration() {
- ConfigurationEditor editor = new ConfigurationEditor(resourceClientProxy.client);
- Configuration config = editor.editConfiguration(getPluginConfigurationDefinition(), getPluginConfiguration());
- if (config != null) {
- updatePluginConfiguration(config);
- }
- }
-
- public void editResourceConfiguration() {
- ConfigurationEditor editor = new ConfigurationEditor(resourceClientProxy.client);
- Configuration config = editor.editConfiguration(getResourceConfigurationDefinition(), getResourceConfiguration());
- if (config != null) {
- updateResourceConfiguration(config);
- }
- }
-
- public Configuration getResourceConfiguration() {
- if (!LazyLoadScenario.isShouldLoad())
- return null;
-
- return remoteClient.getConfigurationManagerRemote().getResourceConfiguration(remoteClient.getSubject(),
- resourceClientProxy.resourceId);
- }
-
- public ConfigurationDefinition getResourceConfigurationDefinition() {
- return resourceClientProxy.resourceConfigurationDefinition;
- }
-
- public ResourceConfigurationUpdate updateResourceConfiguration(Configuration configuration) {
- ResourceConfigurationUpdate update =
- remoteClient.getConfigurationManagerRemote().updateResourceConfiguration(
- remoteClient.getSubject(),
- resourceClientProxy.getId(),
- configuration);
-
- return update;
-
- }
-
- public InstalledPackage getBackingContent() {
-
- return remoteClient.getContentManagerRemote().getBackingPackageForResource(remoteClient.getSubject(), resourceClientProxy.resourceId);
- }
-
- public void updateBackingContent(String filename) {
- File file = new File(filename);
- if (!file.exists()) {
- throw new IllegalArgumentException("File not found: " + file.getAbsolutePath());
- }
- if (file.isDirectory()) {
- throw new IllegalArgumentException("File expected, found directory: " + file.getAbsolutePath());
- }
-
-
- InstalledPackage oldPackage = getBackingContent();
-
-
- String oldVersion = oldPackage.getPackageVersion().getVersion();
- String newVersion = "1.0";
- if (oldVersion != null && oldVersion.length() != 0) {
- String[] parts = oldVersion.split("[^a-zA-Z0-9]");
- String lastPart = parts[parts.length-1];
- try {
- int lastNumber = Integer.parseInt(lastPart);
- newVersion = oldVersion.substring(0, oldVersion.length() - lastPart.length()) + (lastNumber + 1);
- } catch (NumberFormatException nfe) {
- newVersion = oldVersion + ".1";
- }
- }
-
- byte[] fileContents = new ScriptUtil(null).getFileBytes(filename);
-
-
- PackageVersion pv =
- remoteClient.getContentManagerRemote().createPackageVersion(
- remoteClient.getSubject(),
- oldPackage.getPackageVersion().getGeneralPackage().getName(),
- oldPackage.getPackageVersion().getGeneralPackage().getPackageType().getId(),
- newVersion,
- oldPackage.getPackageVersion().getArchitecture().getId(),
- fileContents);
-
- remoteClient.getContentManagerRemote().deployPackages(
- remoteClient.getSubject(),
- new int[] { resourceClientProxy.getId()},
- new int[] {pv.getId()});
-
-
- }
-
- public void retrieveBackingContent(String fileName) throws IOException {
-
- InstalledPackage installedPackage = getBackingContent();
-
- if (fileName == null )
- fileName = installedPackage.getPackageVersion().getFileName();
-
- File file = new File(fileName);
-
- byte[] data =
- remoteClient.getContentManagerRemote().getPackageBytes(
- remoteClient.getSubject(), resourceClientProxy.resourceId, installedPackage.getId());
-
- FileOutputStream fos = new FileOutputStream(file);
- fos.write(data);
- fos.close();
-
- }
-
- // ------------------------------------------------------------------------------------------------------
-
-
-
- public Object invoke(Object proxy, Method method, Method proceedMethod, Object[] args) throws Throwable {
-
- if (proceedMethod != null) {
- Method realMethod = ResourceClientProxy.class.getMethod(method.getName(), method.getParameterTypes());
- return realMethod.invoke(resourceClientProxy, args);
- } else {
-
- try {
- Method localMethod = ClientProxyMethodHandler.class.getDeclaredMethod(method.getName(), method
- .getParameterTypes());
- return localMethod.invoke(this, args);
- } catch (NoSuchMethodException nsme) {
-
- String name = method.getName();
- Object key = resourceClientProxy.allProperties.get(name);
- if (key == null) {
- name = decapitalize(method.getName().substring(3, method.getName().length()));
- key = resourceClientProxy.allProperties.get(name);
- }
-
- if (key != null) {
- if (key instanceof Measurement) {
- return key;
- } else if (key instanceof Operation) {
- System.out.println("Invoking operation " + ((Operation) key).getName());
-
- return ((Operation) key).invoke(args);
-
- }
- }
- }
-
- throw new RuntimeException("Can't find custom method: " + method);
- }
- }
- }
-
-
- static String simpleName(String name) {
- return decapitalize(name.replaceAll("\\W", ""));
- }
-
- private static String decapitalize(String name) {
- return Character.toLowerCase(name.charAt(0)) + name.substring(1, name.length());
- }
-
- static String getterName(String name) {
- return "get" + Character.toUpperCase(name.charAt(0)) + name.substring(1, name.length());
- }
-
- public static interface PluginConfigurable {
- public Configuration getPluginConfiguration();
-
- public ConfigurationDefinition getPluginConfigurationDefinition();
-
- public PluginConfigurationUpdate updatePluginConfiguration(Configuration configuration);
-
- public void editPluginConfiguration();
- }
-
- public static interface ResourceConfigurable {
- public Configuration getResourceConfiguration();
-
- public ConfigurationDefinition getResourceConfigurationDefinition();
-
- public ResourceConfigurationUpdate updateResourceConfiguration(Configuration configuration);
-
- public void editResourceConfiguration();
- }
-
- public static interface ContentBackedResource {
-
- public InstalledPackage getBackingContent();
-
-
- public void updateBackingContent(String fileName);
-
-
- public void retrieveBackingContent(String fileName) throws IOException;
-
- }
-
- public static void main(String[] args) throws Exception {
- RemoteClient rc = new RemoteClient("localhost", 7080);
-
- rc.login("rhqadmin", "rhqadmin");
- ClientMain cm = new ClientMain();
- cm.setRemoteClient(rc);
-
- ResourceClientFactory factory = new ResourceClientFactory(cm);
-
- ResourceClientProxy resource = factory.getResource(10571);
-
- for (Measurement m : resource.getMeasurements()) {
- System.out.println(m.toString());
- }
- }
-}
diff --git a/modules/enterprise/remoting/cli/src/main/java/org/rhq/enterprise/client/utility/ConfigurationClassBuilder.java b/modules/enterprise/remoting/cli/src/main/java/org/rhq/enterprise/client/utility/ConfigurationClassBuilder.java
deleted file mode 100644
index 138e45b..0000000
--- a/modules/enterprise/remoting/cli/src/main/java/org/rhq/enterprise/client/utility/ConfigurationClassBuilder.java
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * RHQ Management Platform
- * Copyright (C) 2005-2008 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.client.utility;
-
-import java.util.LinkedHashMap;
-
-import javassist.ClassPool;
-import javassist.CtClass;
-import javassist.NotFoundException;
-
-import org.rhq.core.domain.configuration.Configuration;
-import org.rhq.core.domain.configuration.PropertySimple;
-import org.rhq.core.domain.configuration.definition.ConfigurationDefinition;
-import org.rhq.core.domain.configuration.definition.PropertyDefinition;
-import org.rhq.core.domain.configuration.definition.PropertyDefinitionSimple;
-
-/**
- * @author Greg Hinkle
- */
-public class ConfigurationClassBuilder {
-
- public static LinkedHashMap<String, CtClass> translateParameters(ConfigurationDefinition def)
- throws NotFoundException {
- LinkedHashMap<String, CtClass> result = new LinkedHashMap<String, CtClass>();
- if (def == null || def.getPropertyDefinitions() == null) {
- return result;
- }
-
- for (PropertyDefinition pd : def.getPropertyDefinitions().values()) {
- if (pd instanceof PropertyDefinitionSimple) {
- PropertyDefinitionSimple simple = (PropertyDefinitionSimple) pd;
- String name = simpleName(simple.getDisplayName());
- CtClass paramType = getSimpleTypeClass(simple);
- result.put(name, paramType);
- }
- }
- return result;
- }
-
- private static CtClass getSimpleTypeClass(PropertyDefinitionSimple simple) throws NotFoundException {
- Class paramType = null;
- switch (simple.getType()) {
- case STRING:
- case LONG_STRING:
- case PASSWORD:
- case FILE:
- case DIRECTORY:
- paramType = String.class;
- break;
- case BOOLEAN:
- paramType = Boolean.TYPE;
- break;
- case INTEGER:
- paramType = Integer.TYPE;
- break;
- case LONG:
- paramType = Long.TYPE;
- break;
- case FLOAT:
- paramType = Float.TYPE;
- break;
- case DOUBLE:
- paramType = Double.TYPE;
- break;
- }
- return ClassPool.getDefault().get(paramType.getName());
- }
-
- public static CtClass translateConfiguration(ConfigurationDefinition def) throws NotFoundException {
- if (def == null) {
- return CtClass.voidType;
- } else if (def.getPropertyDefinitionSimple("operationResult") != null) {
- // Its a simple type
- return getSimpleTypeClass(def.getPropertyDefinitionSimple("operationResult"));
- } else {
-
- // TODO GH: Build a custom type?
- return ClassPool.getDefault().get(Configuration.class.getName());
- }
- }
-
- private static String simpleName(String name) {
- return decapitalize(name.replaceAll("\\W", ""));
- }
-
- private static String decapitalize(String name) {
- return Character.toLowerCase(name.charAt(0)) + name.substring(1, name.length());
- }
-
- public static Configuration translateParametersToConfig(ConfigurationDefinition parametersConfigurationDefinition,
- Object[] args) throws NotFoundException {
- LinkedHashMap<String, CtClass> translateParameters = translateParameters(parametersConfigurationDefinition);
- Configuration config = new Configuration();
-
- int index = 0;
- for (String key : translateParameters.keySet()) {
- config.put(new PropertySimple(key, args[index++]));
-
- }
- return config;
-
- }
-
- public static Object translateResults(ConfigurationDefinition resultsConfigurationDefinition, Configuration result)
- throws NotFoundException {
-
- CtClass expectedReturn = translateConfiguration(resultsConfigurationDefinition);
-
- if (expectedReturn.equals(ClassPool.getDefault().get(Configuration.class.getName()))) {
- return result;
- } else {
- //bail on translation if Configuration passed in is null
- if (result == null)
- return result;
- PropertySimple simple = result.getSimple("operationResult");
- if (simple != null) {
- if (expectedReturn.getName().equals(String.class.getName())) {
- return simple.getStringValue();
- } else if (expectedReturn.getName().equals(Boolean.class.getName())
- || expectedReturn.getName().equals(Boolean.TYPE.getName())) {
- return simple.getBooleanValue();
- } else if (expectedReturn.getName().equals(Integer.class.getName())
- || expectedReturn.getName().equals(Integer.TYPE.getName())) {
- return simple.getIntegerValue();
- } else if (expectedReturn.getName().equals(Long.class.getName())
- || expectedReturn.getName().equals(Long.TYPE.getName())) {
- return simple.getLongValue();
- } else if (expectedReturn.getName().equals(Float.class.getName())
- || expectedReturn.getName().equals(Float.TYPE.getName())) {
- return simple.getFloatValue();
- } else if (expectedReturn.getName().equals(Double.class.getName())
- || expectedReturn.getName().equals(Double.TYPE.getName())) {
- return simple.getDoubleValue();
- } else if (expectedReturn.getName().equals(Boolean.class.getName())
- || expectedReturn.getName().equals(Boolean.TYPE.getName())) {
- return simple.getBooleanValue();
- }
- }
- }
- return null;
- }
-}
diff --git a/modules/enterprise/remoting/cli/src/main/java/org/rhq/enterprise/client/utility/ScriptAssert.java b/modules/enterprise/remoting/cli/src/main/java/org/rhq/enterprise/client/utility/ScriptAssert.java
deleted file mode 100644
index f22af44..0000000
--- a/modules/enterprise/remoting/cli/src/main/java/org/rhq/enterprise/client/utility/ScriptAssert.java
+++ /dev/null
@@ -1,413 +0,0 @@
-/*
- * RHQ Management Platform
- * Copyright (C) 2005-2008 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.client.utility;
-
-import org.testng.Assert;
-
-import javax.script.ScriptEngine;
-import javax.script.ScriptException;
-import java.util.Collection;
-
-public class ScriptAssert {
-
- private ScriptEngine scriptEngine;
-
- public ScriptAssert(ScriptEngine scriptEngine) {
- this.scriptEngine = scriptEngine;
- }
-
- public void assertTrue(boolean condition, String msg) {
- try {
- Assert.assertTrue(condition, msg);
- } catch (AssertionError e) {
- throw new ScriptAssertionException(e);
- }
- }
-
- public void assertTrue(boolean condition) {
- try {
- Assert.assertTrue(condition);
- } catch (AssertionError e) {
- throw new ScriptAssertionException(e);
- }
- }
-
- public void assertFalse(boolean condition, String msg) {
- try {
- Assert.assertFalse(condition, msg);
- } catch (AssertionError e) {
- throw new ScriptAssertionException(e);
- }
- }
-
- public void assertFalse(boolean condition) {
- try {
- Assert.assertFalse(condition);
- } catch (AssertionError e) {
- throw new ScriptAssertionException(e);
- }
- }
-
- public void fail(String msg, Throwable throwable) {
- try {
- Assert.fail(msg, throwable);
- } catch (AssertionError e) {
- throw new ScriptAssertionException(e);
- }
- }
-
- public void fail(String msg) {
- try {
- Assert.fail(msg);
- } catch (AssertionError e) {
- throw new ScriptAssertionException(e);
- }
- }
-
- public void fail() {
- throw new ScriptAssertionException(new AssertionError());
- }
-
- public void assertEquals(Object actual, Object expected, String msg) {
- try {
- Assert.assertEquals(actual, expected, msg);
- } catch (AssertionError e) {
- throw new ScriptAssertionException(e);
- }
- }
-
- public void assertEquals(Object actual, Object expected) {
- try {
- Assert.assertEquals(actual, expected);
- } catch (AssertionError e) {
- throw new ScriptAssertionException(e);
- }
- }
-
- public void assertEquals(String actual, String expected, String msg) {
- try {
- Assert.assertEquals(actual, expected, msg);
- } catch (AssertionError e) {
- throw new ScriptAssertionException(e);
- }
- }
-
- public void assertEquals(String actual, String expected) {
- try {
- Assert.assertEquals(actual, expected);
- } catch (AssertionError e) {
- throw new ScriptAssertionException(e);
- }
- }
-
- public void assertEquals(double actual, double expected, double delta, String msg) {
- try {
- Assert.assertEquals(actual, expected, delta, msg);
- } catch (AssertionError e) {
- throw new ScriptAssertionException(e);
- }
- }
-
- public void assertEquals(double actual, double expected, double delta) {
- try {
- Assert.assertEquals(actual, expected, delta);
- } catch (AssertionError e) {
- throw new ScriptAssertionException(e);
- }
- }
-
- public void assertEquals(float actual, float expected, float delta, String msg) {
- try {
- Assert.assertEquals(actual, expected, delta, msg);
- } catch (AssertionError e) {
- throw new ScriptAssertionException(e);
- }
- }
-
- public void assertEquals(float actual, float expected, float delta) {
- try {
- Assert.assertEquals(actual, expected, delta);
- } catch (AssertionError e) {
- throw new ScriptAssertionException(e);
- }
- }
-
- public void assertEquals(long actual, long expected, String msg) {
- try {
- Assert.assertEquals(actual, expected, msg);
- } catch (AssertionError e) {
- throw new ScriptAssertionException(e);
- }
- }
-
- public void assertEquals(long actual, long expected) {
- try {
- Assert.assertEquals(actual, expected);
- } catch (AssertionError e) {
- throw new ScriptAssertionException(e);
- }
- }
-
- public void assertEquals(boolean actual, boolean expected, String msg) {
- try {
- Assert.assertEquals(actual, expected, msg);
- } catch (AssertionError e) {
- throw new ScriptAssertionException(e);
- }
- }
-
- public void assertEquals(boolean actual, boolean expected) {
- try {
- Assert.assertEquals(actual, expected);
- } catch (AssertionError e) {
- throw new ScriptAssertionException(e);
- }
- }
-
- public void assertEquals(byte actual, byte expected, String msg) {
- try {
- Assert.assertEquals(actual, expected, msg);
- } catch (AssertionError e) {
- throw new ScriptAssertionException(e);
- }
- }
-
- public void assertEquals(byte actual, byte expected) {
- try {
- Assert.assertEquals(actual, expected);
- } catch (AssertionError e) {
- throw new ScriptAssertionException(e);
- }
- }
-
- public void assertEquals(char actual, char expected, String msg) {
- try {
- Assert.assertEquals(actual, expected, msg);
- } catch (AssertionError e) {
- throw new ScriptAssertionException(e);
- }
- }
-
- public void assertEquals(char actual, char expected) {
- try {
- Assert.assertEquals(actual, expected);
- } catch (AssertionError e) {
- throw new ScriptAssertionException(e);
- }
- }
-
- public void assertEquals(short actual, short expected, String msg) {
- try {
- Assert.assertEquals(actual, expected, msg);
- } catch(AssertionError e) {
- throw new ScriptAssertionException(e);
- }
- }
-
- public void assertEquals(short actual, short expected) {
- try {
- Assert.assertEquals(actual, expected);
- } catch (AssertionError e) {
- throw new ScriptAssertionException(e);
- }
- }
-
- public void assertEquals(int actual, int expected, String msg) {
- try {
- Assert.assertEquals(actual, expected, msg);
- } catch (AssertionError e) {
- throw new ScriptAssertionException(e);
- }
- }
-
- public void assertEquals(int actual, int expected) {
- try {
- Assert.assertEquals(actual, expected);
- } catch (AssertionError e) {
- throw new ScriptAssertionException(e);
- }
- }
-
- public void assertNotNull(Object object) {
- try {
- Assert.assertNotNull(object);
- } catch (AssertionError e) {
- throw new ScriptAssertionException(e);
- }
- }
-
- public void assertNotNull(Object object, String msg) {
- try {
- Assert.assertNotNull(object, msg);
- } catch (AssertionError e) {
- throw new ScriptAssertionException(e);
- }
- }
-
- public void assertNull(Object object) {
- try {
- Assert.assertNull(object);
- } catch (AssertionError e) {
- throw new ScriptAssertionException(e);
- }
- }
-
- public void assertNull(Object object, String msg) {
- try {
- Assert.assertNull(object, msg);
- } catch (AssertionError e) {
- throw new ScriptAssertionException(e);
- }
- }
-
- public void assertSame(Object actual, Object expected, String msg) {
- try {
- Assert.assertSame(actual, expected, msg);
- } catch (AssertionError e) {
- throw new ScriptAssertionException(e);
- }
- }
-
- public void assertSame(Object actual, Object expected) {
- try {
- Assert.assertSame(actual, expected);
- } catch (AssertionError e) {
- throw new ScriptAssertionException(e);
- }
- }
-
- public void assertNotSame(Object actual, Object expected, String msg) {
- try {
- Assert.assertNotSame(actual, expected, msg);
- } catch (AssertionError e) {
- throw new ScriptAssertionException(e);
- }
- }
-
- public void assertNotSame(Object actual, Object expected) {
- try {
- Assert.assertNotSame(actual, expected);
- } catch (AssertionError e) {
- throw new ScriptAssertionException(e);
- }
- }
-
- public void assertEquals(Collection actual, Collection expected) {
- try {
- Assert.assertEquals(actual, expected);
- } catch (AssertionError e) {
- throw new ScriptAssertionException(e);
- }
- }
-
- public void assertEquals(Collection actual, Collection expected, String msg) {
- try {
- Assert.assertEquals(actual, expected, msg);
- } catch (AssertionError e) {
- throw new ScriptAssertionException(e);
- }
- }
-
- public void assertEquals(Object[] actual, Object[] expected, String msg) {
- try {
- Assert.assertEquals(actual, expected, msg);
- } catch (AssertionError e) {
- throw new ScriptAssertionException(e);
- }
- }
-
- public void assertEqualsNoOrder(Object[] actual, Object[] expected, String msg) {
- try {
- Assert.assertEqualsNoOrder(actual, expected, msg);
- } catch (AssertionError e) {
- throw new ScriptAssertionException(e);
- }
- }
-
- public void assertEquals(Object[] actual, Object[] expected) {
- try {
- Assert.assertEquals(actual, expected);
- } catch (AssertionError e) {
- throw new ScriptAssertionException(e);
- }
- }
-
- public void assertEqualsNoOrder(Object[] actual, Object[] expected) {
- try {
- Assert.assertEqualsNoOrder(actual, expected);
- } catch (AssertionError e) {
- throw new ScriptAssertionException(e);
- }
- }
-
- public void assertEquals(byte[] actual, byte[] expected) {
- try {
- Assert.assertEquals(actual, expected);
- } catch (AssertionError e) {
- throw new ScriptAssertionException(e);
- }
- }
-
- public void assertEquals(byte[] actual, byte[] expected, String msg) {
- try {
- Assert.assertEquals(actual, expected, msg);
- } catch (AssertionError e) {
- throw new ScriptAssertionException(e);
- }
- }
-
- public void assertExists(String identifier) {
- assertNotNull(scriptEngine.get(identifier), identifier + " is not defined");
- }
-
- /**
- * JavaScript has only a single numeric type such that <code>x = 1</code> and <code>y = 1.0</code> are considered to
- * be of the same type. From within a (JavaScript) script if you were to call <code>assertEquals(x, y)</code>, you
- * would get an exception that looks something like,
- *
- * <pre>
- * Caused by: javax.script.ScriptException: sun.org.mozilla.javascript.internal.EvaluatorException: The choice of
- * Java constructor assertEquals matching JavaScript argument types (number,number,string) is ambiguous;
- * candidate constructors are:
- * void assertEquals(java.lang.String,java.lang.String,java.lang.String)
- * void assertEquals(double,double,double)
- * void assertEquals(float,float,float)
- * void assertEquals(long,long,java.lang.String)
- * void assertEquals(byte,byte,java.lang.String)
- * void assertEquals(char,char,java.lang.String)
- * void assertEquals(short,short,java.lang.String)
- * void assertEquals(int,int,java.lang.String) (<Unknown source>#1) in <Unknown source> at line number 1
- </pre>
- *
- * To avoid the ambiguity when comparing numbers in JavaScript scripts, it is recommended to use this method.
- *
- * @param actual The actual value
- * @param expected The expected value
- * @param msg A useful, meaningful error message
- */
- public void assertNumberEqualsJS(double actual, double expected, String msg) {
- assertEquals(actual, expected, msg);
- }
-
-}
diff --git a/modules/enterprise/remoting/cli/src/main/java/org/rhq/enterprise/client/utility/ScriptAssertionException.java b/modules/enterprise/remoting/cli/src/main/java/org/rhq/enterprise/client/utility/ScriptAssertionException.java
deleted file mode 100644
index f17f02b..0000000
--- a/modules/enterprise/remoting/cli/src/main/java/org/rhq/enterprise/client/utility/ScriptAssertionException.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * RHQ Management Platform
- * Copyright (C) 2005-2008 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.client.utility;
-
-import javax.script.ScriptException;
-
-/**
- * This is a wrapper exception class for {@link java.lang.AssertionError}. The default (i.e., rhino) scripting engine
- * catches any exception, checked or unchecked, thrown from a script and wraps it in an instance of
- * {@link javax.script.ScriptException}. ScriptException provides useful context information such as the script name
- * and line number on which the exception occurred. For reasons unknown instances of {@link Error} are not caught and
- * wrapped in a ScriptException; consequently, no context information is provided about the error, particularly, a line
- * number.
- */
-public class ScriptAssertionException extends RuntimeException {
-
-// public ScriptAssertionException() {
-// super();
-// }
-//
-// public ScriptAssertionException(String message) {
-// super(message);
-// }
-//
-// public ScriptAssertionException(String message, Throwable cause) {
-// super(message, cause);
-// }
-//
-// public ScriptAssertionException(Throwable cause) {
-// super(cause);
-// }
-
- public ScriptAssertionException(AssertionError error) {
- super(new ScriptException(error.getMessage()));
- }
-}
diff --git a/modules/enterprise/remoting/cli/src/main/java/org/rhq/enterprise/client/utility/ScriptUtil.java b/modules/enterprise/remoting/cli/src/main/java/org/rhq/enterprise/client/utility/ScriptUtil.java
deleted file mode 100644
index 5333522..0000000
--- a/modules/enterprise/remoting/cli/src/main/java/org/rhq/enterprise/client/utility/ScriptUtil.java
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * RHQ Management Platform
- * Copyright (C) 2005-2009 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.client.utility;
-
-import org.rhq.core.domain.criteria.ResourceCriteria;
-import org.rhq.core.domain.criteria.ResourceOperationHistoryCriteria;
-import org.rhq.core.domain.operation.OperationRequestStatus;
-import org.rhq.core.domain.operation.ResourceOperationHistory;
-import org.rhq.core.domain.resource.Resource;
-import org.rhq.core.domain.util.PageList;
-import org.rhq.core.domain.util.PageOrdering;
-import org.rhq.enterprise.client.ClientMain;
-import org.rhq.enterprise.client.commands.ScriptCommand;
-import org.rhq.core.domain.operation.bean.ResourceOperationSchedule;
-import org.rhq.enterprise.server.resource.ResourceManagerRemote;
-
-import javax.script.Bindings;
-import javax.script.ScriptContext;
-import javax.script.ScriptEngine;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-
-public class ScriptUtil {
-
- private ClientMain client;
-
-
- public ScriptUtil(ClientMain client) {
- this.client = client;
- }
-
-
-
- public PageList<Resource> findResources(String string) {
- ResourceManagerRemote resourceManager = client.getRemoteClient().getResourceManagerRemote();
-
- ResourceCriteria criteria = new ResourceCriteria();
- criteria.addFilterName(string);
- return resourceManager.findResourcesByCriteria(client.getSubject(), criteria);
- }
-
-
- public byte[] getFileBytes(String fileName) {
- File file = new File(fileName);
- long length = file.length();
-
- if (length > Integer.MAX_VALUE) {
- throw new IllegalArgumentException("Can not read file larger than " + Integer.MAX_VALUE + " byte: "
- + fileName);
- }
-
- byte[] bytes;
- InputStream is = null;
- try {
- bytes = new byte[(int) length];
- is = new FileInputStream(file);
-
- int offset = 0, bytesRead = 0;
- for (offset = 0, bytesRead = 0; offset < bytes.length && bytesRead >= 0; offset += bytesRead) {
- bytesRead = is.read(bytes, offset, bytes.length - offset);
- }
-
- if (offset < bytes.length) {
- throw new RuntimeException("Could not read entire file " + file.getName() + ", only " + offset + " of "
- + bytes.length + " bytes read");
- }
- } catch (IOException ioe) {
- throw new RuntimeException("Error reading file: " + ioe.getMessage());
- } finally {
- try {
- if (is != null) {
- is.close();
- }
- } catch (IOException ioe) {
- throw new RuntimeException("Error closing file: " + ioe.getMessage());
- }
- }
- return bytes;
- }
-
- public String getFileString(String fileName) {
- return new String(getFileBytes(fileName));
- }
-
- public void sleep(long millis) {
- try {
- Thread.sleep(millis);
- } catch (InterruptedException ie) {
- throw new RuntimeException(ie);
- }
- }
-
- public ResourceOperationHistory waitForScheduledOperationToComplete(ResourceOperationSchedule schedule)
- throws InterruptedException{
-
- return waitForScheduledOperationToComplete(schedule, 1000L, 10);
- }
-
- public ResourceOperationHistory waitForScheduledOperationToComplete(ResourceOperationSchedule schedule,
- long intervalDuration,
- int maxIntervals) throws InterruptedException {
- ResourceOperationHistoryCriteria criteria = new ResourceOperationHistoryCriteria();
- criteria.addFilterJobId(schedule.getJobId());
- criteria.addFilterResourceIds(schedule.getResource().getId());
- criteria.addSortStartTime(PageOrdering.DESC);
- criteria.setPaging(0, 1);
- criteria.fetchOperationDefinition(true);
- criteria.fetchParameters(true);
- criteria.fetchResults(true);
-
- ResourceOperationHistory history = null;
-
- int i = 0;
-
- while(history == null && i < maxIntervals) {
- Thread.sleep(intervalDuration);
- PageList<ResourceOperationHistory> histories = client.getRemoteClient().getOperationManagerRemote()
- .findResourceOperationHistoriesByCriteria(client.getRemoteClient().getSubject(), criteria);
- if (histories.size() > 0 && histories.get(0).getStatus() != OperationRequestStatus.INPROGRESS) {
- history = histories.get(0);
- }
- ++i;
- }
-
- return history;
- }
-
- public boolean isDefined(String identifier) {
- ScriptCommand cmd = (ScriptCommand) client.getCommands().get("exec");
- ScriptEngine scriptEngine = cmd.getScriptEngine();
-
- Bindings engineBindings = scriptEngine.getBindings(ScriptContext.ENGINE_SCOPE);
- Bindings globalBindings = scriptEngine.getBindings(ScriptContext.GLOBAL_SCOPE);
-
- return engineBindings.containsKey(identifier) || globalBindings.containsKey(identifier);
- }
-}
diff --git a/modules/enterprise/remoting/cli/src/main/scripts/rhq-client.build.xml b/modules/enterprise/remoting/cli/src/main/scripts/rhq-client.build.xml
index b80f900..f54a691 100644
--- a/modules/enterprise/remoting/cli/src/main/scripts/rhq-client.build.xml
+++ b/modules/enterprise/remoting/cli/src/main/scripts/rhq-client.build.xml
@@ -53,7 +53,7 @@
<copy file="${settings.localRepository}/org/rhq/rhq-remoting-client-api/${project.version}/rhq-remoting-client-api-${project.version}.jar" todir="${lib.home}" verbose="true" />
<copy file="${settings.localRepository}/org/rhq/rhq-core-domain/${project.version}/rhq-core-domain-${project.version}.jar" tofile="${lib.home}/rhq-core-domain-${project.version}.jar" verbose="true" />
<copy file="${settings.localRepository}/org/rhq/rhq-core-util/${project.version}/rhq-core-util-${project.version}.jar" tofile="${lib.home}/rhq-core-util-${project.version}.jar" verbose="true" />
- <copy file="${settings.localRepository}/org/rhq/rhq-enterprise-server/${project.version}/rhq-enterprise-server-${project.version}.jar" tofile="${lib.home}/rhq-enterprise-server-${project.version}.jar" verbose="true" />
+ <copy file="${settings.localRepository}/org/rhq/rhq-enterprise-server/${project.version}/rhq-enterprise-server-${project.version}-client.jar" tofile="${lib.home}/rhq-enterprise-server-${project.version}-client.jar" verbose="true" />
<copy file="${settings.localRepository}/org/rhq/rhq-enterprise-comm/${project.version}/rhq-enterprise-comm-${project.version}.jar" tofile="${lib.home}/rhq-enterprise-comm-${project.version}.jar" verbose="true" />
<copy file="${settings.localRepository}/jboss/jboss-common/${jboss-common.version}/jboss-common-${jboss-common.version}.jar" tofile="${lib.home}/jboss-common-${jboss-common.version}.jar" verbose="true" />
<copy file="${settings.localRepository}/jboss/jboss-remoting/${jboss-remoting.version}/jboss-remoting-${jboss-remoting.version}.jar" tofile="${lib.home}/jboss-remoting-${jboss-remoting.version}.jar" verbose="true" />
@@ -64,6 +64,7 @@
<copy file="${basedir}/target/${project.artifactId}-${project.version}.jar" tofile="${lib.home}/${project.artifactId}-${project.version}.jar" verbose="true" />
<copy file="${settings.localRepository}/net/sf/opencsv/opencsv/${opencsv.version}/opencsv-${opencsv.version}.jar" tofile="${lib.home}/opencsv-${opencsv.version}.jar" verbose="true" />
<copy file="${settings.localRepository}/org/testng/testng/${testng.version}/testng-${testng.version}.jar" tofile="${lib.home}/testng-${testng.version}.jar" verbose="true" />
+ <copy file="${settings.localRepository}/org/rhq/rhq-script-bindings/${project.version}/rhq-script-bindings-${project.version}.jar" tofile="${lib.home}/rhq-script-bindings-${project.version}.jar" verbose="true" />
</target>
</project>
diff --git a/modules/enterprise/remoting/cli/src/test/java/org/rhq/enterprise/client/commands/ScriptCommandTest.java b/modules/enterprise/remoting/cli/src/test/java/org/rhq/enterprise/client/commands/ScriptCommandTest.java
index 22d5305..b795848 100644
--- a/modules/enterprise/remoting/cli/src/test/java/org/rhq/enterprise/client/commands/ScriptCommandTest.java
+++ b/modules/enterprise/remoting/cli/src/test/java/org/rhq/enterprise/client/commands/ScriptCommandTest.java
@@ -12,7 +12,6 @@ import java.util.ArrayList;
import org.testng.annotations.Test;
import org.rhq.enterprise.client.ClientMain;
import org.rhq.enterprise.client.RemoteClient;
-import org.rhq.enterprise.client.utility.ScriptUtil;
import org.rhq.enterprise.server.alert.AlertManagerRemote;
import org.rhq.enterprise.server.alert.AlertDefinitionManagerRemote;
import org.rhq.enterprise.server.configuration.ConfigurationManagerRemote;
@@ -23,7 +22,9 @@ import org.rhq.enterprise.server.authz.RoleManagerRemote;
import org.rhq.enterprise.server.resource.ResourceManagerRemote;
import org.rhq.enterprise.server.resource.group.ResourceGroupManagerRemote;
import org.rhq.enterprise.server.auth.SubjectManagerRemote;
+import org.rhq.bindings.client.RhqManagers;
import org.rhq.bindings.output.TabularWriter;
+import org.rhq.bindings.util.ScriptUtil;
import org.rhq.core.domain.auth.Subject;
import javax.script.ScriptEngine;
@@ -73,7 +74,7 @@ public class ScriptCommandTest {
ScriptEngine scriptEngine = cmd.getScriptEngine();
List<String> mgrsNotBound = new ArrayList<String>();
- for (RemoteClient.Manager mgr : RemoteClient.Manager.values()) {
+ for (RhqManagers mgr : RhqManagers.values()) {
if (!scriptEngine.getBindings(ScriptContext.GLOBAL_SCOPE).containsKey(mgr.name())) {
mgrsNotBound.add(mgr.remoteName());
}
@@ -121,52 +122,52 @@ public class ScriptCommandTest {
}
@Override
- public AlertManagerRemote getAlertManagerRemote() {
+ public AlertManagerRemote getAlertManager() {
return null;
}
@Override
- public AlertDefinitionManagerRemote getAlertDefinitionManagerRemote() {
+ public AlertDefinitionManagerRemote getAlertDefinitionManager() {
return null;
}
@Override
- public ConfigurationManagerRemote getConfigurationManagerRemote() {
+ public ConfigurationManagerRemote getConfigurationManager() {
return null;
}
@Override
- public RepoManagerRemote getRepoManagerRemote() {
+ public RepoManagerRemote getRepoManager() {
return null;
}
@Override
- public ContentManagerRemote getContentManagerRemote() {
+ public ContentManagerRemote getContentManager() {
return null;
}
@Override
- public OperationManagerRemote getOperationManagerRemote() {
+ public OperationManagerRemote getOperationManager() {
return null;
}
@Override
- public RoleManagerRemote getRoleManagerRemote() {
+ public RoleManagerRemote getRoleManager() {
return null;
}
@Override
- public ResourceManagerRemote getResourceManagerRemote() {
+ public ResourceManagerRemote getResourceManager() {
return null;
}
@Override
- public ResourceGroupManagerRemote getResourceGroupManagerRemote() {
+ public ResourceGroupManagerRemote getResourceGroupManager() {
return null;
}
@Override
- public SubjectManagerRemote getSubjectManagerRemote() {
+ public SubjectManagerRemote getSubjectManager() {
return null;
}
}
diff --git a/modules/enterprise/remoting/cli/src/test/java/org/rhq/enterprise/client/utility/ScriptAssertTest.java b/modules/enterprise/remoting/cli/src/test/java/org/rhq/enterprise/client/utility/ScriptAssertTest.java
index a681efc..10f8fa7 100644
--- a/modules/enterprise/remoting/cli/src/test/java/org/rhq/enterprise/client/utility/ScriptAssertTest.java
+++ b/modules/enterprise/remoting/cli/src/test/java/org/rhq/enterprise/client/utility/ScriptAssertTest.java
@@ -28,6 +28,8 @@ import static org.testng.Assert.*;
import org.testng.annotations.Test;
import org.testng.annotations.BeforeClass;
+import org.rhq.bindings.util.ScriptAssert;
+
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
diff --git a/modules/enterprise/remoting/cli/src/test/java/org/rhq/enterprise/client/utility/ScriptUtilTest.java b/modules/enterprise/remoting/cli/src/test/java/org/rhq/enterprise/client/utility/ScriptUtilTest.java
index c257796..7a88720 100644
--- a/modules/enterprise/remoting/cli/src/test/java/org/rhq/enterprise/client/utility/ScriptUtilTest.java
+++ b/modules/enterprise/remoting/cli/src/test/java/org/rhq/enterprise/client/utility/ScriptUtilTest.java
@@ -9,6 +9,8 @@ import javax.script.ScriptEngineManager;
import org.testng.annotations.Test;
+import org.rhq.bindings.util.ScriptUtil;
+
public class ScriptUtilTest {
@Test
diff --git a/modules/enterprise/remoting/client-api/pom.xml b/modules/enterprise/remoting/client-api/pom.xml
index ed44e2a..872ac37 100644
--- a/modules/enterprise/remoting/client-api/pom.xml
+++ b/modules/enterprise/remoting/client-api/pom.xml
@@ -63,94 +63,6 @@
<dependency>
<groupId>${project.groupId}</groupId>
- <artifactId>rhq-enterprise-server</artifactId>
- <version>${project.version}</version>
- <exclusions>
- <exclusion>
- <groupId>ant</groupId>
- <artifactId>ant</artifactId>
- </exclusion>
- <exclusion>
- <groupId>commons-beanutils</groupId>
- <artifactId>commons-beanutils</artifactId>
- </exclusion>
- <exclusion>
- <groupId>commons-collections</groupId>
- <artifactId>commons-collections</artifactId>
- </exclusion>
- <exclusion>
- <groupId>commons-httpclient</groupId>
- <artifactId>commons-httpclient</artifactId>
- </exclusion>
- <exclusion>
- <groupId>commons-lang</groupId>
- <artifactId>commons-lang</artifactId>
- </exclusion>
- <exclusion>
- <groupId>commons-validator</groupId>
- <artifactId>commons-validator</artifactId>
- </exclusion>
- <exclusion>
- <groupId>dom4j</groupId>
- <artifactId>dom4j</artifactId>
- </exclusion>
- <exclusion>
- <groupId>gnu-getopt</groupId>
- <artifactId>getopt</artifactId>
- </exclusion>
- <exclusion>
- <groupId>jboss</groupId>
- <artifactId>jboss-cache</artifactId>
- </exclusion>
- <exclusion>
- <groupId>jboss</groupId>
- <artifactId>jbpm</artifactId>
- </exclusion>
- <exclusion>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- </exclusion>
- <exclusion>
- <groupId>org.rhq</groupId>
- <artifactId>rhq-core-client-api</artifactId>
- </exclusion>
- <exclusion>
- <groupId>org.rhq</groupId>
- <artifactId>rhq-core-dbutils</artifactId>
- </exclusion>
- <exclusion>
- <groupId>org.rhq</groupId>
- <artifactId>rhq-enterprise-server-xml-schemas</artifactId>
- </exclusion>
- <exclusion>
- <groupId>org.rhq</groupId>
- <artifactId>safe-invoker</artifactId>
- </exclusion>
- <exclusion>
- <groupId>org.rhq</groupId>
- <artifactId>test-utils</artifactId>
- </exclusion>
- <exclusion>
- <groupId>org.snmp4j</groupId>
- <artifactId>snmp4j</artifactId>
- </exclusion>
- <exclusion>
- <groupId>oswego-concurrent</groupId>
- <artifactId>concurrent</artifactId>
- </exclusion>
- <exclusion>
- <groupId>postgresql</groupId>
- <artifactId>postgresql</artifactId>
- </exclusion>
- <exclusion>
- <groupId>rss4j</groupId>
- <artifactId>rss4j</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
-
- <dependency>
- <groupId>${project.groupId}</groupId>
<artifactId>rhq-core-domain</artifactId>
<version>${project.version}</version>
</dependency>
diff --git a/modules/enterprise/remoting/client-api/src/main/java/org/rhq/enterprise/client/RemoteClient.java b/modules/enterprise/remoting/client-api/src/main/java/org/rhq/enterprise/client/RemoteClient.java
index 05d8e2c..ddd8f94 100644
--- a/modules/enterprise/remoting/client-api/src/main/java/org/rhq/enterprise/client/RemoteClient.java
+++ b/modules/enterprise/remoting/client-api/src/main/java/org/rhq/enterprise/client/RemoteClient.java
@@ -22,11 +22,16 @@ import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
import org.jboss.remoting.Client;
import org.jboss.remoting.InvokerLocator;
import org.jboss.remoting.security.SSLSocketBuilder;
import org.jboss.remoting.transport.http.ssl.HTTPSClientInvoker;
+import org.rhq.bindings.client.RhqFacade;
+import org.rhq.bindings.client.RhqManagers;
import org.rhq.core.domain.auth.Subject;
import org.rhq.enterprise.communications.util.SecurityUtil;
import org.rhq.enterprise.server.alert.AlertDefinitionManagerRemote;
@@ -66,60 +71,10 @@ import org.rhq.enterprise.server.tagging.TagManagerRemote;
* @author Jay Shaughnessy
* @author John Mazzitelli
*/
-public class RemoteClient {
-
- public enum Manager {
- AlertManager(AlertManagerRemote.class), //
- AlertDefinitionManager(AlertDefinitionManagerRemote.class), //
- AvailabilityManager(AvailabilityManagerRemote.class), //
- BundleManager(BundleManagerRemote.class), //
- CallTimeDataManager(CallTimeDataManagerRemote.class), //
- RepoManager(RepoManagerRemote.class), //
- ConfigurationManager(ConfigurationManagerRemote.class), //
- ContentManager(ContentManagerRemote.class), //
- DataAccessManager(DataAccessManagerRemote.class), //
- DiscoveryBoss(DiscoveryBossRemote.class), //
- EventManager(EventManagerRemote.class), //
- MeasurementBaselineManager(MeasurementBaselineManagerRemote.class), //
- MeasurementDataManager(MeasurementDataManagerRemote.class), //
- MeasurementDefinitionManager(MeasurementDefinitionManagerRemote.class), //
- MeasurementScheduleManager(MeasurementScheduleManagerRemote.class), //
- OperationManager(OperationManagerRemote.class), //
- ResourceManager(ResourceManagerRemote.class), //
- ResourceFactoryManager(ResourceFactoryManagerRemote.class), //
- ResourceGroupManager(ResourceGroupManagerRemote.class), //
- ResourceTypeManager(ResourceTypeManagerRemote.class), //
- RoleManager(RoleManagerRemote.class), //
- SavedSearchManager(SavedSearchManagerRemote.class), //
- SubjectManager(SubjectManagerRemote.class), //
- SupportManager(SupportManagerRemote.class), //
- SystemManager(SystemManagerRemote.class), //
- RemoteInstallManager(RemoteInstallManagerRemote.class), //
- TagManager(TagManagerRemote.class);
-
- private Class<?> remote;
- private String remoteName;
- private String beanName;
-
- private Manager(Class<?> remote) {
- this.remote = remote;
- this.beanName = this.name() + "Bean";
- this.remoteName = this.name() + "Remote";
- }
-
- Class<?> remote() {
- return this.remote;
- }
-
- public String beanName() {
- return this.beanName;
- }
-
- public String remoteName() {
- return this.remoteName;
- }
- };
+public class RemoteClient implements RhqFacade {
+ private static final Log LOG = LogFactory.getLog(RemoteClient.class);
+
public static final String NONSECURE_TRANSPORT = "servlet";
public static final String SECURE_TRANSPORT = "sslservlet";
@@ -184,12 +139,10 @@ public class RemoteClient {
logout();
doConnect();
- this.subject = getSubjectManagerRemote().login(user, password);
+ this.subject = getSubjectManager().login(user, password);
this.loggedIn = true;
- ServerVersion version = getSystemManagerRemote().getServerVersion(this.subject);
- // TODO: what to do with this?
- System.out.println("Remote server version is: " + version);
+ ServerVersion version = getSystemManager().getServerVersion(this.subject);
return this.subject;
}
@@ -200,7 +153,7 @@ public class RemoteClient {
public void logout() {
try {
if (this.loggedIn && this.subject != null) {
- getSubjectManagerRemote().logout(this.subject);
+ getSubjectManager().logout(this.subject);
}
} catch (Exception e) {
// just keep going so we can disconnect this client
@@ -304,112 +257,112 @@ public class RemoteClient {
this.transport = transport;
}
- public AlertManagerRemote getAlertManagerRemote() {
- return RemoteClientProxy.getProcessor(this, Manager.AlertManager);
+ public AlertManagerRemote getAlertManager() {
+ return RemoteClientProxy.getProcessor(this, RhqManagers.AlertManager);
}
- public AlertDefinitionManagerRemote getAlertDefinitionManagerRemote() {
- return RemoteClientProxy.getProcessor(this, Manager.AlertDefinitionManager);
+ public AlertDefinitionManagerRemote getAlertDefinitionManager() {
+ return RemoteClientProxy.getProcessor(this, RhqManagers.AlertDefinitionManager);
}
- public AvailabilityManagerRemote getAvailabilityManagerRemote() {
- return RemoteClientProxy.getProcessor(this, Manager.AvailabilityManager);
+ public AvailabilityManagerRemote getAvailabilityManager() {
+ return RemoteClientProxy.getProcessor(this, RhqManagers.AvailabilityManager);
}
- public BundleManagerRemote getBundleManagerRemote() {
- return RemoteClientProxy.getProcessor(this, Manager.BundleManager);
+ public BundleManagerRemote getBundleManager() {
+ return RemoteClientProxy.getProcessor(this, RhqManagers.BundleManager);
}
- public CallTimeDataManagerRemote getCallTimeDataManagerRemote() {
- return RemoteClientProxy.getProcessor(this, Manager.CallTimeDataManager);
+ public CallTimeDataManagerRemote getCallTimeDataManager() {
+ return RemoteClientProxy.getProcessor(this, RhqManagers.CallTimeDataManager);
}
- public RepoManagerRemote getRepoManagerRemote() {
- return RemoteClientProxy.getProcessor(this, Manager.RepoManager);
+ public RepoManagerRemote getRepoManager() {
+ return RemoteClientProxy.getProcessor(this, RhqManagers.RepoManager);
}
- public ConfigurationManagerRemote getConfigurationManagerRemote() {
- return RemoteClientProxy.getProcessor(this, Manager.ConfigurationManager);
+ public ConfigurationManagerRemote getConfigurationManager() {
+ return RemoteClientProxy.getProcessor(this, RhqManagers.ConfigurationManager);
}
- public ContentManagerRemote getContentManagerRemote() {
- return RemoteClientProxy.getProcessor(this, Manager.ContentManager);
+ public ContentManagerRemote getContentManager() {
+ return RemoteClientProxy.getProcessor(this, RhqManagers.ContentManager);
}
- public DataAccessManagerRemote getDataAccessManagerRemote() {
- return RemoteClientProxy.getProcessor(this, Manager.DataAccessManager);
+ public DataAccessManagerRemote getDataAccessManager() {
+ return RemoteClientProxy.getProcessor(this, RhqManagers.DataAccessManager);
}
- public DiscoveryBossRemote getDiscoveryBossRemote() {
- return RemoteClientProxy.getProcessor(this, Manager.DiscoveryBoss);
+ public DiscoveryBossRemote getDiscoveryBoss() {
+ return RemoteClientProxy.getProcessor(this, RhqManagers.DiscoveryBoss);
}
- public EventManagerRemote getEventManagerRemote() {
- return RemoteClientProxy.getProcessor(this, Manager.EventManager);
+ public EventManagerRemote getEventManager() {
+ return RemoteClientProxy.getProcessor(this, RhqManagers.EventManager);
}
- public MeasurementBaselineManagerRemote getMeasurementBaselineManagerRemote() {
- return RemoteClientProxy.getProcessor(this, Manager.MeasurementBaselineManager);
+ public MeasurementBaselineManagerRemote getMeasurementBaselineManager() {
+ return RemoteClientProxy.getProcessor(this, RhqManagers.MeasurementBaselineManager);
}
- public MeasurementDataManagerRemote getMeasurementDataManagerRemote() {
- return RemoteClientProxy.getProcessor(this, Manager.MeasurementDataManager);
+ public MeasurementDataManagerRemote getMeasurementDataManager() {
+ return RemoteClientProxy.getProcessor(this, RhqManagers.MeasurementDataManager);
}
- public MeasurementDefinitionManagerRemote getMeasurementDefinitionManagerRemote() {
- return RemoteClientProxy.getProcessor(this, Manager.MeasurementDefinitionManager);
+ public MeasurementDefinitionManagerRemote getMeasurementDefinitionManager() {
+ return RemoteClientProxy.getProcessor(this, RhqManagers.MeasurementDefinitionManager);
}
- public MeasurementScheduleManagerRemote getMeasurementScheduleManagerRemote() {
- return RemoteClientProxy.getProcessor(this, Manager.MeasurementScheduleManager);
+ public MeasurementScheduleManagerRemote getMeasurementScheduleManager() {
+ return RemoteClientProxy.getProcessor(this, RhqManagers.MeasurementScheduleManager);
}
- public OperationManagerRemote getOperationManagerRemote() {
- return RemoteClientProxy.getProcessor(this, Manager.OperationManager);
+ public OperationManagerRemote getOperationManager() {
+ return RemoteClientProxy.getProcessor(this, RhqManagers.OperationManager);
}
- public ResourceManagerRemote getResourceManagerRemote() {
- return RemoteClientProxy.getProcessor(this, Manager.ResourceManager);
+ public ResourceManagerRemote getResourceManager() {
+ return RemoteClientProxy.getProcessor(this, RhqManagers.ResourceManager);
}
- public ResourceFactoryManagerRemote getResourceFactoryManagerRemote() {
- return RemoteClientProxy.getProcessor(this, Manager.ResourceFactoryManager);
+ public ResourceFactoryManagerRemote getResourceFactoryManager() {
+ return RemoteClientProxy.getProcessor(this, RhqManagers.ResourceFactoryManager);
}
- public ResourceGroupManagerRemote getResourceGroupManagerRemote() {
- return RemoteClientProxy.getProcessor(this, Manager.ResourceGroupManager);
+ public ResourceGroupManagerRemote getResourceGroupManager() {
+ return RemoteClientProxy.getProcessor(this, RhqManagers.ResourceGroupManager);
}
- public ResourceTypeManagerRemote getResourceTypeManagerRemote() {
- return RemoteClientProxy.getProcessor(this, Manager.ResourceTypeManager);
+ public ResourceTypeManagerRemote getResourceTypeManager() {
+ return RemoteClientProxy.getProcessor(this, RhqManagers.ResourceTypeManager);
}
- public RoleManagerRemote getRoleManagerRemote() {
- return RemoteClientProxy.getProcessor(this, Manager.RoleManager);
+ public RoleManagerRemote getRoleManager() {
+ return RemoteClientProxy.getProcessor(this, RhqManagers.RoleManager);
}
- public SavedSearchManagerRemote getSavedSearchManagerRemote() {
- return RemoteClientProxy.getProcessor(this, Manager.SavedSearchManager);
+ public SavedSearchManagerRemote getSavedSearchManager() {
+ return RemoteClientProxy.getProcessor(this, RhqManagers.SavedSearchManager);
}
- public SubjectManagerRemote getSubjectManagerRemote() {
- return RemoteClientProxy.getProcessor(this, Manager.SubjectManager);
+ public SubjectManagerRemote getSubjectManager() {
+ return RemoteClientProxy.getProcessor(this, RhqManagers.SubjectManager);
}
- public SupportManagerRemote getSupportManagerRemote() {
- return RemoteClientProxy.getProcessor(this, Manager.SupportManager);
+ public SupportManagerRemote getSupportManager() {
+ return RemoteClientProxy.getProcessor(this, RhqManagers.SupportManager);
}
- public SystemManagerRemote getSystemManagerRemote() {
- return RemoteClientProxy.getProcessor(this, Manager.SystemManager);
+ public SystemManagerRemote getSystemManager() {
+ return RemoteClientProxy.getProcessor(this, RhqManagers.SystemManager);
}
- public RemoteInstallManagerRemote getRemoteInstallManagerRemote() {
- return RemoteClientProxy.getProcessor(this, Manager.RemoteInstallManager);
+ public RemoteInstallManagerRemote getRemoteInstallManager() {
+ return RemoteClientProxy.getProcessor(this, RhqManagers.RemoteInstallManager);
}
- public TagManagerRemote getTagManagerRemote() {
- return RemoteClientProxy.getProcessor(this, Manager.TagManager);
+ public TagManagerRemote getTagManager() {
+ return RemoteClientProxy.getProcessor(this, RhqManagers.TagManager);
}
/**
@@ -423,12 +376,12 @@ public class RemoteClient {
this.managers = new HashMap<String, Object>();
- for (Manager manager : Manager.values()) {
+ for (RhqManagers manager : RhqManagers.values()) {
try {
- Method m = this.getClass().getMethod("get" + manager.remoteName());
+ Method m = this.getClass().getMethod("get" + manager.name());
this.managers.put(manager.name(), m.invoke(this));
} catch (Throwable e) {
- System.out.println("Failed to load manager " + manager + " due to missing class: " + e);
+ LOG.error("Failed to load manager " + manager + " due to missing class.", e);
}
}
}
@@ -461,7 +414,7 @@ public class RemoteClient {
this.remotingClient.disconnect();
}
} catch (Exception e) {
- e.printStackTrace(); // TODO what to do here?
+ LOG.warn(e); // TODO what to do here?
} finally {
this.remotingClient = null;
}
diff --git a/modules/enterprise/remoting/client-api/src/main/java/org/rhq/enterprise/client/RemoteClientProxy.java b/modules/enterprise/remoting/client-api/src/main/java/org/rhq/enterprise/client/RemoteClientProxy.java
index c76d46f..5e897cb 100644
--- a/modules/enterprise/remoting/client-api/src/main/java/org/rhq/enterprise/client/RemoteClientProxy.java
+++ b/modules/enterprise/remoting/client-api/src/main/java/org/rhq/enterprise/client/RemoteClientProxy.java
@@ -22,18 +22,13 @@ import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
-import javassist.CannotCompileException;
-import javassist.ClassPool;
-import javassist.CtClass;
-import javassist.CtMethod;
-import javassist.CtNewMethod;
-import javassist.NotFoundException;
-import javassist.bytecode.ParameterAnnotationsAttribute;
-
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+
import org.jboss.remoting.invocation.NameBasedInvocation;
+import org.rhq.bindings.client.RhqManagers;
+import org.rhq.bindings.util.InterfaceSimplifier;
import org.rhq.core.domain.auth.Subject;
import org.rhq.core.server.ExternalizableStrategy;
@@ -43,116 +38,34 @@ import org.rhq.core.server.ExternalizableStrategy;
*
* @author Greg Hinkle
*/
-@SuppressWarnings("unchecked")
public class RemoteClientProxy implements InvocationHandler {
- private static final Log LOG = LogFactory.getLog(RemoteClientProxy.class);
-
private RemoteClient client;
- private RemoteClient.Manager manager;
+ private RhqManagers manager;
// public RHQRemoteClientProxy(RHQRemoteClient client, Class targetClass) {
- public RemoteClientProxy(RemoteClient client, RemoteClient.Manager manager) {
+ public RemoteClientProxy(RemoteClient client, RhqManagers manager) {
this.client = client;
this.manager = manager;
}
- public Class getRemoteInterface() {
+ public Class<?> getRemoteInterface() {
return this.manager.remote();
}
- public static <T> T getProcessor(RemoteClient remoteClient, RemoteClient.Manager manager) {
+ @SuppressWarnings("unchecked")
+ public static <T> T getProcessor(RemoteClient remoteClient, RhqManagers manager) {
try {
RemoteClientProxy gpc = new RemoteClientProxy(remoteClient, manager);
- Class intf = simplifyInterface(gpc.manager.remote());
+ Class<?> intf = InterfaceSimplifier.simplify(gpc.manager.remote());
return (T) Proxy
- .newProxyInstance(Thread.currentThread().getContextClassLoader(), new Class[] { intf }, gpc);
+ .newProxyInstance(Thread.currentThread().getContextClassLoader(), new Class<?>[] { intf }, gpc);
} catch (Exception e) {
throw new RuntimeException("Failed to get remote connection proxy", e);
}
}
- private static Class simplifyInterface(Class intf) {
- try {
- ClassPool cp = ClassPool.getDefault();
-
- String simpleName = intf.getName() + "Simple";
-
- try {
- @SuppressWarnings({"UnusedDeclaration"})
- CtClass cached = cp.get(simpleName);
- return Class.forName(simpleName, false, cp.getClassLoader());
-
- } catch (NotFoundException e) {
- // ok... load it
- } catch (ClassNotFoundException e) {
- LOG.debug("Class [" + simpleName + "] not found - cause: " + e);
- }
-
- CtClass cc = cp.get(intf.getName());
-
- CtClass cz = cp.getAndRename(intf.getName(), simpleName);
- // CtClass cz = cp.makeInterface(simpleName, cc);
-
- cz.defrost();
-
- cz.setSuperclass(cc);
-
- CtMethod[] methods = cc.getMethods();
-
- for (CtMethod originalMethod : methods) {
-
- CtClass[] params = originalMethod.getParameterTypes();
- if (params.length > 0 && params[0].getName().equals(Subject.class.getName())) {
-
- CtClass[] simpleParams = new CtClass[params.length - 1];
-
- System.arraycopy(params, 1, simpleParams, 0, params.length - 1);
- cz.defrost();
-
- CtMethod newMethod = CtNewMethod.abstractMethod(originalMethod.getReturnType(), originalMethod
- .getName(), simpleParams, null, cz);
-
- ParameterAnnotationsAttribute originalAnnotationsAttribute = (ParameterAnnotationsAttribute) originalMethod
- .getMethodInfo().getAttribute(ParameterAnnotationsAttribute.visibleTag);
-
- // If there are any parameter annotations, copy the one's we're keeping
- if (originalAnnotationsAttribute != null) {
-
- javassist.bytecode.annotation.Annotation[][] originalAnnotations = originalAnnotationsAttribute
- .getAnnotations();
- javassist.bytecode.annotation.Annotation[][] newAnnotations = new javassist.bytecode.annotation.Annotation[originalAnnotations.length - 1][];
-
- for (int i = 1; i < originalAnnotations.length; i++) {
- newAnnotations[i - 1] = new javassist.bytecode.annotation.Annotation[originalAnnotations[i].length];
- System.arraycopy(originalAnnotations[i], 0, newAnnotations[i - 1], 0,
- originalAnnotations[i].length);
- }
-
- ParameterAnnotationsAttribute newAnnotationsAttribute = new ParameterAnnotationsAttribute(
- newMethod.getMethodInfo().getConstPool(), ParameterAnnotationsAttribute.visibleTag);
-
- newAnnotationsAttribute.setAnnotations(newAnnotations);
-
- newMethod.getMethodInfo().addAttribute(newAnnotationsAttribute);
-
- }
-
- cz.addMethod(newMethod);
- }
- }
-
- return cz.toClass();
-
- } catch (NotFoundException e) {
- LOG.debug("Failed to simplify " + intf + " - cause: " + e);
- } catch (CannotCompileException e) {
- LOG.error("Failed to simplify " + intf + ".", e);
- }
- return intf;
- }
-
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
try {
@@ -161,12 +74,12 @@ public class RemoteClientProxy implements InvocationHandler {
String methodName = manager.beanName() + ":" + method.getName();
- Class[] params = method.getParameterTypes();
+ Class<?>[] params = method.getParameterTypes();
try {
- Class[] interfaces = method.getDeclaringClass().getInterfaces();
+ Class<?>[] interfaces = method.getDeclaringClass().getInterfaces();
- Class originalClass;
+ Class<?> originalClass;
if (interfaces != null && interfaces.length > 0) {
originalClass = interfaces[0];
} else {
@@ -187,7 +100,7 @@ public class RemoteClientProxy implements InvocationHandler {
args = newArgs;
int numParams = (null == params) ? 0 : params.length;
- Class[] newParams = new Class[numParams + 1];
+ Class<?>[] newParams = new Class[numParams + 1];
if (numParams > 0) {
System.arraycopy(params, 0, newParams, 1, numParams);
}
@@ -210,7 +123,7 @@ public class RemoteClientProxy implements InvocationHandler {
}
}
- private String[] createParamSignature(Class[] types) {
+ private String[] createParamSignature(Class<?>[] types) {
String[] paramSig = new String[types.length];
for (int x = 0; x < types.length; x++) {
paramSig[x] = types[x].getName();
diff --git a/modules/enterprise/server/jar/pom.xml b/modules/enterprise/server/jar/pom.xml
index 7363fcc..29abc06 100644
--- a/modules/enterprise/server/jar/pom.xml
+++ b/modules/enterprise/server/jar/pom.xml
@@ -482,6 +482,14 @@
</testResources>
<plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-ejb-plugin</artifactId>
+ <version>2.3</version>
+ <configuration>
+ <generateClient>true</generateClient>
+ </configuration>
+ </plugin>
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
commit 8e0df522a432a66392d428aeb8e86a71c6d1061e
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Fri Jan 7 11:43:03 2011 +0100
Starting to rip out common ScriptEngine bindings out of the CLI code into a reusable component that could be used on the serverside without a standard input attached.
diff --git a/modules/enterprise/binding/pom.xml b/modules/enterprise/binding/pom.xml
new file mode 100644
index 0000000..8523c1d
--- /dev/null
+++ b/modules/enterprise/binding/pom.xml
@@ -0,0 +1,59 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <artifactId>rhq-enterprise-parent</artifactId>
+ <groupId>org.rhq</groupId>
+ <version>4.0.0-SNAPSHOT</version>
+ </parent>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-script-bindings</artifactId>
+ <version>4.0.0-SNAPSHOT</version>
+ <name>RHQ Script Bindings</name>
+ <description>Abstraction of different facilities and default configurations for script bindings</description>
+
+ <properties>
+ <persistence-api.version>1.0</persistence-api.version>
+ <opencsv.version>1.8</opencsv.version>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>rhq-core-domain</artifactId>
+ <version>${project.version}</version>
+ <exclusions>
+ <exclusion>
+ <groupId>hibernate</groupId>
+ <artifactId>hibernate3</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+
+ <dependency>
+ <groupId>commons-lang</groupId>
+ <artifactId>commons-lang</artifactId>
+ <version>2.4</version>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>javax.persistence</groupId>
+ <artifactId>persistence-api</artifactId>
+ <version>${persistence-api.version}</version>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.testng</groupId>
+ <artifactId>testng</artifactId>
+ <version>${testng.version}</version>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>net.sf.opencsv</groupId>
+ <artifactId>opencsv</artifactId>
+ <version>${opencsv.version}</version>
+ </dependency>
+ </dependencies>
+</project>
\ No newline at end of file
diff --git a/modules/enterprise/binding/src/main/java/org/rhq/bindings/ScriptEngineFactory.java b/modules/enterprise/binding/src/main/java/org/rhq/bindings/ScriptEngineFactory.java
new file mode 100644
index 0000000..4179dbe
--- /dev/null
+++ b/modules/enterprise/binding/src/main/java/org/rhq/bindings/ScriptEngineFactory.java
@@ -0,0 +1,100 @@
+/*
+ * 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 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.bindings;
+
+import java.io.IOException;
+
+import javax.script.Bindings;
+import javax.script.ScriptContext;
+import javax.script.ScriptEngine;
+import javax.script.ScriptException;
+
+import org.rhq.bindings.engine.JsEngineInitializer;
+import org.rhq.bindings.engine.ScriptEngineInitializer;
+import org.rhq.bindings.export.Exporter;
+import org.rhq.bindings.util.PackageFinder;
+import org.rhq.core.domain.util.PageControl;
+
+/**
+ * This is RHQ specific imitation of ScriptEngineFactory.
+ *
+ * In RHQ, we provide a standard set of bound variables in the script context
+ * and also import classes from our standard packages to ease the development
+ * of the scripts.
+ * <p>
+ * This factory is able to instantiate a script engine and initialize it consistently
+ * so that all users of the script engine get the uniform environment to write the scripts
+ * in.
+ *
+ * @author Lukas Krejci
+ */
+public class ScriptEngineFactory {
+
+ private static final ScriptEngineInitializer[] KNOWN_ENGINES = {new JsEngineInitializer()};
+
+ private ScriptEngineFactory() {
+
+ }
+
+ /**
+ * Initializes the script engine for given language.
+ *
+ * @param language the language of the script to instantiate
+ * @param packageFinder the package finder to find the standard packages in user provided locations
+ * @return the initialized engine or null if the engine for given language isn't known.
+ *
+ * @throws ScriptException on error during initialization of the script environment
+ * @throws IOException if the package finder fails to find the packages
+ */
+ public static ScriptEngine getScriptEngine(String language, PackageFinder packageFinder) throws ScriptException, IOException {
+ ScriptEngineInitializer initializer = getInitializer(language);
+
+ if (initializer == null) {
+ return null;
+ }
+
+ ScriptEngine engine = initializer.instantiate(packageFinder.findPackages("org.rhq.core.domain"));
+
+ injectStandardBindings(engine);
+
+ return engine;
+ }
+
+ public static void injectStandardBindings(ScriptEngine engine) {
+ Bindings bindings = engine.getBindings(ScriptContext.ENGINE_SCOPE);
+ PageControl pc = new PageControl();
+ pc.setPageNumber(-1);
+ bindings.put("unlimitedPC", pc);
+ bindings.put("pageControl", PageControl.getUnlimitedInstance());
+ bindings.put("exporter", new Exporter());
+
+ engine.setBindings(bindings, ScriptContext.ENGINE_SCOPE);
+ }
+
+ private static ScriptEngineInitializer getInitializer(String language) {
+ for (ScriptEngineInitializer i : KNOWN_ENGINES) {
+ if (i.getEngineName().equals(language)) {
+ return i;
+ }
+ }
+
+ return null;
+ }
+}
diff --git a/modules/enterprise/binding/src/main/java/org/rhq/bindings/engine/JsEngineInitializer.java b/modules/enterprise/binding/src/main/java/org/rhq/bindings/engine/JsEngineInitializer.java
new file mode 100644
index 0000000..8186831
--- /dev/null
+++ b/modules/enterprise/binding/src/main/java/org/rhq/bindings/engine/JsEngineInitializer.java
@@ -0,0 +1,50 @@
+/*
+ * 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 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.bindings.engine;
+
+import java.util.List;
+
+import javax.script.ScriptEngine;
+import javax.script.ScriptEngineManager;
+import javax.script.ScriptException;
+
+/**
+ *
+ *
+ * @author Lukas Krejci
+ */
+public class JsEngineInitializer implements ScriptEngineInitializer {
+
+ public String getEngineName() {
+ return "JavaScript";
+ }
+
+ public ScriptEngine instantiate(List<String> packages) throws ScriptException {
+ ScriptEngineManager sem = new ScriptEngineManager();
+ ScriptEngine eng = sem.getEngineByName(getEngineName());
+
+ for(String pkg : packages) {
+ eng.eval("importPackage(" + pkg + ")");
+ }
+
+ return eng;
+ }
+
+}
diff --git a/modules/enterprise/binding/src/main/java/org/rhq/bindings/engine/ScriptEngineInitializer.java b/modules/enterprise/binding/src/main/java/org/rhq/bindings/engine/ScriptEngineInitializer.java
new file mode 100644
index 0000000..bc76433
--- /dev/null
+++ b/modules/enterprise/binding/src/main/java/org/rhq/bindings/engine/ScriptEngineInitializer.java
@@ -0,0 +1,38 @@
+/*
+ * 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 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.bindings.engine;
+
+import java.util.List;
+
+import javax.script.ScriptEngine;
+import javax.script.ScriptException;
+
+/**
+ * Is able to instatiate a script engine and import packages into the context
+ * of the engine.
+ *
+ * @author Lukas Krejci
+ */
+public interface ScriptEngineInitializer {
+
+ String getEngineName();
+
+ ScriptEngine instantiate(List<String> packages) throws ScriptException;
+}
diff --git a/modules/enterprise/binding/src/main/java/org/rhq/bindings/export/ExportException.java b/modules/enterprise/binding/src/main/java/org/rhq/bindings/export/ExportException.java
new file mode 100644
index 0000000..6fe8e32
--- /dev/null
+++ b/modules/enterprise/binding/src/main/java/org/rhq/bindings/export/ExportException.java
@@ -0,0 +1,43 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2008 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.bindings.export;
+
+public class ExportException extends RuntimeException {
+
+ public ExportException() {
+ super();
+ }
+
+ public ExportException(String message) {
+ super(message);
+ }
+
+ public ExportException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public ExportException(Throwable cause) {
+ super(cause);
+ }
+}
diff --git a/modules/enterprise/binding/src/main/java/org/rhq/bindings/export/Exporter.java b/modules/enterprise/binding/src/main/java/org/rhq/bindings/export/Exporter.java
new file mode 100644
index 0000000..0e39b54
--- /dev/null
+++ b/modules/enterprise/binding/src/main/java/org/rhq/bindings/export/Exporter.java
@@ -0,0 +1,86 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2008 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.bindings.export;
+
+import org.rhq.bindings.output.TabularWriter;
+
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.PrintWriter;
+
+public class Exporter {
+
+ private String format;
+
+ private String file;
+
+ private TabularWriter tabularWriter;
+
+ private FileWriter fileWriter;
+
+ public void setTarget(String format, String file) {
+ try {
+ this.format = format;
+ this.file = file;
+ fileWriter = new FileWriter(this.file);
+ tabularWriter = new TabularWriter(new PrintWriter(fileWriter), format);
+ tabularWriter.setExportMode(true);
+ } catch (IOException e) {
+ throw new ExportException(e);
+ }
+ }
+
+ public int getPageWidth() {
+ return tabularWriter.getWidth();
+ }
+
+ public void setPageWidth(int width) {
+ tabularWriter.setWidth(width);
+ }
+
+ public void write(Object object) {
+ try {
+ tabularWriter.print(object);
+ fileWriter.flush();
+ } catch (IOException e) {
+ throw new ExportException(e);
+ }
+ }
+
+ public String getFormat() {
+ return format;
+ }
+
+ public void setFormat(String format) {
+ this.format = format;
+ }
+
+ public String getFile() {
+ return file;
+ }
+
+ public void setFile(String file) {
+ this.file = file;
+ }
+}
diff --git a/modules/enterprise/binding/src/main/java/org/rhq/bindings/output/TabularWriter.java b/modules/enterprise/binding/src/main/java/org/rhq/bindings/output/TabularWriter.java
new file mode 100644
index 0000000..5e24f53
--- /dev/null
+++ b/modules/enterprise/binding/src/main/java/org/rhq/bindings/output/TabularWriter.java
@@ -0,0 +1,708 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2008 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.bindings.output;
+
+import java.beans.IntrospectionException;
+import java.beans.PropertyDescriptor;
+import java.io.PrintWriter;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import au.com.bytecode.opencsv.CSVWriter;
+
+import org.rhq.bindings.util.LazyLoadScenario;
+import org.rhq.bindings.util.ShortOutput;
+import org.rhq.bindings.util.SummaryFilter;
+import org.rhq.core.domain.configuration.Configuration;
+import org.rhq.core.domain.configuration.Property;
+import org.rhq.core.domain.configuration.PropertyList;
+import org.rhq.core.domain.configuration.PropertyMap;
+import org.rhq.core.domain.configuration.PropertySimple;
+import org.rhq.core.domain.measurement.ResourceAvailability;
+import org.rhq.core.domain.resource.ResourceType;
+
+/**
+ * @author Greg Hinkle
+ */
+public class TabularWriter {
+
+ private static final String CSV = "csv";
+
+ String[] headers;
+ int[] maxColumnLength;
+ boolean[] noShrinkColumns;
+ int width = 160;
+ PrintWriter out;
+ private String format = "raw";
+ private CSVWriter csvWriter;
+ private SummaryFilter summaryFilter = new SummaryFilter();
+ boolean exportMode;
+
+ static Set<String> IGNORED_PROPS = new HashSet<String>();
+
+ static {
+ IGNORED_PROPS.add("mtime");
+ IGNORED_PROPS.add("ctime");
+ IGNORED_PROPS.add("itime");
+ IGNORED_PROPS.add("uuid");
+ IGNORED_PROPS.add("parentResource");
+ }
+
+ static Set<Class> SIMPLE_TYPES = new HashSet<Class>();
+
+ static {
+ SIMPLE_TYPES.add(Byte.class);
+ SIMPLE_TYPES.add(Byte.TYPE);
+ SIMPLE_TYPES.add(Short.class);
+ SIMPLE_TYPES.add(Short.TYPE);
+ SIMPLE_TYPES.add(Integer.class);
+ SIMPLE_TYPES.add(Integer.TYPE);
+ SIMPLE_TYPES.add(Long.class);
+ SIMPLE_TYPES.add(Long.TYPE);
+ SIMPLE_TYPES.add(Float.class);
+ SIMPLE_TYPES.add(Float.TYPE);
+ SIMPLE_TYPES.add(Double.class);
+ SIMPLE_TYPES.add(Double.TYPE);
+ SIMPLE_TYPES.add(Boolean.class);
+ SIMPLE_TYPES.add(Boolean.TYPE);
+ SIMPLE_TYPES.add(String.class);
+ }
+
+ public TabularWriter(PrintWriter out, String... headers) {
+ this.headers = headers;
+ this.out = out;
+ }
+
+ public TabularWriter(PrintWriter out) {
+ this.out = out;
+ }
+
+ public TabularWriter(PrintWriter out, String format) {
+ this.out = out;
+ this.format = format;
+
+ if (CSV.equals(format)) {
+ csvWriter = new CSVWriter(out);
+ }
+ }
+
+ public void print(Object object) {
+
+ if (object instanceof Map) {
+ print((Map) object);
+ return;
+ }
+
+ if (object instanceof Collection) {
+ print((Collection) object);
+ return;
+ }
+
+ if (object instanceof Configuration) {
+ print((Configuration) object);
+ return;
+ }
+
+ if (object != null && object.getClass().isArray()) {
+ print((Object[]) object);
+ return;
+ }
+
+ try {
+
+ if (SIMPLE_TYPES.contains(object.getClass())) {
+ this.out.println(String.valueOf(object));
+ return;
+ }
+
+ out.println(object.getClass().getSimpleName() + ":");
+ Map<String, PropertyInfo> properties = new LinkedHashMap<String, PropertyInfo>();
+ int maxLength = 0;
+
+ for (PropertyDescriptor pd : summaryFilter.getPropertyDescriptors(object, exportMode)) {
+ Method m = pd.getReadMethod();
+ Object val = null;
+ if (m != null) {
+ val = invoke(object, m);
+ }
+
+ if (val == null) {
+ maxLength = Math.max(maxLength, pd.getName().length());
+ properties.put(pd.getName(), new PropertyInfo(pd.getName(), null));
+ } else {
+ try {
+ String str = shortVersion(val);
+ maxLength = Math.max(maxLength, pd.getName().length());
+ properties.put(pd.getName(), new PropertyInfo(str, pd.getPropertyType()));
+ } catch (Exception e) {
+ }
+ }
+ }
+
+ for (String key : properties.keySet()) {
+ printProperty(key, properties.get(key), maxLength);
+ }
+
+ } catch (InvocationTargetException e) {
+ e.printStackTrace();
+ } catch (IllegalAccessException e) {
+ e.printStackTrace();
+ } catch (IntrospectionException e) {
+ e.printStackTrace();
+ }
+
+ }
+
+ private static class PropertyInfo {
+ String value;
+
+ Class<?> type;
+
+ PropertyInfo(String propertyValue, Class<?> propertyType) {
+ value = propertyValue;
+ type = propertyType;
+ }
+ }
+
+ private void printProperty(String name, PropertyInfo propertyInfo, int maxLength) {
+ out.print("\t");
+ printPreSpaced(out, name, maxLength);
+ out.print(": ");
+
+ if (propertyInfo.type == null) {
+ out.println("");
+ } else if (exportMode || !String.class.equals(propertyInfo.type)) {
+ out.println(propertyInfo.value);
+ } else {
+ out.println(abbreviate(propertyInfo.value, width - 12 - maxLength));
+ }
+ }
+
+ // This method is taken verbatim from the Commons Lang project in the org.apache.commons.lang.StringUtils class
+ // TODO Should this method go into one our StringUtil classes?
+ private String abbreviate(String string, int maxWidth) {
+ int offset = 0;
+
+ if (string == null) {
+ return null;
+ }
+
+ if (maxWidth < 4) {
+ throw new IllegalArgumentException("Minimum abbreviation width is 4");
+ }
+
+ if (string.length() <= maxWidth) {
+ return string;
+ }
+
+ if (offset > string.length()) {
+ offset = string.length();
+ }
+
+ if ((string.length() - offset) < (maxWidth - 3)) {
+ offset = string.length() - (maxWidth - 3);
+ }
+
+ if (offset <= 4) {
+ return string.substring(0, maxWidth - 3) + "...";
+ }
+
+ if (maxWidth < 7) {
+ throw new IllegalArgumentException("Minimum abbreviation width with offset is 7");
+ }
+
+ if ((offset + (maxWidth - 3)) < string.length()) {
+ return "..." + abbreviate(string.substring(offset), maxWidth - 3);
+ }
+
+ return "..." + string.substring(string.length() - (maxWidth - 3));
+ }
+
+ public void print(Map map) {
+
+ String[][] data = new String[map.size()][];
+ int i = 0;
+ for (Object key : map.keySet()) {
+ Object value = map.get(key);
+ data[i] = new String[2];
+ data[i][0] = shortVersion(key);
+ data[i][1] = shortVersion(value);
+ i++;
+ }
+ this.headers = new String[] { "Key", "Value" };
+ print(data);
+ }
+
+ public void print(Collection list) {
+ // List of arbitrary objects
+ if (list == null || list.size() == 0)
+ out.println("no data");
+ else if (list.size() == 1 && !CSV.equals(format)) {
+ out.println("one row");
+
+ print(list.iterator().next());
+ } else {
+
+ String[][] data = null;
+
+ if (!allOneType(list)) {
+ printStrings(list);
+ } else {
+
+ Object firstObject = list.iterator().next();
+ try {
+
+ if (firstObject instanceof String) {
+ headers = new String[] { "Value" };
+ data = new String[list.size()][1];
+ int i = 0;
+ for (Object object : list) {
+ data[i++][0] = (String) object;
+ }
+
+ } else {
+
+ if (consistentMaps(list)) {
+ // results printed
+
+ } else {
+
+ int i = 0;
+
+ List<PropertyDescriptor> pdList = new ArrayList<PropertyDescriptor>();
+ for (PropertyDescriptor pd : summaryFilter.getPropertyDescriptors(firstObject, exportMode)) {
+ try {
+ boolean allNull = true;
+ for (Object row : list) {
+ Method m = pd.getReadMethod();
+ Object val = null;
+ if (m != null) {
+ val = invoke(row, pd.getReadMethod());
+ }
+ if ((val != null && !(val instanceof Collection))
+ || ((val != null && (val instanceof Collection) && !((Collection) val)
+ .isEmpty())))
+ allNull = false;
+ }
+ if (!allNull && !IGNORED_PROPS.contains(pd.getName())) {
+ pdList.add(pd);
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ headers = new String[pdList.size()];
+ data = new String[list.size()][pdList.size()];
+
+ for (PropertyDescriptor pd : pdList) {
+ headers[i++] = pd.getName();
+ }
+ i = 0;
+ for (Object row : list) {
+ int j = 0;
+ for (PropertyDescriptor pd : pdList) {
+
+ Object val = "?";
+ val = invoke(row, pd.getReadMethod());
+ if (val == null) {
+ data[i][j++] = "";
+ } else {
+ data[i][j++] = shortVersion(val);
+ }
+ }
+ i++;
+ }
+
+ this.print(data);
+
+ }
+ }
+ } catch (Exception e) {
+ e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
+ } finally {
+ headers = null;
+ }
+ }
+
+ }
+
+ }
+
+ private boolean consistentMaps(Collection list) {
+ List<String> keys = null;
+ String[][] data = new String[list.size()][];
+ int i = 0;
+ for (Object row : list) {
+ if (!(row instanceof Map) && !(row instanceof PropertyMap)) {
+ return false;
+ }
+ if (keys == null) {
+ keys = new ArrayList<String>();
+
+ //insert check for PropertyMap as they are not instances of Map
+ if (row instanceof PropertyMap) {
+ //TODO: spinder 1/15/10. PropertyMap is arbitrarily complex. Only serialize simple props?
+ for (Object key : ((PropertyMap) row).getMap().keySet()) {
+ String headerKey = stringValueOf(key);
+ keys.add(headerKey);
+ }
+ } else {//else row is a Map
+ for (Object key : ((Map) row).keySet()) {
+ String headerKey = stringValueOf(key);
+ keys.add(headerKey);
+ }
+ }
+ //conditionally put order on the headers to mimic core gui listing style/order
+ //Ex. Pid Name Size User Time Kernel Time
+ if (keys.contains("pid")) {
+ String[] processAttribute = { "pid", "name", "size", "userTime", "kernelTime" };
+ List<String> newKeyOrder = new ArrayList<String>();
+ for (String attribute : processAttribute) {
+ newKeyOrder.add(attribute);
+ keys.remove(attribute);
+ }
+ //postpend remaining keys if any to the newHeader list
+ for (String key : keys) {
+ newKeyOrder.add(key);
+ }
+ keys = newKeyOrder;
+ }
+ }
+
+ data[i] = new String[keys.size()];
+ if (row instanceof PropertyMap) {
+ for (String key : keys) {
+ if (!keys.contains(stringValueOf(key))) {
+ return false;
+ }
+ data[i][keys.lastIndexOf(stringValueOf(key))] = shortVersion(((PropertyMap) row).get(String
+ .valueOf(key)));
+ }
+ } else {//else row is a Map
+ for (Object key : ((Map) row).keySet()) {
+ if (!keys.contains(stringValueOf(key))) {
+ return false;
+ }
+ data[i][keys.lastIndexOf(stringValueOf(key))] = shortVersion(((Map) row).get(key));
+ }
+ }
+ i++;
+ }
+
+ if (keys != null) {
+ headers = keys.toArray(new String[keys.size()]);
+ print(data);
+ return true;
+ } else {
+ return false;
+ }
+
+ }
+
+ public void print(Configuration config) {
+ out.println("Configuration [" + config.getId() + "] - " + config.getNotes());
+ for (PropertySimple p : config.getSimpleProperties().values()) {
+ print(p, 1);
+ }
+ for (PropertyList p : config.getListProperties().values()) {
+ print(p, 1);
+ }
+ for (PropertyMap p : config.getMapProperties().values()) {
+ print(p, 1);
+ }
+
+ }
+
+ public void print(PropertySimple p, int depth) {
+ out.println(indent(depth) + p.getName() + " = " + p.getStringValue());
+ }
+
+ public void print(PropertyList p, int depth) {
+ out.println(indent(depth) + p.getName() + " [" + p.getList().size() + "] {");
+ if (p.getList().get(0) instanceof PropertyMap) {
+ consistentMaps(p.getList());
+
+ } else {
+ for (Property entry : p.getList()) {
+ if (entry instanceof PropertySimple) {
+ print((PropertySimple) entry, depth + 1);
+ } else if (entry instanceof PropertyMap) {
+ print((PropertyMap) entry, depth + 1);
+ }
+ }
+ }
+
+ out.println(indent(depth) + "}");
+ }
+
+ public void print(PropertyMap p, int depth) {
+ out.println(indent(depth) + p.getName() + " [" + p.getMap().size() + "] {");
+ for (String key : p.getMap().keySet()) {
+ Property entry = p.getMap().get(key);
+ if (entry instanceof PropertySimple) {
+ print((PropertySimple) entry, depth + 1);
+ } else if (entry instanceof PropertyMap) {
+ print((PropertyMap) entry, depth + 1);
+ }
+ }
+ out.println(indent(depth) + "}");
+ }
+
+ private String indent(int x) {
+ StringBuilder buf = new StringBuilder();
+ for (int i = 0; i < x; i++) {
+ buf.append(" ");
+ }
+ return buf.toString();
+ }
+
+ private void printStrings(Collection list) {
+ for (Object object : list) {
+ out.println(stringValueOf(object));
+ }
+ }
+
+ private boolean allOneType(Collection list) {
+ Class lastClass = null;
+ for (Object object : list) {
+ if (lastClass == null) {
+ lastClass = object.getClass();
+ } else if (!object.getClass().equals(lastClass)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public void print(Object[] data) {
+ if (data == null || data.length == 0) {
+ out.println("0 rows");
+ return;
+ }
+ out.println("Array of " + (data.getClass().getComponentType().getName()));
+
+ print(Arrays.asList(data));
+ }
+
+ private void resizeColumns(int[] actualColumnWidths, int maxColumnWidth, List<Integer> columns) {
+ int extraSpace = 0;
+
+ Iterator<Integer> iterator = columns.iterator();
+ while (iterator.hasNext()) {
+ int col = iterator.next();
+
+ if (actualColumnWidths[col] < maxColumnWidth) {
+ extraSpace += maxColumnWidth - actualColumnWidths[col];
+ iterator.remove();
+ }
+ }
+
+ if (extraSpace == 0) {
+ // There is no extra space with which to work so at this point we have to
+ // truncate any columns that still need more space
+ for (Integer col : columns) {
+ actualColumnWidths[col] = maxColumnWidth;
+ }
+ }
+ else if (columns.size() == 0) {
+ // If the columns list is empty then that means that there is enough available
+ // space for each column so we are done.
+ return;
+ }
+ else if (extraSpace > 0) {
+ // Since we have extra space, we will go ahead and recalculate the widths for
+ // those columns still needing space
+ int newMaxColumnWidth = (maxColumnWidth + extraSpace) / columns.size();
+ resizeColumns(actualColumnWidths, newMaxColumnWidth, columns);
+ }
+ }
+
+ public void print(String[][] data) {
+
+ if (data == null || data.length == 0) {
+ out.println("0 rows");
+ return;
+ }
+
+ int numberOfColumns = data[0].length;
+ int maxColumnWidth = width / numberOfColumns;
+ int[] actualColumnWidths = new int[numberOfColumns];
+
+ for (String[] row : data) {
+ for (int col = 0; col < row.length; ++col) {
+ if (row[col] == null) {
+ row[col] = "";
+ }
+ actualColumnWidths[col] = Math.max(actualColumnWidths[col], row[col].length());
+ }
+ }
+
+ if (headers != null) {
+ for (int col = 0; col < headers.length; ++col) {
+ actualColumnWidths[col] = Math.max(actualColumnWidths[col], headers[col].length());
+ }
+ }
+
+ List<Integer> columns = new LinkedList();
+ for (int col = 0; col < actualColumnWidths.length; ++col) {
+ columns.add(col);
+ }
+ resizeColumns(actualColumnWidths, maxColumnWidth, columns);
+
+ if (headers != null) {
+ if (CSV.equals(format)) {
+ csvWriter.writeNext(headers);
+ } else {
+ for (int i = 0; i < actualColumnWidths.length; i++) {
+ int colSize = actualColumnWidths[i];
+ printSpaced(out, headers[i], colSize);
+ if (i < actualColumnWidths.length - 1) {
+ out.print(" ");
+ }
+ }
+
+ out.print("\n");
+
+ for (int i = 1; i < width; i++) {
+ out.print("-");
+ }
+ }
+ out.print("\n");
+
+ }
+
+ if (CSV.equals(format)) {
+ for (String[] row : data) {
+ csvWriter.writeNext(row);
+ }
+ } else {
+ for (String[] row : data) {
+ for (int i = 0; i < actualColumnWidths.length; i++) {
+ int colSize = actualColumnWidths[i];
+
+ printSpaced(out, row[i], colSize);
+ if (i < actualColumnWidths.length - 1) {
+ out.print(" ");
+ }
+ }
+ out.print("\n");
+ }
+ }
+
+ out.print(data.length + " rows\n");
+ }
+
+ private void printSpaced(PrintWriter out, String data, int length) {
+ int dataLength = data.length();
+ if (dataLength > length) {
+ out.print(data.substring(0, length));
+ } else {
+ out.print(data);
+
+ for (int i = dataLength; i < length; i++) {
+ out.print(" ");
+ }
+ }
+
+ }
+
+ private void printPreSpaced(PrintWriter out, String data, int length) {
+ int dataLength = data.length();
+ if (dataLength > length) {
+ out.print(data.substring(0, length));
+ } else {
+ for (int i = dataLength; i < length; i++) {
+ out.print(" ");
+ }
+ out.print(data);
+ }
+
+ }
+
+ public int getWidth() {
+ return width;
+ }
+
+ public void setWidth(int width) {
+ this.width = width;
+ }
+
+ public boolean isExportMode() {
+ return exportMode;
+ }
+
+ public void setExportMode(boolean exportMode) {
+ this.exportMode = exportMode;
+ }
+
+ private static String shortVersion(Object object) {
+
+ if (object instanceof ShortOutput) {
+ return ((ShortOutput) object).getShortOutput();
+ } else if (object instanceof PropertySimple) {
+ return ((PropertySimple) object).getStringValue();
+ } else if (object instanceof ResourceType) {
+ return ((ResourceType) object).getName();
+ } else if (object instanceof ResourceAvailability) {
+ return ((ResourceAvailability) object).getAvailabilityType().getName();
+ } else if (object != null && object.getClass().isArray()) {
+ return Arrays.toString((Object[]) object);
+ } else {
+ return stringValueOf(object);
+ }
+ }
+
+ private static Object invoke(Object o, Method m) throws IllegalAccessException, InvocationTargetException {
+ boolean access = m.isAccessible();
+ m.setAccessible(true);
+ try {
+ LazyLoadScenario.setShouldLoad(false);
+
+ return m.invoke(o);
+ } catch (Exception e) {
+ // That's fine
+ return null;
+ } finally {
+ LazyLoadScenario.setShouldLoad(true);
+ m.setAccessible(access);
+ }
+ }
+
+ private static String stringValueOf(Object object) {
+ try {
+ LazyLoadScenario.setShouldLoad(false);
+ return String.valueOf(object);
+ } catch (Exception e) {
+ return "null";
+ } finally {
+ LazyLoadScenario.setShouldLoad(true);
+ }
+ }
+}
diff --git a/modules/enterprise/binding/src/main/java/org/rhq/bindings/util/LazyLoadScenario.java b/modules/enterprise/binding/src/main/java/org/rhq/bindings/util/LazyLoadScenario.java
new file mode 100644
index 0000000..8eb0128
--- /dev/null
+++ b/modules/enterprise/binding/src/main/java/org/rhq/bindings/util/LazyLoadScenario.java
@@ -0,0 +1,44 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2008 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.bindings.util;
+
+/**
+ * Set by reflective access utilities like the tabular writer to avoid
+ * remote calls behind proxy methods.
+ *
+ * @author Greg Hinkle
+ */
+public class LazyLoadScenario {
+
+ private static ThreadLocal<Boolean> shouldLoad = new ThreadLocal<Boolean>() {
+
+ protected Boolean initialValue() {
+ return true;
+ }
+ };
+
+ public static boolean isShouldLoad() {
+ return shouldLoad.get();
+ }
+
+ public static void setShouldLoad(boolean shouldLoad) {
+ LazyLoadScenario.shouldLoad.set(shouldLoad);
+ }
+
+}
diff --git a/modules/enterprise/binding/src/main/java/org/rhq/bindings/util/PackageFinder.java b/modules/enterprise/binding/src/main/java/org/rhq/bindings/util/PackageFinder.java
new file mode 100644
index 0000000..d48382f
--- /dev/null
+++ b/modules/enterprise/binding/src/main/java/org/rhq/bindings/util/PackageFinder.java
@@ -0,0 +1,132 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2008 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.bindings.util;
+
+import java.io.File;
+import java.io.FileFilter;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+import java.net.URL;
+
+/**
+ * @author Greg Hinkle
+ * @author Lukas Krejci
+ */
+public class PackageFinder {
+
+ private List<File> jarLocations;
+
+ public PackageFinder(List<File> jarLocations) {
+ this.jarLocations = new ArrayList<File>(jarLocations);
+ }
+
+ public List<String> findPackages(String packageRoot) throws IOException {
+ ArrayList<String> found = new ArrayList<String>();
+
+//TODO this is where the original package finder used to look for the jars.
+//update the code somewhere in the CLI client to supply this dir to this
+//new style impl.
+// String cwd = System.getProperty("user.dir");
+// File libDir = new File(cwd, "lib");
+
+
+ List<File> jars = new ArrayList<File>();
+
+ for (File loc : jarLocations) {
+ if (loc.exists()) {
+ jars.addAll(Arrays.asList(loc.listFiles(new FileFilter() {
+ public boolean accept(File pathname) {
+ return pathname.isFile() && pathname.getName().endsWith(".jar");
+ }
+ })));
+ }
+ }
+
+ jars.addAll(loadJARsFromClassPath(packageRoot));
+
+ for (File jar : jars) {
+ findPackages(packageRoot, found, jar);
+ }
+
+ return found;
+ }
+
+ private List<File> loadJARsFromClassPath(String pkgRoot) throws IOException {
+ List<File> jarFiles = new ArrayList<File>();
+ String pkgPath = pkgRoot.replaceAll("\\.", "/");
+ Enumeration<URL> resources = getClass().getClassLoader().getResources(pkgPath);
+ URL resource = null;
+
+ while (resources.hasMoreElements()) {
+ resource = resources.nextElement();
+ if (resource.toString().startsWith("jar:file")) {
+ String jarFilePath = getJARFilePath(resource);
+ jarFiles.add(new File(jarFilePath));
+ }
+ }
+
+ return jarFiles;
+ }
+
+ private String getJARFilePath(URL resource) {
+ int startIndex = "jar:file:".length();
+ String string = resource.toString().substring(startIndex);
+ int endIndex = string.indexOf("!");
+
+ return string.substring(0, endIndex);
+ }
+
+ private void findPackages(String packageRoot, List<String> list, File jar) throws IOException {
+
+ Set<String> paths = new HashSet<String>();
+ JarFile jf = null;
+ try {
+ jf = new JarFile(jar);
+
+ String packagePath = packageRoot.replaceAll("\\.", "/");
+
+ Enumeration<JarEntry> entries = jf.entries();
+
+ while (entries.hasMoreElements()) {
+ JarEntry entry = entries.nextElement();
+
+ if (entry.getName().startsWith(packagePath)) {
+ String match = entry.getName().substring(0, entry.getName().lastIndexOf("/"));
+ paths.add(match.replaceAll("/", "\\."));
+ }
+ }
+ list.addAll(paths);
+ } finally {
+ try {
+ if (jf != null) {
+ jf.close();
+ }
+ } catch (IOException e) {
+
+ }
+ }
+ }
+}
diff --git a/modules/enterprise/binding/src/main/java/org/rhq/bindings/util/ShortOutput.java b/modules/enterprise/binding/src/main/java/org/rhq/bindings/util/ShortOutput.java
new file mode 100644
index 0000000..c7f68e3
--- /dev/null
+++ b/modules/enterprise/binding/src/main/java/org/rhq/bindings/util/ShortOutput.java
@@ -0,0 +1,27 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2008 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.bindings.util;
+
+/**
+ * @author Greg Hinkle
+ */
+public interface ShortOutput {
+
+ String getShortOutput();
+}
diff --git a/modules/enterprise/binding/src/main/java/org/rhq/bindings/util/SummaryFilter.java b/modules/enterprise/binding/src/main/java/org/rhq/bindings/util/SummaryFilter.java
new file mode 100644
index 0000000..871484f
--- /dev/null
+++ b/modules/enterprise/binding/src/main/java/org/rhq/bindings/util/SummaryFilter.java
@@ -0,0 +1,127 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2008 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.bindings.util;
+
+import org.rhq.core.domain.util.Summary;
+
+import java.beans.BeanInfo;
+import java.beans.IntrospectionException;
+import java.beans.Introspector;
+import java.beans.PropertyDescriptor;
+import java.beans.IndexedPropertyDescriptor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.Map;
+
+public class SummaryFilter {
+
+
+
+ public PropertyDescriptor[] getPropertyDescriptors(Object object, boolean exportMode) throws IntrospectionException {
+
+ BeanInfo info = Introspector.getBeanInfo(object.getClass(), object.getClass().getSuperclass());
+
+ final Map<PropertyDescriptor, Integer> indexes = new HashMap<PropertyDescriptor, Integer>();
+
+
+
+ for (PropertyDescriptor property : info.getPropertyDescriptors()) {
+ boolean add = false;
+ int index = 100;
+ try {
+ Field field = getField(property);
+
+ if (field.isAnnotationPresent(Summary.class)) {
+ add = true;
+ index = field.getAnnotation(Summary.class).index();
+ } else if (property.getReadMethod() != null && property.getReadMethod().isAnnotationPresent(Summary.class)) {
+ add = true;
+ index = property.getReadMethod().getAnnotation(Summary.class).index();
+ }
+
+ } catch (NoSuchFieldException e) {
+ if (property.getReadMethod() != null && property.getReadMethod().isAnnotationPresent(Summary.class)) {
+ add = true;
+ index = property.getReadMethod().getAnnotation(Summary.class).index();
+ }
+ }
+ if (add || exportMode) {
+ indexes.put(property, index);
+ }
+ }
+
+ if (indexes.isEmpty()) {
+ for (PropertyDescriptor property : info.getPropertyDescriptors()) {
+ indexes.put(property, 0);
+ }
+ }
+
+
+ PropertyDescriptor[] descriptors;
+ descriptors = indexes.keySet().toArray(new PropertyDescriptor[indexes.size()]);
+ Arrays.sort(descriptors, new Comparator<PropertyDescriptor>() {
+ public int compare(PropertyDescriptor o1, PropertyDescriptor o2) {
+ int i = indexes.get(o1).compareTo(indexes.get(o2));
+ if (i == 0) {
+ i = o1.getName().compareTo(o2.getName());
+ }
+ return i;
+ }
+ });
+
+ return descriptors;
+ }
+
+
+ private Field getField(PropertyDescriptor property) throws NoSuchFieldException {
+ String propertyName = property.getName();
+ Class<?> declaringClass = getDeclaringClass(property);
+
+ return declaringClass.getDeclaredField(propertyName);
+ }
+
+ private Class<?> getDeclaringClass(PropertyDescriptor property) {
+ Method method = null;
+
+ if (property instanceof IndexedPropertyDescriptor) {
+ method = ((IndexedPropertyDescriptor)property).getIndexedReadMethod();
+ if (method == null) {
+ method = ((IndexedPropertyDescriptor)property).getIndexedWriteMethod();
+ }
+ } else {
+ method = property.getReadMethod();
+
+ if (method == null) {
+ method = property.getWriteMethod();
+ }
+ }
+
+ return method.getDeclaringClass();
+
+ }
+
+
+}
diff --git a/modules/enterprise/binding/src/test/java/org/rhq/bindings/TabularWriterTest.java b/modules/enterprise/binding/src/test/java/org/rhq/bindings/TabularWriterTest.java
new file mode 100644
index 0000000..a80d2c2
--- /dev/null
+++ b/modules/enterprise/binding/src/test/java/org/rhq/bindings/TabularWriterTest.java
@@ -0,0 +1,397 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2008 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.bindings;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.OneToMany;
+import javax.persistence.OneToOne;
+
+import org.apache.commons.lang.StringUtils;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import org.rhq.bindings.output.TabularWriter;
+import org.rhq.core.domain.measurement.AvailabilityType;
+import org.rhq.core.domain.resource.Resource;
+import org.rhq.core.domain.shared.ResourceBuilder;
+
+import static org.testng.Assert.*;
+
+public class TabularWriterTest {
+
+ StringWriter stringWriter;
+
+ TabularWriter writer;
+
+ @BeforeMethod
+ public void initFixture() {
+ stringWriter = new StringWriter();
+ writer = new TabularWriter(new PrintWriter(stringWriter));
+ }
+
+ @Test
+ public void aByteShouldPrintUnchanged() {
+ byte value = 1;
+
+ writer.print(value);
+
+ String expected = "1\n";
+ String actual = stringWriter.toString();
+
+ assertEquals(actual, expected, "A byte or Byte should have its value printed as a String");
+ }
+
+ @Test
+ public void anIntegerShouldPrintUnchanged() {
+ int value = 1;
+
+ writer.print(value);
+
+ String expected = "1\n";
+ String actual = stringWriter.toString();
+
+ assertEquals(actual, expected, "An int or Integer should have its value printed as a String");
+ }
+
+ @Test
+ public void theSimpleClassNameShouldPrintFirstForEntity() {
+ User user = new User(1, "rhqadmin", "rhqadmin");
+
+ writer.print(user);
+
+ assertNumberOfLinesPrintedIs(4);
+ assertLineEquals(0, user.getClass().getSimpleName() + ":", "The simple class name should be the first line printed");
+ }
+
+ @Test
+ public void theIdShouldBeTheFirstPropertyPrintedForEntity() {
+ User user = new User(1, "rhqadmin", "rhqadmin");
+
+ writer.print(user);
+
+ int paddingSize = "username".length();
+ int idLineNumber = 1;
+ String expected = "\t" + StringUtils.leftPad("id", paddingSize) + ": " + user.getId();
+
+ assertLineEquals(idLineNumber, expected, "The id property should be the 2nd line printed");
+ }
+
+ @Test
+ public void otherPropertiesShouldPrintAfterIdForEntity() {
+ User user = new User(1, "rhqadmin", "rhqadmin");
+
+ writer.print(user);
+
+ int passwordLineNumber = 2;
+ String expectedPasswordLine = "\tpassword: " + user.getPassword();
+
+ assertLineEquals(passwordLineNumber, expectedPasswordLine, "The password property should be the 3rd line printed");
+
+ int usernameLineNumber = 3;
+ String expectedUsernameLine = "\tusername: " + user.getUsername();
+
+ assertLineEquals(usernameLineNumber, expectedUsernameLine, "The username property should be the 4th line printed");
+ }
+
+ @Test
+ public void oneToOneAssociationShouldPrintForAnEntity() {
+ User mgr = new User(1, "rhqadmin", "rhqadmin");
+ Department department = new Department(1, mgr);
+
+ writer.print(department);
+
+ int lineNumber = 2;
+ String expectedLine = "\tmanager: " + mgr;
+
+ assertLineEquals(lineNumber, expectedLine, "The manager property should be the 3rd line printed");
+ }
+
+ @Test(enabled = false) // TODO revisit
+ public void oneToManyAssociationShouldPrintForEntity() {
+ User employee = new User(1, "rhq", "rhq");
+
+ Company company = new Company(1);
+ company.addEmployee(employee);
+
+ writer.print(company);
+
+ int lineNumber = 2;
+ String expectedLine = "\temployees: " + company.getEmployees();
+
+ assertLineEquals(lineNumber, expectedLine, "The employees property should be the 2nd line printed and the " +
+ "toString() value of the collection should be displayed.");
+ }
+
+ @Test
+ public void idShouldBeFirstResourcePropertyPrinted() {
+ Resource resource = createResource();
+
+ writer.print(resource);
+
+ assertLineEquals(
+ 1,
+ "\t" + padResourceField("id") + ": " + resource.getId(),
+ "Expected Resource.id to be the first property printed."
+ );
+ }
+
+ @Test
+ public void nameShouldBeSecondResourcePropertyPrinted() {
+ Resource resource = createResource();
+
+ writer.print(resource);
+
+ assertLineEquals(
+ 2,
+ "\t" + padResourceField("name") + ": " + resource.getName(),
+ "Expected Resource.name to be second property printed"
+ );
+ }
+
+ @Test
+ public void versionShouldBeThirdResourcePropertyPrinted() {
+ Resource resource = createResource();
+
+ writer.print(resource);
+
+ assertLineEquals(
+ 3,
+ "\t" + padResourceField("version") + ": " + resource.getVersion(),
+ "Expected Resource.version to be third property printed"
+ );
+ }
+
+ @Test
+ public void currentAvailabilityShouldBeFourthResourcePropertyPrinted() {
+ Resource resource = createResource();
+
+ writer.print(resource);
+
+ assertLineEquals(
+ 4,
+ "\t" + padResourceField("currentAvailability") + ": " + resource.getCurrentAvailability().getAvailabilityType(),
+ "Expected short version of Resource.currentAvailability to be fourth property printed"
+ );
+ }
+
+ @Test
+ public void handleNullCurrentAvailabilityForResource() {
+ Resource resource = createUncommittedResource();
+
+ writer.print(resource);
+
+ assertLineEquals(
+ 4,
+ "\t" + padResourceField("currentAvailability") + ": ",
+ "Expected to see empty string for Resource.currentAvailability when property is null"
+ );
+ }
+
+ @Test
+ public void resourceTypeShouldBeLastResourcePropertyPrinted() {
+ Resource resource = createResource();
+
+ writer.print(resource);
+
+ assertLineEquals(
+ 5,
+ "\t" + padResourceField("resourceType") + ": " + resource.getResourceType().getName(),
+ "Expected short version of Resource.resourceType to be the fifth property printed"
+ );
+ }
+
+ private Resource createResource() {
+ return new ResourceBuilder().createServer()
+ .usingDefaultResourceType()
+ .withId(111)
+ .withName("test-server")
+ .withUuid("12345")
+ .withVersion("1.0")
+ .inInventory()
+ .withCurrentAvailability(AvailabilityType.UP)
+ .build();
+ }
+
+ private Resource createUncommittedResource() {
+ return new ResourceBuilder().createServer()
+ .usingDefaultResourceType()
+ .withId(111)
+ .withName("test-server")
+ .withUuid("12345")
+ .withVersion("1.0")
+ .notInInventory()
+ .build();
+ }
+
+ @Test
+ public void printCollectionOfUncommittedResource() {
+ Resource parent = new ResourceBuilder().createServer()
+ .usingDefaultResourceType()
+ .withName("test-server")
+ .withUuid("12345")
+ .withVersion("1.0")
+ .inInventory()
+ .with(2).randomChildServices()
+// .notInInventory()
+// .included()
+ .build();
+
+ writer.print(parent.getChildResources());
+ }
+
+ void assertNumberOfLinesPrintedIs(int expectedNumberOfLines) {
+ String lines[] = getLines();
+ assertEquals(lines.length, expectedNumberOfLines, "The actual lines printed were\n[\n" +
+ stringWriter.toString() + "\n]");
+ }
+
+ void assertLineEquals(int lineNumber, String expectedLine, String msg) {
+ String actualLine = getLines()[lineNumber];
+
+ assertEquals(actualLine, expectedLine, msg + " -- The actual output was \n[\n" + stringWriter + "\n].");
+ }
+
+ String[] getLines() {
+ return stringWriter.toString().split("\n");
+ }
+
+ String padResourceField(String field) {
+ return StringUtils.leftPad(field, "currentAvailability".length());
+ }
+
+ @Entity
+ static class User {
+ @Id
+ private int id;
+
+ private String username;
+
+ private String password;
+
+ public User(int id, String username, String password) {
+ this.id = id;
+ this.username = username;
+ this.password = password;
+ }
+
+ public int getId() {
+ return id;
+ }
+
+ public void setId(int id) {
+ this.id = id;
+ }
+
+ public String getUsername() {
+ return username;
+ }
+
+ public void setUsername(String username) {
+ this.username = username;
+ }
+
+ public String getPassword() {
+ return password;
+ }
+
+ public void setPassword(String password) {
+ this.password = password;
+ }
+
+ @Override
+ public String toString() {
+ return User.class.getSimpleName() + "[id=" + id + ", username=" + username + ", password=" + password + "]";
+ }
+ }
+
+ @Entity
+ static class Department {
+ @Id
+ private int id;
+
+ @OneToOne
+ private User manager;
+
+ public Department(int id, User manager) {
+ this.id = id;
+ this.manager = manager;
+ }
+
+ public int getId() {
+ return id;
+ }
+
+ public void setId(int id) {
+ this.id = id;
+ }
+
+ public User getManager() {
+ return manager;
+ }
+
+ public void setManager(User manager) {
+ this.manager = manager;
+ }
+ }
+
+ @Entity
+ static class Company {
+ @Id
+ private int id;
+
+ @OneToMany
+ private List<User> employees = new ArrayList<User>();
+
+ public Company(int id) {
+ this.id = id;
+ }
+
+ public int getId() {
+ return id;
+ }
+
+ public void setId(int id) {
+ this.id = id;
+ }
+
+ public List<User> getEmployees() {
+ return employees;
+ }
+
+ public void setEmployees(List<User> employees) {
+ this.employees = employees;
+ }
+
+ public void addEmployee(User employee) {
+ employees.add(employee);
+ }
+ }
+
+}
diff --git a/modules/enterprise/remoting/cli/src/main/java/org/rhq/enterprise/client/SummaryFilter.java b/modules/enterprise/remoting/cli/src/main/java/org/rhq/enterprise/client/SummaryFilter.java
deleted file mode 100644
index bc4151b..0000000
--- a/modules/enterprise/remoting/cli/src/main/java/org/rhq/enterprise/client/SummaryFilter.java
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * RHQ Management Platform
- * Copyright (C) 2005-2008 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.client;
-
-import org.rhq.core.domain.util.Summary;
-
-import java.beans.BeanInfo;
-import java.beans.IntrospectionException;
-import java.beans.Introspector;
-import java.beans.PropertyDescriptor;
-import java.beans.IndexedPropertyDescriptor;
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-import java.util.Arrays;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.Map;
-
-public class SummaryFilter {
-
-
-
- public PropertyDescriptor[] getPropertyDescriptors(Object object, boolean exportMode) throws IntrospectionException {
-
- BeanInfo info = Introspector.getBeanInfo(object.getClass(), object.getClass().getSuperclass());
-
- final Map<PropertyDescriptor, Integer> indexes = new HashMap<PropertyDescriptor, Integer>();
-
-
-
- for (PropertyDescriptor property : info.getPropertyDescriptors()) {
- boolean add = false;
- int index = 100;
- try {
- Field field = getField(property);
-
- if (field.isAnnotationPresent(Summary.class)) {
- add = true;
- index = field.getAnnotation(Summary.class).index();
- } else if (property.getReadMethod() != null && property.getReadMethod().isAnnotationPresent(Summary.class)) {
- add = true;
- index = property.getReadMethod().getAnnotation(Summary.class).index();
- }
-
- } catch (NoSuchFieldException e) {
- if (property.getReadMethod() != null && property.getReadMethod().isAnnotationPresent(Summary.class)) {
- add = true;
- index = property.getReadMethod().getAnnotation(Summary.class).index();
- }
- }
- if (add || exportMode) {
- indexes.put(property, index);
- }
- }
-
- if (indexes.isEmpty()) {
- for (PropertyDescriptor property : info.getPropertyDescriptors()) {
- indexes.put(property, 0);
- }
- }
-
-
- PropertyDescriptor[] descriptors;
- descriptors = indexes.keySet().toArray(new PropertyDescriptor[indexes.size()]);
- Arrays.sort(descriptors, new Comparator<PropertyDescriptor>() {
- public int compare(PropertyDescriptor o1, PropertyDescriptor o2) {
- int i = indexes.get(o1).compareTo(indexes.get(o2));
- if (i == 0) {
- i = o1.getName().compareTo(o2.getName());
- }
- return i;
- }
- });
-
- return descriptors;
- }
-
-
- private Field getField(PropertyDescriptor property) throws NoSuchFieldException {
- String propertyName = property.getName();
- Class<?> declaringClass = getDeclaringClass(property);
-
- return declaringClass.getDeclaredField(propertyName);
- }
-
- private Class<?> getDeclaringClass(PropertyDescriptor property) {
- Method method = null;
-
- if (property instanceof IndexedPropertyDescriptor) {
- method = ((IndexedPropertyDescriptor)property).getIndexedReadMethod();
- if (method == null) {
- method = ((IndexedPropertyDescriptor)property).getIndexedWriteMethod();
- }
- } else {
- method = property.getReadMethod();
-
- if (method == null) {
- method = property.getWriteMethod();
- }
- }
-
- return method.getDeclaringClass();
-
- }
-
-
-}
diff --git a/modules/enterprise/remoting/cli/src/main/java/org/rhq/enterprise/client/TabularWriter.java b/modules/enterprise/remoting/cli/src/main/java/org/rhq/enterprise/client/TabularWriter.java
deleted file mode 100644
index 4b63c4e..0000000
--- a/modules/enterprise/remoting/cli/src/main/java/org/rhq/enterprise/client/TabularWriter.java
+++ /dev/null
@@ -1,708 +0,0 @@
-/*
- * RHQ Management Platform
- * Copyright (C) 2005-2008 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.client;
-
-import java.beans.IntrospectionException;
-import java.beans.PropertyDescriptor;
-import java.io.PrintWriter;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.LinkedHashMap;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import au.com.bytecode.opencsv.CSVWriter;
-
-import org.rhq.core.domain.configuration.Configuration;
-import org.rhq.core.domain.configuration.Property;
-import org.rhq.core.domain.configuration.PropertyList;
-import org.rhq.core.domain.configuration.PropertyMap;
-import org.rhq.core.domain.configuration.PropertySimple;
-import org.rhq.core.domain.measurement.ResourceAvailability;
-import org.rhq.core.domain.resource.ResourceType;
-import org.rhq.enterprise.client.utility.LazyLoadScenario;
-import org.rhq.enterprise.client.utility.ShortOutput;
-
-/**
- * @author Greg Hinkle
- */
-public class TabularWriter {
-
- private static final String CSV = "csv";
-
- String[] headers;
- int[] maxColumnLength;
- boolean[] noShrinkColumns;
- int width = 160;
- PrintWriter out;
- private String format = "raw";
- private CSVWriter csvWriter;
- private SummaryFilter summaryFilter = new SummaryFilter();
- boolean exportMode;
-
- static Set<String> IGNORED_PROPS = new HashSet<String>();
-
- static {
- IGNORED_PROPS.add("mtime");
- IGNORED_PROPS.add("ctime");
- IGNORED_PROPS.add("itime");
- IGNORED_PROPS.add("uuid");
- IGNORED_PROPS.add("parentResource");
- }
-
- static Set<Class> SIMPLE_TYPES = new HashSet<Class>();
-
- static {
- SIMPLE_TYPES.add(Byte.class);
- SIMPLE_TYPES.add(Byte.TYPE);
- SIMPLE_TYPES.add(Short.class);
- SIMPLE_TYPES.add(Short.TYPE);
- SIMPLE_TYPES.add(Integer.class);
- SIMPLE_TYPES.add(Integer.TYPE);
- SIMPLE_TYPES.add(Long.class);
- SIMPLE_TYPES.add(Long.TYPE);
- SIMPLE_TYPES.add(Float.class);
- SIMPLE_TYPES.add(Float.TYPE);
- SIMPLE_TYPES.add(Double.class);
- SIMPLE_TYPES.add(Double.TYPE);
- SIMPLE_TYPES.add(Boolean.class);
- SIMPLE_TYPES.add(Boolean.TYPE);
- SIMPLE_TYPES.add(String.class);
- }
-
- public TabularWriter(PrintWriter out, String... headers) {
- this.headers = headers;
- this.out = out;
- }
-
- public TabularWriter(PrintWriter out) {
- this.out = out;
- }
-
- public TabularWriter(PrintWriter out, String format) {
- this.out = out;
- this.format = format;
-
- if (CSV.equals(format)) {
- csvWriter = new CSVWriter(out);
- }
- }
-
- public void print(Object object) {
-
- if (object instanceof Map) {
- print((Map) object);
- return;
- }
-
- if (object instanceof Collection) {
- print((Collection) object);
- return;
- }
-
- if (object instanceof Configuration) {
- print((Configuration) object);
- return;
- }
-
- if (object != null && object.getClass().isArray()) {
- print((Object[]) object);
- return;
- }
-
- try {
-
- if (SIMPLE_TYPES.contains(object.getClass())) {
- this.out.println(String.valueOf(object));
- return;
- }
-
- out.println(object.getClass().getSimpleName() + ":");
- Map<String, PropertyInfo> properties = new LinkedHashMap<String, PropertyInfo>();
- int maxLength = 0;
-
- for (PropertyDescriptor pd : summaryFilter.getPropertyDescriptors(object, exportMode)) {
- Method m = pd.getReadMethod();
- Object val = null;
- if (m != null) {
- val = invoke(object, m);
- }
-
- if (val == null) {
- maxLength = Math.max(maxLength, pd.getName().length());
- properties.put(pd.getName(), new PropertyInfo(pd.getName(), null));
- } else {
- try {
- String str = shortVersion(val);
- maxLength = Math.max(maxLength, pd.getName().length());
- properties.put(pd.getName(), new PropertyInfo(str, pd.getPropertyType()));
- } catch (Exception e) {
- }
- }
- }
-
- for (String key : properties.keySet()) {
- printProperty(key, properties.get(key), maxLength);
- }
-
- } catch (InvocationTargetException e) {
- e.printStackTrace();
- } catch (IllegalAccessException e) {
- e.printStackTrace();
- } catch (IntrospectionException e) {
- e.printStackTrace();
- }
-
- }
-
- private static class PropertyInfo {
- String value;
-
- Class<?> type;
-
- PropertyInfo(String propertyValue, Class<?> propertyType) {
- value = propertyValue;
- type = propertyType;
- }
- }
-
- private void printProperty(String name, PropertyInfo propertyInfo, int maxLength) {
- out.print("\t");
- printPreSpaced(out, name, maxLength);
- out.print(": ");
-
- if (propertyInfo.type == null) {
- out.println("");
- } else if (exportMode || !String.class.equals(propertyInfo.type)) {
- out.println(propertyInfo.value);
- } else {
- out.println(abbreviate(propertyInfo.value, width - 12 - maxLength));
- }
- }
-
- // This method is taken verbatim from the Commons Lang project in the org.apache.commons.lang.StringUtils class
- // TODO Should this method go into one our StringUtil classes?
- private String abbreviate(String string, int maxWidth) {
- int offset = 0;
-
- if (string == null) {
- return null;
- }
-
- if (maxWidth < 4) {
- throw new IllegalArgumentException("Minimum abbreviation width is 4");
- }
-
- if (string.length() <= maxWidth) {
- return string;
- }
-
- if (offset > string.length()) {
- offset = string.length();
- }
-
- if ((string.length() - offset) < (maxWidth - 3)) {
- offset = string.length() - (maxWidth - 3);
- }
-
- if (offset <= 4) {
- return string.substring(0, maxWidth - 3) + "...";
- }
-
- if (maxWidth < 7) {
- throw new IllegalArgumentException("Minimum abbreviation width with offset is 7");
- }
-
- if ((offset + (maxWidth - 3)) < string.length()) {
- return "..." + abbreviate(string.substring(offset), maxWidth - 3);
- }
-
- return "..." + string.substring(string.length() - (maxWidth - 3));
- }
-
- public void print(Map map) {
-
- String[][] data = new String[map.size()][];
- int i = 0;
- for (Object key : map.keySet()) {
- Object value = map.get(key);
- data[i] = new String[2];
- data[i][0] = shortVersion(key);
- data[i][1] = shortVersion(value);
- i++;
- }
- this.headers = new String[] { "Key", "Value" };
- print(data);
- }
-
- public void print(Collection list) {
- // List of arbitrary objects
- if (list == null || list.size() == 0)
- out.println("no data");
- else if (list.size() == 1 && !CSV.equals(format)) {
- out.println("one row");
-
- print(list.iterator().next());
- } else {
-
- String[][] data = null;
-
- if (!allOneType(list)) {
- printStrings(list);
- } else {
-
- Object firstObject = list.iterator().next();
- try {
-
- if (firstObject instanceof String) {
- headers = new String[] { "Value" };
- data = new String[list.size()][1];
- int i = 0;
- for (Object object : list) {
- data[i++][0] = (String) object;
- }
-
- } else {
-
- if (consistentMaps(list)) {
- // results printed
-
- } else {
-
- int i = 0;
-
- List<PropertyDescriptor> pdList = new ArrayList<PropertyDescriptor>();
- for (PropertyDescriptor pd : summaryFilter.getPropertyDescriptors(firstObject, exportMode)) {
- try {
- boolean allNull = true;
- for (Object row : list) {
- Method m = pd.getReadMethod();
- Object val = null;
- if (m != null) {
- val = invoke(row, pd.getReadMethod());
- }
- if ((val != null && !(val instanceof Collection))
- || ((val != null && (val instanceof Collection) && !((Collection) val)
- .isEmpty())))
- allNull = false;
- }
- if (!allNull && !IGNORED_PROPS.contains(pd.getName())) {
- pdList.add(pd);
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
-
- headers = new String[pdList.size()];
- data = new String[list.size()][pdList.size()];
-
- for (PropertyDescriptor pd : pdList) {
- headers[i++] = pd.getName();
- }
- i = 0;
- for (Object row : list) {
- int j = 0;
- for (PropertyDescriptor pd : pdList) {
-
- Object val = "?";
- val = invoke(row, pd.getReadMethod());
- if (val == null) {
- data[i][j++] = "";
- } else {
- data[i][j++] = shortVersion(val);
- }
- }
- i++;
- }
-
- this.print(data);
-
- }
- }
- } catch (Exception e) {
- e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
- } finally {
- headers = null;
- }
- }
-
- }
-
- }
-
- private boolean consistentMaps(Collection list) {
- List<String> keys = null;
- String[][] data = new String[list.size()][];
- int i = 0;
- for (Object row : list) {
- if (!(row instanceof Map) && !(row instanceof PropertyMap)) {
- return false;
- }
- if (keys == null) {
- keys = new ArrayList<String>();
-
- //insert check for PropertyMap as they are not instances of Map
- if (row instanceof PropertyMap) {
- //TODO: spinder 1/15/10. PropertyMap is arbitrarily complex. Only serialize simple props?
- for (Object key : ((PropertyMap) row).getMap().keySet()) {
- String headerKey = stringValueOf(key);
- keys.add(headerKey);
- }
- } else {//else row is a Map
- for (Object key : ((Map) row).keySet()) {
- String headerKey = stringValueOf(key);
- keys.add(headerKey);
- }
- }
- //conditionally put order on the headers to mimic core gui listing style/order
- //Ex. Pid Name Size User Time Kernel Time
- if (keys.contains("pid")) {
- String[] processAttribute = { "pid", "name", "size", "userTime", "kernelTime" };
- List<String> newKeyOrder = new ArrayList<String>();
- for (String attribute : processAttribute) {
- newKeyOrder.add(attribute);
- keys.remove(attribute);
- }
- //postpend remaining keys if any to the newHeader list
- for (String key : keys) {
- newKeyOrder.add(key);
- }
- keys = newKeyOrder;
- }
- }
-
- data[i] = new String[keys.size()];
- if (row instanceof PropertyMap) {
- for (String key : keys) {
- if (!keys.contains(stringValueOf(key))) {
- return false;
- }
- data[i][keys.lastIndexOf(stringValueOf(key))] = shortVersion(((PropertyMap) row).get(String
- .valueOf(key)));
- }
- } else {//else row is a Map
- for (Object key : ((Map) row).keySet()) {
- if (!keys.contains(stringValueOf(key))) {
- return false;
- }
- data[i][keys.lastIndexOf(stringValueOf(key))] = shortVersion(((Map) row).get(key));
- }
- }
- i++;
- }
-
- if (keys != null) {
- headers = keys.toArray(new String[keys.size()]);
- print(data);
- return true;
- } else {
- return false;
- }
-
- }
-
- public void print(Configuration config) {
- out.println("Configuration [" + config.getId() + "] - " + config.getNotes());
- for (PropertySimple p : config.getSimpleProperties().values()) {
- print(p, 1);
- }
- for (PropertyList p : config.getListProperties().values()) {
- print(p, 1);
- }
- for (PropertyMap p : config.getMapProperties().values()) {
- print(p, 1);
- }
-
- }
-
- public void print(PropertySimple p, int depth) {
- out.println(indent(depth) + p.getName() + " = " + p.getStringValue());
- }
-
- public void print(PropertyList p, int depth) {
- out.println(indent(depth) + p.getName() + " [" + p.getList().size() + "] {");
- if (p.getList().get(0) instanceof PropertyMap) {
- consistentMaps(p.getList());
-
- } else {
- for (Property entry : p.getList()) {
- if (entry instanceof PropertySimple) {
- print((PropertySimple) entry, depth + 1);
- } else if (entry instanceof PropertyMap) {
- print((PropertyMap) entry, depth + 1);
- }
- }
- }
-
- out.println(indent(depth) + "}");
- }
-
- public void print(PropertyMap p, int depth) {
- out.println(indent(depth) + p.getName() + " [" + p.getMap().size() + "] {");
- for (String key : p.getMap().keySet()) {
- Property entry = p.getMap().get(key);
- if (entry instanceof PropertySimple) {
- print((PropertySimple) entry, depth + 1);
- } else if (entry instanceof PropertyMap) {
- print((PropertyMap) entry, depth + 1);
- }
- }
- out.println(indent(depth) + "}");
- }
-
- private String indent(int x) {
- StringBuilder buf = new StringBuilder();
- for (int i = 0; i < x; i++) {
- buf.append(" ");
- }
- return buf.toString();
- }
-
- private void printStrings(Collection list) {
- for (Object object : list) {
- out.println(stringValueOf(object));
- }
- }
-
- private boolean allOneType(Collection list) {
- Class lastClass = null;
- for (Object object : list) {
- if (lastClass == null) {
- lastClass = object.getClass();
- } else if (!object.getClass().equals(lastClass)) {
- return false;
- }
- }
- return true;
- }
-
- public void print(Object[] data) {
- if (data == null || data.length == 0) {
- out.println("0 rows");
- return;
- }
- out.println("Array of " + (data.getClass().getComponentType().getName()));
-
- print(Arrays.asList(data));
- }
-
- private void resizeColumns(int[] actualColumnWidths, int maxColumnWidth, List<Integer> columns) {
- int extraSpace = 0;
-
- Iterator<Integer> iterator = columns.iterator();
- while (iterator.hasNext()) {
- int col = iterator.next();
-
- if (actualColumnWidths[col] < maxColumnWidth) {
- extraSpace += maxColumnWidth - actualColumnWidths[col];
- iterator.remove();
- }
- }
-
- if (extraSpace == 0) {
- // There is no extra space with which to work so at this point we have to
- // truncate any columns that still need more space
- for (Integer col : columns) {
- actualColumnWidths[col] = maxColumnWidth;
- }
- }
- else if (columns.size() == 0) {
- // If the columns list is empty then that means that there is enough available
- // space for each column so we are done.
- return;
- }
- else if (extraSpace > 0) {
- // Since we have extra space, we will go ahead and recalculate the widths for
- // those columns still needing space
- int newMaxColumnWidth = (maxColumnWidth + extraSpace) / columns.size();
- resizeColumns(actualColumnWidths, newMaxColumnWidth, columns);
- }
- }
-
- public void print(String[][] data) {
-
- if (data == null || data.length == 0) {
- out.println("0 rows");
- return;
- }
-
- int numberOfColumns = data[0].length;
- int maxColumnWidth = width / numberOfColumns;
- int[] actualColumnWidths = new int[numberOfColumns];
-
- for (String[] row : data) {
- for (int col = 0; col < row.length; ++col) {
- if (row[col] == null) {
- row[col] = "";
- }
- actualColumnWidths[col] = Math.max(actualColumnWidths[col], row[col].length());
- }
- }
-
- if (headers != null) {
- for (int col = 0; col < headers.length; ++col) {
- actualColumnWidths[col] = Math.max(actualColumnWidths[col], headers[col].length());
- }
- }
-
- List<Integer> columns = new LinkedList();
- for (int col = 0; col < actualColumnWidths.length; ++col) {
- columns.add(col);
- }
- resizeColumns(actualColumnWidths, maxColumnWidth, columns);
-
- if (headers != null) {
- if (CSV.equals(format)) {
- csvWriter.writeNext(headers);
- } else {
- for (int i = 0; i < actualColumnWidths.length; i++) {
- int colSize = actualColumnWidths[i];
- printSpaced(out, headers[i], colSize);
- if (i < actualColumnWidths.length - 1) {
- out.print(" ");
- }
- }
-
- out.print("\n");
-
- for (int i = 1; i < width; i++) {
- out.print("-");
- }
- }
- out.print("\n");
-
- }
-
- if (CSV.equals(format)) {
- for (String[] row : data) {
- csvWriter.writeNext(row);
- }
- } else {
- for (String[] row : data) {
- for (int i = 0; i < actualColumnWidths.length; i++) {
- int colSize = actualColumnWidths[i];
-
- printSpaced(out, row[i], colSize);
- if (i < actualColumnWidths.length - 1) {
- out.print(" ");
- }
- }
- out.print("\n");
- }
- }
-
- out.print(data.length + " rows\n");
- }
-
- private void printSpaced(PrintWriter out, String data, int length) {
- int dataLength = data.length();
- if (dataLength > length) {
- out.print(data.substring(0, length));
- } else {
- out.print(data);
-
- for (int i = dataLength; i < length; i++) {
- out.print(" ");
- }
- }
-
- }
-
- private void printPreSpaced(PrintWriter out, String data, int length) {
- int dataLength = data.length();
- if (dataLength > length) {
- out.print(data.substring(0, length));
- } else {
- for (int i = dataLength; i < length; i++) {
- out.print(" ");
- }
- out.print(data);
- }
-
- }
-
- public int getWidth() {
- return width;
- }
-
- public void setWidth(int width) {
- this.width = width;
- }
-
- public boolean isExportMode() {
- return exportMode;
- }
-
- public void setExportMode(boolean exportMode) {
- this.exportMode = exportMode;
- }
-
- private static String shortVersion(Object object) {
-
- if (object instanceof ShortOutput) {
- return ((ShortOutput) object).getShortOutput();
- } else if (object instanceof PropertySimple) {
- return ((PropertySimple) object).getStringValue();
- } else if (object instanceof ResourceType) {
- return ((ResourceType) object).getName();
- } else if (object instanceof ResourceAvailability) {
- return ((ResourceAvailability) object).getAvailabilityType().getName();
- } else if (object != null && object.getClass().isArray()) {
- return Arrays.toString((Object[]) object);
- } else {
- return stringValueOf(object);
- }
- }
-
- private static Object invoke(Object o, Method m) throws IllegalAccessException, InvocationTargetException {
- boolean access = m.isAccessible();
- m.setAccessible(true);
- try {
- LazyLoadScenario.setShouldLoad(false);
-
- return m.invoke(o);
- } catch (Exception e) {
- // That's fine
- return null;
- } finally {
- LazyLoadScenario.setShouldLoad(true);
- m.setAccessible(access);
- }
- }
-
- private static String stringValueOf(Object object) {
- try {
- LazyLoadScenario.setShouldLoad(false);
- return String.valueOf(object);
- } catch (Exception e) {
- return "null";
- } finally {
- LazyLoadScenario.setShouldLoad(true);
- }
- }
-}
diff --git a/modules/enterprise/remoting/cli/src/main/java/org/rhq/enterprise/client/commands/HelpCommand.java b/modules/enterprise/remoting/cli/src/main/java/org/rhq/enterprise/client/commands/HelpCommand.java
index ab3023b..abddad4 100644
--- a/modules/enterprise/remoting/cli/src/main/java/org/rhq/enterprise/client/commands/HelpCommand.java
+++ b/modules/enterprise/remoting/cli/src/main/java/org/rhq/enterprise/client/commands/HelpCommand.java
@@ -32,8 +32,8 @@ import java.util.Comparator;
import java.util.List;
import java.util.Map;
+import org.rhq.bindings.output.TabularWriter;
import org.rhq.enterprise.client.ClientMain;
-import org.rhq.enterprise.client.TabularWriter;
import org.rhq.enterprise.client.Controller;
import org.rhq.enterprise.client.utility.ReflectionUtility;
diff --git a/modules/enterprise/remoting/cli/src/main/java/org/rhq/enterprise/client/commands/ScriptCommand.java b/modules/enterprise/remoting/cli/src/main/java/org/rhq/enterprise/client/commands/ScriptCommand.java
index 4aed6bd..ca3a185 100644
--- a/modules/enterprise/remoting/cli/src/main/java/org/rhq/enterprise/client/commands/ScriptCommand.java
+++ b/modules/enterprise/remoting/cli/src/main/java/org/rhq/enterprise/client/commands/ScriptCommand.java
@@ -20,12 +20,14 @@ package org.rhq.enterprise.client.commands;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+
+import org.rhq.bindings.export.Exporter;
+import org.rhq.bindings.output.TabularWriter;
+import org.rhq.bindings.util.PackageFinder;
import org.rhq.core.domain.util.PageControl;
import org.rhq.enterprise.client.ClientMain;
import org.rhq.enterprise.client.Controller;
-import org.rhq.enterprise.client.export.Exporter;
import org.rhq.enterprise.client.RemoteClient;
-import org.rhq.enterprise.client.TabularWriter;
import org.rhq.enterprise.client.proxy.ResourceClientFactory;
import org.rhq.enterprise.client.proxy.ConfigurationEditor;
import org.rhq.enterprise.client.script.CLIScriptException;
@@ -34,7 +36,6 @@ import org.rhq.enterprise.client.script.CommandLineParseException;
import org.rhq.enterprise.client.script.NamedScriptArg;
import org.rhq.enterprise.client.script.ScriptArg;
import org.rhq.enterprise.client.script.ScriptCmdLine;
-import org.rhq.enterprise.client.utility.PackageFinder;
import org.rhq.enterprise.client.utility.ScriptAssert;
import org.rhq.enterprise.client.utility.ScriptUtil;
diff --git a/modules/enterprise/remoting/cli/src/main/java/org/rhq/enterprise/client/export/ExportException.java b/modules/enterprise/remoting/cli/src/main/java/org/rhq/enterprise/client/export/ExportException.java
deleted file mode 100644
index 69f4fea..0000000
--- a/modules/enterprise/remoting/cli/src/main/java/org/rhq/enterprise/client/export/ExportException.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * RHQ Management Platform
- * Copyright (C) 2005-2008 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.client.export;
-
-public class ExportException extends RuntimeException {
-
- public ExportException() {
- super();
- }
-
- public ExportException(String message) {
- super(message);
- }
-
- public ExportException(String message, Throwable cause) {
- super(message, cause);
- }
-
- public ExportException(Throwable cause) {
- super(cause);
- }
-}
diff --git a/modules/enterprise/remoting/cli/src/main/java/org/rhq/enterprise/client/export/Exporter.java b/modules/enterprise/remoting/cli/src/main/java/org/rhq/enterprise/client/export/Exporter.java
deleted file mode 100644
index 208a1f7..0000000
--- a/modules/enterprise/remoting/cli/src/main/java/org/rhq/enterprise/client/export/Exporter.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * RHQ Management Platform
- * Copyright (C) 2005-2008 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.client.export;
-
-import org.rhq.enterprise.client.TabularWriter;
-
-import java.io.FileWriter;
-import java.io.IOException;
-import java.io.PrintWriter;
-
-public class Exporter {
-
- private String format;
-
- private String file;
-
- private TabularWriter tabularWriter;
-
- private FileWriter fileWriter;
-
- public void setTarget(String format, String file) {
- try {
- this.format = format;
- this.file = file;
- fileWriter = new FileWriter(this.file);
- tabularWriter = new TabularWriter(new PrintWriter(fileWriter), format);
- tabularWriter.setExportMode(true);
- } catch (IOException e) {
- throw new ExportException(e);
- }
- }
-
- public int getPageWidth() {
- return tabularWriter.getWidth();
- }
-
- public void setPageWidth(int width) {
- tabularWriter.setWidth(width);
- }
-
- public void write(Object object) {
- try {
- tabularWriter.print(object);
- fileWriter.flush();
- } catch (IOException e) {
- throw new ExportException(e);
- }
- }
-
- public String getFormat() {
- return format;
- }
-
- public void setFormat(String format) {
- this.format = format;
- }
-
- public String getFile() {
- return file;
- }
-
- public void setFile(String file) {
- this.file = file;
- }
-}
diff --git a/modules/enterprise/remoting/cli/src/main/java/org/rhq/enterprise/client/proxy/ConfigurationEditor.java b/modules/enterprise/remoting/cli/src/main/java/org/rhq/enterprise/client/proxy/ConfigurationEditor.java
index 32fe93d..2fd6ee4 100644
--- a/modules/enterprise/remoting/cli/src/main/java/org/rhq/enterprise/client/proxy/ConfigurationEditor.java
+++ b/modules/enterprise/remoting/cli/src/main/java/org/rhq/enterprise/client/proxy/ConfigurationEditor.java
@@ -19,7 +19,7 @@
package org.rhq.enterprise.client.proxy;
import org.rhq.enterprise.client.ClientMain;
-import org.rhq.enterprise.client.TabularWriter;
+import org.rhq.bindings.output.TabularWriter;
import org.rhq.core.domain.configuration.Configuration;
import org.rhq.core.domain.configuration.PropertySimple;
import org.rhq.core.domain.configuration.definition.ConfigurationDefinition;
diff --git a/modules/enterprise/remoting/cli/src/main/java/org/rhq/enterprise/client/proxy/ResourceClientProxy.java b/modules/enterprise/remoting/cli/src/main/java/org/rhq/enterprise/client/proxy/ResourceClientProxy.java
index 6d56a76..5b21a94 100644
--- a/modules/enterprise/remoting/cli/src/main/java/org/rhq/enterprise/client/proxy/ResourceClientProxy.java
+++ b/modules/enterprise/remoting/cli/src/main/java/org/rhq/enterprise/client/proxy/ResourceClientProxy.java
@@ -31,6 +31,8 @@ import java.io.IOException;
import javassist.util.proxy.MethodHandler;
+import org.rhq.bindings.util.LazyLoadScenario;
+import org.rhq.bindings.util.ShortOutput;
import org.rhq.core.domain.configuration.Configuration;
import org.rhq.core.domain.configuration.ResourceConfigurationUpdate;
import org.rhq.core.domain.configuration.PluginConfigurationUpdate;
@@ -59,8 +61,6 @@ import org.rhq.core.domain.util.Summary;
import org.rhq.core.server.MeasurementConverter;
import org.rhq.enterprise.client.RemoteClient;
import org.rhq.enterprise.client.ClientMain;
-import org.rhq.enterprise.client.utility.LazyLoadScenario;
-import org.rhq.enterprise.client.utility.ShortOutput;
import org.rhq.enterprise.client.utility.ConfigurationClassBuilder;
import org.rhq.enterprise.client.utility.ScriptUtil;
import org.rhq.enterprise.server.content.ContentManagerRemote;
diff --git a/modules/enterprise/remoting/cli/src/main/java/org/rhq/enterprise/client/utility/LazyLoadScenario.java b/modules/enterprise/remoting/cli/src/main/java/org/rhq/enterprise/client/utility/LazyLoadScenario.java
deleted file mode 100644
index c6a9111..0000000
--- a/modules/enterprise/remoting/cli/src/main/java/org/rhq/enterprise/client/utility/LazyLoadScenario.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * RHQ Management Platform
- * Copyright (C) 2005-2008 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.client.utility;
-
-/**
- * Set by reflective access utilities like the tabular writer to avoid
- * remote calls behind proxy methods.
- *
- * @author Greg Hinkle
- */
-public class LazyLoadScenario {
-
- private static ThreadLocal<Boolean> shouldLoad = new ThreadLocal<Boolean>() {
-
- protected Boolean initialValue() {
- return true;
- }
- };
-
- public static boolean isShouldLoad() {
- return shouldLoad.get();
- }
-
- public static void setShouldLoad(boolean shouldLoad) {
- LazyLoadScenario.shouldLoad.set(shouldLoad);
- }
-
-}
diff --git a/modules/enterprise/remoting/cli/src/main/java/org/rhq/enterprise/client/utility/PackageFinder.java b/modules/enterprise/remoting/cli/src/main/java/org/rhq/enterprise/client/utility/PackageFinder.java
deleted file mode 100644
index 914b10c..0000000
--- a/modules/enterprise/remoting/cli/src/main/java/org/rhq/enterprise/client/utility/PackageFinder.java
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * RHQ Management Platform
- * Copyright (C) 2005-2008 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.client.utility;
-
-import java.io.File;
-import java.io.FileFilter;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Enumeration;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-import java.util.jar.JarEntry;
-import java.util.jar.JarFile;
-import java.net.URL;
-
-/**
- * @author Greg Hinkle
- */
-public class PackageFinder {
-
-
-
- public List<String> findPackages(String packageRoot) {
- ArrayList<String> found = new ArrayList<String>();
-
- String cwd = System.getProperty("user.dir");
- File libDir = new File(cwd, "lib");
- File[] jars;
-
- if (libDir.exists()) {
- jars = libDir.listFiles(new FileFilter() {
- public boolean accept(File pathname) {
- return pathname.isFile() && pathname.getName().endsWith(".jar");
- }
- });
- }
- else {
- jars = loadJARsFromClassPath(packageRoot);
- }
-
-
- for (File jar : jars) {
- findPackages(packageRoot, found, jar);
- }
-
- return found;
- }
-
- private File[] loadJARsFromClassPath(String pkgRoot) {
- try {
- List<File> jarFiles = new ArrayList<File>();
- String pkgPath = pkgRoot.replaceAll("\\.", "/");
- Enumeration<URL> resources = getClass().getClassLoader().getResources(pkgPath);
- URL resource = null;
-
- while (resources.hasMoreElements()) {
- resource = resources.nextElement();
- if (resource.toString().startsWith("jar:file")) {
- String jarFilePath = getJARFilePath(resource);
- jarFiles.add(new File(jarFilePath));
- }
- }
-
- return jarFiles.toArray(new File[] {});
- }
- catch (IOException e) {
- e.printStackTrace();
- return new File[] {};
- }
-
- }
-
- private String getJARFilePath(URL resource) {
- int startIndex = "jar:file:".length();
- String string = resource.toString().substring(startIndex);
- int endIndex = string.indexOf("!");
-
- return string.substring(0, endIndex);
- }
-
- private void findPackages(String packageRoot, List<String> list, File jar) {
-
- Set<String> paths = new HashSet<String>();
- JarFile jf = null;
- try {
- jf = new JarFile(jar);
-
- String packagePath = packageRoot.replaceAll("\\.", "/");
-
- Enumeration<JarEntry> entries = jf.entries();
-
- while (entries.hasMoreElements()) {
- JarEntry entry = entries.nextElement();
-
- if (entry.getName().startsWith(packagePath)) {
- String match = entry.getName().substring(0, entry.getName().lastIndexOf("/"));
- paths.add(match.replaceAll("/", "\\."));
- }
- }
- list.addAll(paths);
-
- } catch (IOException e) {
- e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
- } finally {
- try {
- if (jf != null) {
- jf.close();
- }
- } catch (IOException e) {
- e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
- }
- }
- }
-
-
-
-
-
- public static void main(String[] args) {
- new PackageFinder().findPackages("org.rhq.core.domain");
- }
-
-}
diff --git a/modules/enterprise/remoting/cli/src/main/java/org/rhq/enterprise/client/utility/ShortOutput.java b/modules/enterprise/remoting/cli/src/main/java/org/rhq/enterprise/client/utility/ShortOutput.java
deleted file mode 100644
index 8f9099b..0000000
--- a/modules/enterprise/remoting/cli/src/main/java/org/rhq/enterprise/client/utility/ShortOutput.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * RHQ Management Platform
- * Copyright (C) 2005-2008 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.client.utility;
-
-/**
- * @author Greg Hinkle
- */
-public interface ShortOutput {
-
- String getShortOutput();
-}
diff --git a/modules/enterprise/remoting/cli/src/test/java/org/rhq/enterprise/client/SummaryFilterTest.java b/modules/enterprise/remoting/cli/src/test/java/org/rhq/enterprise/client/SummaryFilterTest.java
index f91bed9..a2abec5 100644
--- a/modules/enterprise/remoting/cli/src/test/java/org/rhq/enterprise/client/SummaryFilterTest.java
+++ b/modules/enterprise/remoting/cli/src/test/java/org/rhq/enterprise/client/SummaryFilterTest.java
@@ -26,6 +26,8 @@ package org.rhq.enterprise.client;
import static org.testng.Assert.*;
import org.testng.annotations.Test;
+
+import org.rhq.bindings.util.SummaryFilter;
import org.rhq.core.domain.util.Summary;
import javax.persistence.Entity;
diff --git a/modules/enterprise/remoting/cli/src/test/java/org/rhq/enterprise/client/TabularWriterTest.java b/modules/enterprise/remoting/cli/src/test/java/org/rhq/enterprise/client/TabularWriterTest.java
deleted file mode 100644
index 665abf0..0000000
--- a/modules/enterprise/remoting/cli/src/test/java/org/rhq/enterprise/client/TabularWriterTest.java
+++ /dev/null
@@ -1,396 +0,0 @@
-/*
- * RHQ Management Platform
- * Copyright (C) 2005-2008 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.client;
-
-import static org.testng.Assert.*;
-
-import org.rhq.core.domain.resource.Resource;
-import org.rhq.core.domain.shared.ResourceBuilder;
-
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-import org.apache.commons.lang.StringUtils;
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import javax.persistence.OneToOne;
-import javax.persistence.OneToMany;
-import java.io.PrintWriter;
-import java.io.StringWriter;
-import java.util.List;
-import java.util.ArrayList;
-
-import static org.rhq.core.domain.measurement.AvailabilityType.*;
-
-public class TabularWriterTest {
-
- StringWriter stringWriter;
-
- TabularWriter writer;
-
- @BeforeMethod
- public void initFixture() {
- stringWriter = new StringWriter();
- writer = new TabularWriter(new PrintWriter(stringWriter));
- }
-
- @Test
- public void aByteShouldPrintUnchanged() {
- byte value = 1;
-
- writer.print(value);
-
- String expected = "1\n";
- String actual = stringWriter.toString();
-
- assertEquals(actual, expected, "A byte or Byte should have its value printed as a String");
- }
-
- @Test
- public void anIntegerShouldPrintUnchanged() {
- int value = 1;
-
- writer.print(value);
-
- String expected = "1\n";
- String actual = stringWriter.toString();
-
- assertEquals(actual, expected, "An int or Integer should have its value printed as a String");
- }
-
- @Test
- public void theSimpleClassNameShouldPrintFirstForEntity() {
- User user = new User(1, "rhqadmin", "rhqadmin");
-
- writer.print(user);
-
- assertNumberOfLinesPrintedIs(4);
- assertLineEquals(0, user.getClass().getSimpleName() + ":", "The simple class name should be the first line printed");
- }
-
- @Test
- public void theIdShouldBeTheFirstPropertyPrintedForEntity() {
- User user = new User(1, "rhqadmin", "rhqadmin");
-
- writer.print(user);
-
- int paddingSize = "username".length();
- int idLineNumber = 1;
- String expected = "\t" + StringUtils.leftPad("id", paddingSize) + ": " + user.getId();
-
- assertLineEquals(idLineNumber, expected, "The id property should be the 2nd line printed");
- }
-
- @Test
- public void otherPropertiesShouldPrintAfterIdForEntity() {
- User user = new User(1, "rhqadmin", "rhqadmin");
-
- writer.print(user);
-
- int passwordLineNumber = 2;
- String expectedPasswordLine = "\tpassword: " + user.getPassword();
-
- assertLineEquals(passwordLineNumber, expectedPasswordLine, "The password property should be the 3rd line printed");
-
- int usernameLineNumber = 3;
- String expectedUsernameLine = "\tusername: " + user.getUsername();
-
- assertLineEquals(usernameLineNumber, expectedUsernameLine, "The username property should be the 4th line printed");
- }
-
- @Test
- public void oneToOneAssociationShouldPrintForAnEntity() {
- User mgr = new User(1, "rhqadmin", "rhqadmin");
- Department department = new Department(1, mgr);
-
- writer.print(department);
-
- int lineNumber = 2;
- String expectedLine = "\tmanager: " + mgr;
-
- assertLineEquals(lineNumber, expectedLine, "The manager property should be the 3rd line printed");
- }
-
- @Test(enabled = false) // TODO revisit
- public void oneToManyAssociationShouldPrintForEntity() {
- User employee = new User(1, "rhq", "rhq");
-
- Company company = new Company(1);
- company.addEmployee(employee);
-
- writer.print(company);
-
- int lineNumber = 2;
- String expectedLine = "\temployees: " + company.getEmployees();
-
- assertLineEquals(lineNumber, expectedLine, "The employees property should be the 2nd line printed and the " +
- "toString() value of the collection should be displayed.");
- }
-
- @Test
- public void idShouldBeFirstResourcePropertyPrinted() {
- Resource resource = createResource();
-
- writer.print(resource);
-
- assertLineEquals(
- 1,
- "\t" + padResourceField("id") + ": " + resource.getId(),
- "Expected Resource.id to be the first property printed."
- );
- }
-
- @Test
- public void nameShouldBeSecondResourcePropertyPrinted() {
- Resource resource = createResource();
-
- writer.print(resource);
-
- assertLineEquals(
- 2,
- "\t" + padResourceField("name") + ": " + resource.getName(),
- "Expected Resource.name to be second property printed"
- );
- }
-
- @Test
- public void versionShouldBeThirdResourcePropertyPrinted() {
- Resource resource = createResource();
-
- writer.print(resource);
-
- assertLineEquals(
- 3,
- "\t" + padResourceField("version") + ": " + resource.getVersion(),
- "Expected Resource.version to be third property printed"
- );
- }
-
- @Test
- public void currentAvailabilityShouldBeFourthResourcePropertyPrinted() {
- Resource resource = createResource();
-
- writer.print(resource);
-
- assertLineEquals(
- 4,
- "\t" + padResourceField("currentAvailability") + ": " + resource.getCurrentAvailability().getAvailabilityType(),
- "Expected short version of Resource.currentAvailability to be fourth property printed"
- );
- }
-
- @Test
- public void handleNullCurrentAvailabilityForResource() {
- Resource resource = createUncommittedResource();
-
- writer.print(resource);
-
- assertLineEquals(
- 4,
- "\t" + padResourceField("currentAvailability") + ": ",
- "Expected to see empty string for Resource.currentAvailability when property is null"
- );
- }
-
- @Test
- public void resourceTypeShouldBeLastResourcePropertyPrinted() {
- Resource resource = createResource();
-
- writer.print(resource);
-
- assertLineEquals(
- 5,
- "\t" + padResourceField("resourceType") + ": " + resource.getResourceType().getName(),
- "Expected short version of Resource.resourceType to be the fifth property printed"
- );
- }
-
- private Resource createResource() {
- return new ResourceBuilder().createServer()
- .usingDefaultResourceType()
- .withId(111)
- .withName("test-server")
- .withUuid("12345")
- .withVersion("1.0")
- .inInventory()
- .withCurrentAvailability(UP)
- .build();
- }
-
- private Resource createUncommittedResource() {
- return new ResourceBuilder().createServer()
- .usingDefaultResourceType()
- .withId(111)
- .withName("test-server")
- .withUuid("12345")
- .withVersion("1.0")
- .notInInventory()
- .build();
- }
-
- @Test
- public void printCollectionOfUncommittedResource() {
- Resource parent = new ResourceBuilder().createServer()
- .usingDefaultResourceType()
- .withName("test-server")
- .withUuid("12345")
- .withVersion("1.0")
- .inInventory()
- .with(2).randomChildServices()
-// .notInInventory()
-// .included()
- .build();
-
- writer.print(parent.getChildResources());
- }
-
- void assertNumberOfLinesPrintedIs(int expectedNumberOfLines) {
- String lines[] = getLines();
- assertEquals(lines.length, expectedNumberOfLines, "The actual lines printed were\n[\n" +
- stringWriter.toString() + "\n]");
- }
-
- void assertLineEquals(int lineNumber, String expectedLine, String msg) {
- String actualLine = getLines()[lineNumber];
-
- assertEquals(actualLine, expectedLine, msg + " -- The actual output was \n[\n" + stringWriter + "\n].");
- }
-
- String[] getLines() {
- return stringWriter.toString().split("\n");
- }
-
- String padResourceField(String field) {
- return StringUtils.leftPad(field, "currentAvailability".length());
- }
-
- @Entity
- static class User {
- @Id
- private int id;
-
- private String username;
-
- private String password;
-
- public User(int id, String username, String password) {
- this.id = id;
- this.username = username;
- this.password = password;
- }
-
- public int getId() {
- return id;
- }
-
- public void setId(int id) {
- this.id = id;
- }
-
- public String getUsername() {
- return username;
- }
-
- public void setUsername(String username) {
- this.username = username;
- }
-
- public String getPassword() {
- return password;
- }
-
- public void setPassword(String password) {
- this.password = password;
- }
-
- @Override
- public String toString() {
- return User.class.getSimpleName() + "[id=" + id + ", username=" + username + ", password=" + password + "]";
- }
- }
-
- @Entity
- static class Department {
- @Id
- private int id;
-
- @OneToOne
- private User manager;
-
- public Department(int id, User manager) {
- this.id = id;
- this.manager = manager;
- }
-
- public int getId() {
- return id;
- }
-
- public void setId(int id) {
- this.id = id;
- }
-
- public User getManager() {
- return manager;
- }
-
- public void setManager(User manager) {
- this.manager = manager;
- }
- }
-
- @Entity
- static class Company {
- @Id
- private int id;
-
- @OneToMany
- private List<User> employees = new ArrayList<User>();
-
- public Company(int id) {
- this.id = id;
- }
-
- public int getId() {
- return id;
- }
-
- public void setId(int id) {
- this.id = id;
- }
-
- public List<User> getEmployees() {
- return employees;
- }
-
- public void setEmployees(List<User> employees) {
- this.employees = employees;
- }
-
- public void addEmployee(User employee) {
- employees.add(employee);
- }
- }
-
-}
diff --git a/modules/enterprise/remoting/cli/src/test/java/org/rhq/enterprise/client/commands/ScriptCommandTest.java b/modules/enterprise/remoting/cli/src/test/java/org/rhq/enterprise/client/commands/ScriptCommandTest.java
index 1bb32fd..22d5305 100644
--- a/modules/enterprise/remoting/cli/src/test/java/org/rhq/enterprise/client/commands/ScriptCommandTest.java
+++ b/modules/enterprise/remoting/cli/src/test/java/org/rhq/enterprise/client/commands/ScriptCommandTest.java
@@ -12,7 +12,6 @@ import java.util.ArrayList;
import org.testng.annotations.Test;
import org.rhq.enterprise.client.ClientMain;
import org.rhq.enterprise.client.RemoteClient;
-import org.rhq.enterprise.client.TabularWriter;
import org.rhq.enterprise.client.utility.ScriptUtil;
import org.rhq.enterprise.server.alert.AlertManagerRemote;
import org.rhq.enterprise.server.alert.AlertDefinitionManagerRemote;
@@ -24,6 +23,7 @@ import org.rhq.enterprise.server.authz.RoleManagerRemote;
import org.rhq.enterprise.server.resource.ResourceManagerRemote;
import org.rhq.enterprise.server.resource.group.ResourceGroupManagerRemote;
import org.rhq.enterprise.server.auth.SubjectManagerRemote;
+import org.rhq.bindings.output.TabularWriter;
import org.rhq.core.domain.auth.Subject;
import javax.script.ScriptEngine;
diff --git a/modules/enterprise/remoting/client-api/pom.xml b/modules/enterprise/remoting/client-api/pom.xml
index 9434aa8..ed44e2a 100644
--- a/modules/enterprise/remoting/client-api/pom.xml
+++ b/modules/enterprise/remoting/client-api/pom.xml
@@ -166,7 +166,13 @@
</exclusion>
</exclusions>
</dependency>
-
+
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>rhq-script-bindings</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
<dependency>
<groupId>jboss</groupId>
<artifactId>jboss-remoting</artifactId>
commit 5d7eb67211b84c813e6fb7d22cf84517979dbd8a
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Thu Jan 6 16:53:25 2011 +0100
Adding the new maven module for the cli alert plugin
diff --git a/modules/enterprise/server/plugins/alert-cli/pom.xml b/modules/enterprise/server/plugins/alert-cli/pom.xml
new file mode 100644
index 0000000..55aa5d3
--- /dev/null
+++ b/modules/enterprise/server/plugins/alert-cli/pom.xml
@@ -0,0 +1,23 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <artifactId>rhq-enterprise-server-plugins-parent</artifactId>
+ <groupId>org.rhq</groupId>
+ <version>4.0.0-SNAPSHOT</version>
+ </parent>
+ <groupId>org.rhq</groupId>
+ <artifactId>alert-cli</artifactId>
+ <version>4.0.0-SNAPSHOT</version>
+ <name>RHQ Enterprise Server CLI Script Alert Plugin</name>
+ <description>An alert sender able to execute an arbitrary CLI script as a response to an alert</description>
+
+ <scm>
+ <connection>scm:git:ssh://git.fedorahosted.org/git/rhq.git/modules/enterprise/server/...</connection>
+ <developerConnection>scm:git:ssh://git.fedorahosted.org/git/rhq.git/modules/enterprise/server/...</developerConnection>
+ </scm>
+
+ <properties>
+ <scm.module.path>modules/enterprise/server/plugins/alert-cli/</scm.module.path>
+ </properties>
+
+</project>
\ No newline at end of file
13 years, 2 months