You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@syncope.apache.org by fm...@apache.org on 2013/07/25 11:25:10 UTC
svn commit: r1506859 [1/2] - in /syncope/trunk:
common/src/main/java/org/apache/syncope/common/to/ console/
console/src/main/java/org/apache/syncope/console/
console/src/main/java/org/apache/syncope/console/pages/
console/src/main/java/org/apache/synco...
Author: fmartelli
Date: Thu Jul 25 09:25:09 2013
New Revision: 1506859
URL: http://svn.apache.org/r1506859
Log:
Provided creator, lastModifier, creationDate and lastChangeDate for attributables and resources - see SYNCOPE-15
Added:
syncope/trunk/common/src/main/java/org/apache/syncope/common/to/AbstractSysInfoTO.java
syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/panels/SysInfoPanel.java
- copied, changed from r1506478, syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/panels/AccountInformationPanel.java
syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/panels/SysInfoPanel.html
- copied, changed from r1506478, syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/panels/AccountInformationPanel.html
syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/panels/SysInfoPanel.properties
- copied, changed from r1506478, syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/panels/AccountInformationPanel.properties
syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/panels/SysInfoPanel_it.properties
- copied, changed from r1506478, syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/panels/AccountInformationPanel_it.properties
syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/panels/SysInfoPanel_pt_BR.properties
- copied, changed from r1506478, syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/panels/AccountInformationPanel_pt_BR.properties
syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/AbstractSysInfo.java
syncope/trunk/core/src/main/java/org/apache/syncope/core/util/SysInfoListener.java
Modified:
syncope/trunk/common/src/main/java/org/apache/syncope/common/to/ConnObjectTO.java
syncope/trunk/common/src/main/java/org/apache/syncope/common/to/NotificationTaskTO.java
syncope/trunk/common/src/main/java/org/apache/syncope/common/to/ResourceTO.java
syncope/trunk/common/src/main/java/org/apache/syncope/common/to/UserTO.java
syncope/trunk/console/pom.xml
syncope/trunk/console/src/main/java/org/apache/syncope/console/SyncopeSession.java
syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/Logout.java
syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/MembershipModalPage.java
syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/ResourceModalPage.java
syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/Todo.java
syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/UserModalPage.java
syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/panels/AccountInformationPanel.java
syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/panels/RolePanel.java
syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/MembershipModalPage.html
syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/ResourceModalPage.html
syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/panels/AccountInformationPanel.html
syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/panels/AccountInformationPanel.properties
syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/panels/RolePanel.html
syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/AbstractAttributable.java
syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/ExternalResource.java
syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/UserRequest.java
syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/user/SyncopeUser.java
syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/dao/impl/MembershipDAOImpl.java
syncope/trunk/core/src/main/java/org/apache/syncope/core/rest/data/ResourceDataBinder.java
syncope/trunk/core/src/main/java/org/apache/syncope/core/rest/data/RoleDataBinder.java
syncope/trunk/core/src/main/java/org/apache/syncope/core/rest/data/UserDataBinder.java
syncope/trunk/core/src/main/java/org/apache/syncope/core/util/JexlUtil.java
syncope/trunk/core/src/test/java/org/apache/syncope/core/persistence/dao/DerAttrTest.java
syncope/trunk/core/src/test/java/org/apache/syncope/core/persistence/relationships/AttrTest.java
syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/AuthenticationTestITCase.java
syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/RoleTestITCase.java
syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/UserTestITCase.java
syncope/trunk/core/src/test/resources/content.xml
Added: syncope/trunk/common/src/main/java/org/apache/syncope/common/to/AbstractSysInfoTO.java
URL: http://svn.apache.org/viewvc/syncope/trunk/common/src/main/java/org/apache/syncope/common/to/AbstractSysInfoTO.java?rev=1506859&view=auto
==============================================================================
--- syncope/trunk/common/src/main/java/org/apache/syncope/common/to/AbstractSysInfoTO.java (added)
+++ syncope/trunk/common/src/main/java/org/apache/syncope/common/to/AbstractSysInfoTO.java Thu Jul 25 09:25:09 2013
@@ -0,0 +1,91 @@
+/*
+ * Copyright 2013 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.syncope.common.to;
+
+import java.util.Date;
+import org.apache.syncope.common.AbstractBaseBean;
+
+/**
+ * Abstract wrapper for common system information.
+ */
+public class AbstractSysInfoTO extends AbstractBaseBean {
+
+ private static final long serialVersionUID = -930797879027642457L;
+
+ /**
+ * Username of the user that has created this profile.
+ * <p>
+ * Cannot be used a reference to an existing user for two main reasons: the creator can be the user <tt>admin</tt>;
+ * the creator could have been removed.
+ */
+ private String creator;
+
+ /**
+ * Creation date.
+ */
+ private Date creationDate;
+
+ /**
+ * Username of the user that has performed the last modification to this profile.
+ * <p>
+ * This field cannot be null: at creation time it have to be initialized with the creator username.
+ * <p>
+ * The modifier can be the user itself whether the last performed change has been a self-modification.
+ * <p>
+ * Cannot be used a reference to an existing user for two main reasons: the modifier can be the user <tt>admin</tt>;
+ * the modifier could have been removed.
+ */
+ private String lastModifier;
+
+ /**
+ * Last change date.
+ * <p>
+ * This field cannot be null: at creation time it has to be initialized with <tt>creationDate</tt> field value.
+ */
+ private Date lastChangeDate;
+
+ public String getCreator() {
+ return creator;
+ }
+
+ public void setCreator(final String creator) {
+ this.creator = creator;
+ }
+
+ public Date getCreationDate() {
+ return creationDate;
+ }
+
+ public void setCreationDate(final Date creationDate) {
+ this.creationDate = creationDate;
+ }
+
+ public String getLastModifier() {
+ return lastModifier;
+ }
+
+ public void setLastModifier(final String lastModifier) {
+ this.lastModifier = lastModifier;
+ }
+
+ public Date getLastChangeDate() {
+ return lastChangeDate;
+ }
+
+ public void setLastChangeDate(final Date lastChangeDate) {
+ this.lastChangeDate = lastChangeDate;
+ }
+}
Modified: syncope/trunk/common/src/main/java/org/apache/syncope/common/to/ConnObjectTO.java
URL: http://svn.apache.org/viewvc/syncope/trunk/common/src/main/java/org/apache/syncope/common/to/ConnObjectTO.java?rev=1506859&r1=1506858&r2=1506859&view=diff
==============================================================================
--- syncope/trunk/common/src/main/java/org/apache/syncope/common/to/ConnObjectTO.java (original)
+++ syncope/trunk/common/src/main/java/org/apache/syncope/common/to/ConnObjectTO.java Thu Jul 25 09:25:09 2013
@@ -29,11 +29,10 @@ import javax.xml.bind.annotation.XmlElem
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
-import org.apache.syncope.common.AbstractBaseBean;
@XmlRootElement(name = "connObject")
@XmlType
-public class ConnObjectTO extends AbstractBaseBean {
+public class ConnObjectTO extends AbstractSysInfoTO {
private static final long serialVersionUID = 5139554911265442497L;
Modified: syncope/trunk/common/src/main/java/org/apache/syncope/common/to/NotificationTaskTO.java
URL: http://svn.apache.org/viewvc/syncope/trunk/common/src/main/java/org/apache/syncope/common/to/NotificationTaskTO.java?rev=1506859&r1=1506858&r2=1506859&view=diff
==============================================================================
--- syncope/trunk/common/src/main/java/org/apache/syncope/common/to/NotificationTaskTO.java (original)
+++ syncope/trunk/common/src/main/java/org/apache/syncope/common/to/NotificationTaskTO.java Thu Jul 25 09:25:09 2013
@@ -18,6 +18,7 @@
*/
package org.apache.syncope.common.to;
+import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.HashSet;
import java.util.Set;
@@ -50,6 +51,7 @@ public class NotificationTaskTO extends
@XmlElementWrapper(name = "recipients")
@XmlElement(name = "recipient")
+ @JsonProperty("recipients")
public Set<String> getRecipients() {
return recipients;
}
Modified: syncope/trunk/common/src/main/java/org/apache/syncope/common/to/ResourceTO.java
URL: http://svn.apache.org/viewvc/syncope/trunk/common/src/main/java/org/apache/syncope/common/to/ResourceTO.java?rev=1506859&r1=1506858&r2=1506859&view=diff
==============================================================================
--- syncope/trunk/common/src/main/java/org/apache/syncope/common/to/ResourceTO.java (original)
+++ syncope/trunk/common/src/main/java/org/apache/syncope/common/to/ResourceTO.java Thu Jul 25 09:25:09 2013
@@ -25,14 +25,13 @@ import javax.xml.bind.annotation.XmlElem
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
-import org.apache.syncope.common.AbstractBaseBean;
import org.apache.syncope.common.types.ConnConfProperty;
import org.apache.syncope.common.types.PropagationMode;
import org.apache.syncope.common.types.TraceLevel;
@XmlRootElement(name = "resource")
@XmlType
-public class ResourceTO extends AbstractBaseBean {
+public class ResourceTO extends AbstractSysInfoTO {
private static final long serialVersionUID = -9193551354041698963L;
Modified: syncope/trunk/common/src/main/java/org/apache/syncope/common/to/UserTO.java
URL: http://svn.apache.org/viewvc/syncope/trunk/common/src/main/java/org/apache/syncope/common/to/UserTO.java?rev=1506859&r1=1506858&r2=1506859&view=diff
==============================================================================
--- syncope/trunk/common/src/main/java/org/apache/syncope/common/to/UserTO.java (original)
+++ syncope/trunk/common/src/main/java/org/apache/syncope/common/to/UserTO.java Thu Jul 25 09:25:09 2013
@@ -54,8 +54,6 @@ public class UserTO extends AbstractAttr
private Date lastLoginDate;
- private Date creationDate;
-
private Date changePwdDate;
private Integer failedLogins;
@@ -150,10 +148,6 @@ public class UserTO extends AbstractAttr
return changePwdDate;
}
- public Date getCreationDate() {
- return creationDate;
- }
-
public Integer getFailedLogins() {
return failedLogins;
}
@@ -166,10 +160,6 @@ public class UserTO extends AbstractAttr
this.changePwdDate = changePwdDate;
}
- public void setCreationDate(final Date creationDate) {
- this.creationDate = creationDate;
- }
-
public void setFailedLogins(final Integer failedLogins) {
this.failedLogins = failedLogins;
}
Modified: syncope/trunk/console/pom.xml
URL: http://svn.apache.org/viewvc/syncope/trunk/console/pom.xml?rev=1506859&r1=1506858&r2=1506859&view=diff
==============================================================================
--- syncope/trunk/console/pom.xml (original)
+++ syncope/trunk/console/pom.xml Thu Jul 25 09:25:09 2013
@@ -240,8 +240,7 @@ under the License.
<cargo.tomcat.ajp.port>${cargo.tomcat.ajp.port}</cargo.tomcat.ajp.port>
<cargo.rmi.port>${cargo.rmi.port}</cargo.rmi.port>
- <!--<cargo.jvmargs>-Xdebug -Xrunjdwp:transport=dt_socket,address=8000,server=y,suspend=n</cargo.jvmargs>-->
- <cargo.jvmargs>-noverify ${javaagent} -Drebel.spring_plugin=false -Xms512m -Xmx1024m -XX:PermSize=512m -XX:MaxPermSize=1024m</cargo.jvmargs>
+ <cargo.jvmargs>-Xdebug -Xrunjdwp:transport=dt_socket,address=8000,server=y,suspend=n -noverify ${javaagent} -Drebel.spring_plugin=false -Xms512m -Xmx1024m -XX:PermSize=512m -XX:MaxPermSize=1024m</cargo.jvmargs>
</properties>
<configfiles>
<configfile>
Modified: syncope/trunk/console/src/main/java/org/apache/syncope/console/SyncopeSession.java
URL: http://svn.apache.org/viewvc/syncope/trunk/console/src/main/java/org/apache/syncope/console/SyncopeSession.java?rev=1506859&r1=1506858&r2=1506859&view=diff
==============================================================================
--- syncope/trunk/console/src/main/java/org/apache/syncope/console/SyncopeSession.java (original)
+++ syncope/trunk/console/src/main/java/org/apache/syncope/console/SyncopeSession.java Thu Jul 25 09:25:09 2013
@@ -24,6 +24,7 @@ import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
+import org.apache.commons.lang3.StringUtils;
import org.apache.syncope.client.rest.RestClientFactoryBean;
import org.apache.wicket.Session;
import org.apache.wicket.authroles.authorization.strategies.role.Roles;
@@ -74,10 +75,17 @@ public class SyncopeSession extends WebS
@SuppressWarnings("unchecked")
public <T> T getService(final Class<T> service, final String username, final String password) {
- if (!restServices.containsKey(service)) {
- restServices.put(service, restClientFactory.createServiceInstance(service, username, password));
+ T res;
+ if (restServices.containsKey(service)) {
+ res = (T) restServices.get(service);
+ } else {
+ res = restClientFactory.createServiceInstance(service, username, password);
+ if (StringUtils.isNotBlank(username) && StringUtils.isNotBlank(password)) {
+ restServices.put(service, restClientFactory.createServiceInstance(service, username, password));
+ }
}
- return (T) restServices.get(service);
+
+ return res;
}
public String getUsername() {
Modified: syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/Logout.java
URL: http://svn.apache.org/viewvc/syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/Logout.java?rev=1506859&r1=1506858&r2=1506859&view=diff
==============================================================================
--- syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/Logout.java (original)
+++ syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/Logout.java Thu Jul 25 09:25:09 2013
@@ -32,7 +32,7 @@ public class Logout extends BasePage {
super(parameters);
SyncopeSession.get().invalidate();
-
+
setResponsePage(getApplication().getHomePage());
}
}
Modified: syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/MembershipModalPage.java
URL: http://svn.apache.org/viewvc/syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/MembershipModalPage.java?rev=1506859&r1=1506858&r2=1506859&view=diff
==============================================================================
--- syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/MembershipModalPage.java (original)
+++ syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/MembershipModalPage.java Thu Jul 25 09:25:09 2013
@@ -22,6 +22,7 @@ import org.apache.syncope.common.to.Memb
import org.apache.syncope.common.to.UserTO;
import org.apache.syncope.console.pages.panels.AttributesPanel;
import org.apache.syncope.console.pages.panels.DerivedAttributesPanel;
+import org.apache.syncope.console.pages.panels.SysInfoPanel;
import org.apache.syncope.console.pages.panels.VirtualAttributesPanel;
import org.apache.wicket.PageReference;
import org.apache.wicket.ajax.AjaxRequestTarget;
@@ -90,6 +91,7 @@ public class MembershipModalPage extends
// Attributes panel
//--------------------------------
form.add(new AttributesPanel("attributes", membershipTO, form, templateMode));
+ form.add(new SysInfoPanel("systeminformation", membershipTO));
//--------------------------------
//--------------------------------
Modified: syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/ResourceModalPage.java
URL: http://svn.apache.org/viewvc/syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/ResourceModalPage.java?rev=1506859&r1=1506858&r2=1506859&view=diff
==============================================================================
--- syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/ResourceModalPage.java (original)
+++ syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/ResourceModalPage.java Thu Jul 25 09:25:09 2013
@@ -27,6 +27,7 @@ import org.apache.syncope.console.pages.
import org.apache.syncope.console.pages.panels.ResourceDetailsPanel;
import org.apache.syncope.console.pages.panels.ResourceMappingPanel;
import org.apache.syncope.console.pages.panels.ResourceSecurityPanel;
+import org.apache.syncope.console.pages.panels.SysInfoPanel;
import org.apache.wicket.PageReference;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.markup.html.form.AjaxButton;
@@ -67,6 +68,8 @@ public class ResourceModalPage extends B
//--------------------------------
form.add(new ResourceDetailsPanel("details", resourceTO,
resourceRestClient.getPropagationActionsClasses(), createFlag));
+
+ form.add(new SysInfoPanel("systeminformation", resourceTO));
//--------------------------------
//--------------------------------
Modified: syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/Todo.java
URL: http://svn.apache.org/viewvc/syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/Todo.java?rev=1506859&r1=1506858&r2=1506859&view=diff
==============================================================================
--- syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/Todo.java (original)
+++ syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/Todo.java Thu Jul 25 09:25:09 2013
@@ -372,7 +372,7 @@ public class Todo extends BasePage {
@Override
public Iterator<WorkflowFormTO> iterator(final long first, final long count) {
- List<WorkflowFormTO> list = approvalRestClient.getForms();
+ final List<WorkflowFormTO> list = approvalRestClient.getForms();
Collections.sort(list, comparator);
Modified: syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/UserModalPage.java
URL: http://svn.apache.org/viewvc/syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/UserModalPage.java?rev=1506859&r1=1506858&r2=1506859&view=diff
==============================================================================
--- syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/UserModalPage.java (original)
+++ syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/UserModalPage.java Thu Jul 25 09:25:09 2013
@@ -135,8 +135,7 @@ public abstract class UserModalPage exte
//--------------------------------
// Resources panel
//--------------------------------
- form.add(new ResourcesPanel.Builder("resources")
- .attributableTO(userTO).statusPanel(null).build());
+ form.add(new ResourcesPanel.Builder("resources").attributableTO(userTO).statusPanel(null).build());
//--------------------------------
//--------------------------------
Modified: syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/panels/AccountInformationPanel.java
URL: http://svn.apache.org/viewvc/syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/panels/AccountInformationPanel.java?rev=1506859&r1=1506858&r2=1506859&view=diff
==============================================================================
--- syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/panels/AccountInformationPanel.java (original)
+++ syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/panels/AccountInformationPanel.java Thu Jul 25 09:25:09 2013
@@ -22,63 +22,48 @@ import org.apache.syncope.common.to.Abst
import org.apache.syncope.common.to.UserTO;
import org.apache.syncope.console.SyncopeSession;
import org.apache.wicket.markup.html.basic.Label;
-import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.model.Model;
-public class AccountInformationPanel extends Panel {
+public class AccountInformationPanel extends SysInfoPanel {
private static final long serialVersionUID = 4228064224811390808L;
public <T extends AbstractAttributableTO> AccountInformationPanel(final String id, final UserTO userTO) {
-
- super(id);
-
- // ------------------------
- // Creation date
- // ------------------------
- add(new Label("creationDate", new Model(userTO.getCreationDate() != null
- ? SyncopeSession.get().getDateFormat().format(userTO.getCreationDate())
- : "")));
- // ------------------------
+ super(id, userTO);
// ------------------------
// Change password date
// ------------------------
add(new Label("changePwdDate", new Model(userTO.getChangePwdDate() != null
- ? SyncopeSession.get().getDateFormat().format(userTO.getChangePwdDate())
- : "")));
+ ? SyncopeSession.get().getDateFormat().format(userTO.getChangePwdDate()) : "")));
// ------------------------
// ------------------------
// Last login date
// ------------------------
add(new Label("lastLoginDate", new Model(userTO.getLastLoginDate() != null
- ? SyncopeSession.get().getDateFormat().format(userTO.getLastLoginDate())
- : "")));
+ ? SyncopeSession.get().getDateFormat().format(userTO.getLastLoginDate()) : "")));
// ------------------------
// ------------------------
// Failed logins
// ------------------------
add(new Label("failedLogins", new Model(userTO.getFailedLogins() != null
- ? userTO.getFailedLogins()
- : "")));
+ ? userTO.getFailedLogins() : "")));
// ------------------------
// ------------------------
// Token
// ------------------------
add(new Label("token", new Model(userTO.getToken() != null
- ? userTO.getToken()
- : "")));
+ ? userTO.getToken() : "")));
// ------------------------
// ------------------------
// Token expire time
// ------------------------
add(new Label("tokenExpireTime", new Model(userTO.getTokenExpireTime() != null
- ? userTO.getTokenExpireTime()
- : "")));
+ ? userTO.getTokenExpireTime() : "")));
// ------------------------
}
}
Modified: syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/panels/RolePanel.java
URL: http://svn.apache.org/viewvc/syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/panels/RolePanel.java?rev=1506859&r1=1506858&r2=1506859&view=diff
==============================================================================
--- syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/panels/RolePanel.java (original)
+++ syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/panels/RolePanel.java Thu Jul 25 09:25:09 2013
@@ -114,6 +114,8 @@ public class RolePanel extends Panel {
this.add(statusPanel);
}
+ this.add(new SysInfoPanel("systeminformation", builder.roleTO));
+
//--------------------------------
// Attributes panel
this.add(new AttributesPanel(
Copied: syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/panels/SysInfoPanel.java (from r1506478, syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/panels/AccountInformationPanel.java)
URL: http://svn.apache.org/viewvc/syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/panels/SysInfoPanel.java?p2=syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/panels/SysInfoPanel.java&p1=syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/panels/AccountInformationPanel.java&r1=1506478&r2=1506859&rev=1506859&view=diff
==============================================================================
--- syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/panels/AccountInformationPanel.java (original)
+++ syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/panels/SysInfoPanel.java Thu Jul 25 09:25:09 2013
@@ -19,66 +19,49 @@
package org.apache.syncope.console.pages.panels;
import org.apache.syncope.common.to.AbstractAttributableTO;
-import org.apache.syncope.common.to.UserTO;
+import org.apache.syncope.common.to.AbstractSysInfoTO;
import org.apache.syncope.console.SyncopeSession;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.model.Model;
-public class AccountInformationPanel extends Panel {
+public class SysInfoPanel extends Panel {
- private static final long serialVersionUID = 4228064224811390808L;
+ private static final long serialVersionUID = 4228064224811390809L;
- public <T extends AbstractAttributableTO> AccountInformationPanel(final String id, final UserTO userTO) {
+ public <T extends AbstractAttributableTO> SysInfoPanel(
+ final String id, final AbstractSysInfoTO sysInfoTO) {
super(id);
// ------------------------
// Creation date
// ------------------------
- add(new Label("creationDate", new Model(userTO.getCreationDate() != null
- ? SyncopeSession.get().getDateFormat().format(userTO.getCreationDate())
- : "")));
+ add(new Label("creationDate", new Model<String>(sysInfoTO.getCreationDate() != null
+ ? SyncopeSession.get().getDateFormat().format(sysInfoTO.getCreationDate()) : "")));
// ------------------------
// ------------------------
- // Change password date
+ // Last change date
// ------------------------
- add(new Label("changePwdDate", new Model(userTO.getChangePwdDate() != null
- ? SyncopeSession.get().getDateFormat().format(userTO.getChangePwdDate())
- : "")));
+ add(new Label("lastChangeDate", new Model<String>(sysInfoTO.getLastChangeDate() != null
+ ? SyncopeSession.get().getDateFormat().format(sysInfoTO.getCreationDate()) : "")));
// ------------------------
- // ------------------------
- // Last login date
- // ------------------------
- add(new Label("lastLoginDate", new Model(userTO.getLastLoginDate() != null
- ? SyncopeSession.get().getDateFormat().format(userTO.getLastLoginDate())
- : "")));
- // ------------------------
// ------------------------
- // Failed logins
+ // Creator
// ------------------------
- add(new Label("failedLogins", new Model(userTO.getFailedLogins() != null
- ? userTO.getFailedLogins()
- : "")));
+ add(new Label("creator", new Model<String>(sysInfoTO.getCreator() != null
+ ? sysInfoTO.getCreator() : "")));
// ------------------------
// ------------------------
- // Token
+ // Last modifier
// ------------------------
- add(new Label("token", new Model(userTO.getToken() != null
- ? userTO.getToken()
- : "")));
+ add(new Label("lastModifier", new Model<String>(sysInfoTO.getLastModifier() != null
+ ? sysInfoTO.getLastModifier() : "")));
// ------------------------
- // ------------------------
- // Token expire time
- // ------------------------
- add(new Label("tokenExpireTime", new Model(userTO.getTokenExpireTime() != null
- ? userTO.getTokenExpireTime()
- : "")));
- // ------------------------
}
}
Modified: syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/MembershipModalPage.html
URL: http://svn.apache.org/viewvc/syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/MembershipModalPage.html?rev=1506859&r1=1506858&r2=1506859&view=diff
==============================================================================
--- syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/MembershipModalPage.html (original)
+++ syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/MembershipModalPage.html Thu Jul 25 09:25:09 2013
@@ -28,6 +28,7 @@ under the License.
<div id="tabs-1">
<div id="formtable">
<span wicket:id="attributes">[membership attributes]</span>
+ <span wicket:id="systeminformation">[System Information]</span>
</div>
<script type="text/javascript">
Modified: syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/ResourceModalPage.html
URL: http://svn.apache.org/viewvc/syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/ResourceModalPage.html?rev=1506859&r1=1506858&r2=1506859&view=diff
==============================================================================
--- syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/ResourceModalPage.html (original)
+++ syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/ResourceModalPage.html Thu Jul 25 09:25:09 2013
@@ -34,6 +34,7 @@ under the License.
</ul>
<div id="resource">
<span wicket:id="details">[details]</span>
+ <span wicket:id="systeminformation">[System Information]</span>
</div>
<div id="umapping">
<span wicket:id="umapping">[umapping]</span>
Modified: syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/panels/AccountInformationPanel.html
URL: http://svn.apache.org/viewvc/syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/panels/AccountInformationPanel.html?rev=1506859&r1=1506858&r2=1506859&view=diff
==============================================================================
--- syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/panels/AccountInformationPanel.html (original)
+++ syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/panels/AccountInformationPanel.html Thu Jul 25 09:25:09 2013
@@ -17,98 +17,51 @@ specific language governing permissions
under the License.
-->
<html>
- <wicket:head>
- <style>
- div.information{
- margin-top: 30px;
- border: 1px solid #DDDDDD;
- font-size: 8px;
- color: #555555;
- display: inline-table;
- width: 100%;
- clear: both;
- float:none;
- }
+ <wicket:extend>
- div.infolabel{
- margin-left: 5px;
- float:left;
- width: 150px;
- font-weight: bold
- }
-
- div.infoleft{
- float:left;
- display: inline-table;
- width: 50%
- }
-
- div.inforight{
- display: inline-table;
- width: 50%
- }
-
- div.inforow{
- display: inline-table;
- width: 100%
- }
- </style>
- </wicket:head>
- <wicket:panel>
- <div class="information">
- <div class="infoleft">
- <div class="infolabel">
- <wicket:message key="creationDate"/>:
- </div>
- <div>
- <span wicket:id="creationDate" />
- </div>
- </div>
-
- <div class="inforight">
- <div class="infolabel">
- <wicket:message key="lastLoginDate"/>:
- </div>
- <div>
- <span wicket:id="lastLoginDate" />
- </div>
- </div>
-
- <div class="infoleft">
- <div class="infolabel">
- <wicket:message key="changePwdDate"/>:
- </div>
- <div>
- <span wicket:id="changePwdDate" />
- </div>
- </div>
-
- <div class="inforight">
- <div class="infolabel">
- <wicket:message key="failedLogins"/>:
- </div>
- <div>
- <span wicket:id="failedLogins" />
- </div>
- </div>
-
- <div class="inforow">
- <div class="infolabel">
- <wicket:message key="token"/>:
- </div>
- <div>
- <span wicket:id="token" />
- </div>
- </div>
-
- <div class="inforow">
- <div class="infolabel">
- <wicket:message key="tokenExpireTime"/>
- </div>
- <div>
- <span wicket:id="tokenExpireTime" />
- </div>
- </div>
- </div>
- </wicket:panel>
+ <div class="infoleft">
+ <div class="infolabel">
+ <wicket:message key="lastLoginDate"/>:
+ </div>
+ <div>
+ <span wicket:id="lastLoginDate" />
+ </div>
+ </div>
+
+ <div class="inforight">
+ <div class="infolabel">
+ <wicket:message key="failedLogins"/>:
+ </div>
+ <div>
+ <span wicket:id="failedLogins" />
+ </div>
+ </div>
+
+ <div class="infoleft">
+ <div class="infolabel">
+ <wicket:message key="changePwdDate"/>:
+ </div>
+ <div>
+ <span wicket:id="changePwdDate" />
+ </div>
+ </div>
+
+ <div class="inforight">
+ <div class="infolabel">
+ <wicket:message key="tokenExpireTime"/>
+ </div>
+ <div>
+ <span wicket:id="tokenExpireTime" />
+ </div>
+ </div>
+
+ <div class="inforow">
+ <div class="infolabel">
+ <wicket:message key="token"/>:
+ </div>
+ <div>
+ <span wicket:id="token" />
+ </div>
+ </div>
+ </wicket:extend>
</html>
Modified: syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/panels/AccountInformationPanel.properties
URL: http://svn.apache.org/viewvc/syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/panels/AccountInformationPanel.properties?rev=1506859&r1=1506858&r2=1506859&view=diff
==============================================================================
--- syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/panels/AccountInformationPanel.properties (original)
+++ syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/panels/AccountInformationPanel.properties Thu Jul 25 09:25:09 2013
@@ -14,7 +14,6 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-creationDate=Creation Date
changePwdDate=Last Change Password Date
lastLoginDate=Last Login Data
failedLogins=Subsequent Failed Logins
Modified: syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/panels/RolePanel.html
URL: http://svn.apache.org/viewvc/syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/panels/RolePanel.html?rev=1506859&r1=1506858&r2=1506859&view=diff
==============================================================================
--- syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/panels/RolePanel.html (original)
+++ syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/panels/RolePanel.html Thu Jul 25 09:25:09 2013
@@ -22,6 +22,7 @@ under the License.
<div id="tabs-1">
<span wicket:id="details">[role details]</span>
<span wicket:id="statuspanel">[Status Panel]</span>
+ <span wicket:id="systeminformation">[System Information]</span>
</div>
<div id="tabs-2">
Copied: syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/panels/SysInfoPanel.html (from r1506478, syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/panels/AccountInformationPanel.html)
URL: http://svn.apache.org/viewvc/syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/panels/SysInfoPanel.html?p2=syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/panels/SysInfoPanel.html&p1=syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/panels/AccountInformationPanel.html&r1=1506478&r2=1506859&rev=1506859&view=diff
==============================================================================
--- syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/panels/AccountInformationPanel.html (original)
+++ syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/panels/SysInfoPanel.html Thu Jul 25 09:25:09 2013
@@ -17,98 +17,82 @@ specific language governing permissions
under the License.
-->
<html>
- <wicket:head>
- <style>
- div.information{
- margin-top: 30px;
- border: 1px solid #DDDDDD;
- font-size: 8px;
- color: #555555;
- display: inline-table;
- width: 100%;
- clear: both;
- float:none;
- }
-
- div.infolabel{
- margin-left: 5px;
- float:left;
- width: 150px;
- font-weight: bold
- }
-
- div.infoleft{
- float:left;
- display: inline-table;
- width: 50%
- }
-
- div.inforight{
- display: inline-table;
- width: 50%
- }
-
- div.inforow{
- display: inline-table;
- width: 100%
- }
- </style>
- </wicket:head>
- <wicket:panel>
- <div class="information">
- <div class="infoleft">
- <div class="infolabel">
- <wicket:message key="creationDate"/>:
- </div>
- <div>
- <span wicket:id="creationDate" />
- </div>
- </div>
-
- <div class="inforight">
- <div class="infolabel">
- <wicket:message key="lastLoginDate"/>:
- </div>
- <div>
- <span wicket:id="lastLoginDate" />
- </div>
- </div>
-
- <div class="infoleft">
- <div class="infolabel">
- <wicket:message key="changePwdDate"/>:
- </div>
- <div>
- <span wicket:id="changePwdDate" />
- </div>
- </div>
-
- <div class="inforight">
- <div class="infolabel">
- <wicket:message key="failedLogins"/>:
- </div>
- <div>
- <span wicket:id="failedLogins" />
- </div>
- </div>
-
- <div class="inforow">
- <div class="infolabel">
- <wicket:message key="token"/>:
- </div>
- <div>
- <span wicket:id="token" />
- </div>
- </div>
-
- <div class="inforow">
- <div class="infolabel">
- <wicket:message key="tokenExpireTime"/>
- </div>
- <div>
- <span wicket:id="tokenExpireTime" />
- </div>
- </div>
+ <wicket:head>
+ <style>
+ div.information{
+ margin-top: 30px;
+ border: 1px solid #DDDDDD;
+ font-size: 8px;
+ color: #555555;
+ display: inline-table;
+ width: 100%;
+ clear: both;
+ float:none;
+ }
+
+ div.infolabel{
+ margin-left: 5px;
+ float:left;
+ width: 150px;
+ font-weight: bold
+ }
+
+ div.infoleft{
+ float:left;
+ display: inline-table;
+ width: 50%
+ }
+
+ div.inforight{
+ display: inline-table;
+ width: 50%
+ }
+
+ div.inforow{
+ display: inline-table;
+ width: 100%
+ }
+ </style>
+ </wicket:head>
+ <wicket:panel>
+ <div class="information">
+ <div class="infoleft">
+ <div class="infolabel">
+ <wicket:message key="creationDate"/>:
</div>
- </wicket:panel>
+ <div>
+ <span wicket:id="creationDate" />
+ </div>
+ </div>
+
+ <div class="inforight">
+ <div class="infolabel">
+ <wicket:message key="lastChangeDate"/>:
+ </div>
+ <div>
+ <span wicket:id="lastChangeDate" />
+ </div>
+ </div>
+
+ <div class="infoleft">
+ <div class="infolabel">
+ <wicket:message key="creator"/>:
+ </div>
+ <div>
+ <span wicket:id="creator" />
+ </div>
+ </div>
+
+ <div class="inforight">
+ <div class="infolabel">
+ <wicket:message key="lastModifier"/>:
+ </div>
+ <div>
+ <span wicket:id="lastModifier" />
+ </div>
+ </div>
+
+ <wicket:child />
+ </div>
+ </wicket:panel>
</html>
Copied: syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/panels/SysInfoPanel.properties (from r1506478, syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/panels/AccountInformationPanel.properties)
URL: http://svn.apache.org/viewvc/syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/panels/SysInfoPanel.properties?p2=syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/panels/SysInfoPanel.properties&p1=syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/panels/AccountInformationPanel.properties&r1=1506478&r2=1506859&rev=1506859&view=diff
==============================================================================
--- syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/panels/AccountInformationPanel.properties (original)
+++ syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/panels/SysInfoPanel.properties Thu Jul 25 09:25:09 2013
@@ -15,9 +15,6 @@
# specific language governing permissions and limitations
# under the License.
creationDate=Creation Date
-changePwdDate=Last Change Password Date
-lastLoginDate=Last Login Data
-failedLogins=Subsequent Failed Logins
-token=Token
-tokenExpireTime=Token Expire Time
-confirmPassword=Password (confirm)
+creator=Creator
+lastChangeDate=Last change date
+lastModifier=Last modifier
Copied: syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/panels/SysInfoPanel_it.properties (from r1506478, syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/panels/AccountInformationPanel_it.properties)
URL: http://svn.apache.org/viewvc/syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/panels/SysInfoPanel_it.properties?p2=syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/panels/SysInfoPanel_it.properties&p1=syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/panels/AccountInformationPanel_it.properties&r1=1506478&r2=1506859&rev=1506859&view=diff
==============================================================================
--- syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/panels/AccountInformationPanel_it.properties (original)
+++ syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/panels/SysInfoPanel_it.properties Thu Jul 25 09:25:09 2013
@@ -15,9 +15,6 @@
# specific language governing permissions and limitations
# under the License.
creationDate=Data Di Creazione
-changePwdDate=Data Ultimo Cambio Password
-lastLoginDate=Data Di Ultimo Login
-failedLogins=Login Consecutivi Falliti
-token=Token
-tokenExpireTime=Scadenza Token
-confirmPassword=Password (conferma)
+creator=Creatore
+lastChangeDate=Data Di Ultima Modifica
+lastModifier=Ultimo Modificatore
Copied: syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/panels/SysInfoPanel_pt_BR.properties (from r1506478, syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/panels/AccountInformationPanel_pt_BR.properties)
URL: http://svn.apache.org/viewvc/syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/panels/SysInfoPanel_pt_BR.properties?p2=syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/panels/SysInfoPanel_pt_BR.properties&p1=syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/panels/AccountInformationPanel_pt_BR.properties&r1=1506478&r2=1506859&rev=1506859&view=diff
==============================================================================
--- syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/panels/AccountInformationPanel_pt_BR.properties (original)
+++ syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/panels/SysInfoPanel_pt_BR.properties Thu Jul 25 09:25:09 2013
@@ -14,10 +14,7 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-creationDate=Data de Cria\u00E7\u00E3o
-changePwdDate=Data da \u00DAltima Troca de Senha
-lastLoginDate=Data do \u00DAltimo Login
-failedLogins=Falhas Subsequentes de Logins
-token=Token
-tokenExpireTime=Tempo de Expira\u00E7\u00E3o do Token
-confirmPassword=Senha (confirmar)
+creationDate=Data de Cria\u00e7\u00e3o
+creator=Criador
+lastChangeDate=Data De \u00daltima Altera\u00e7\u00e3o
+lastModifier=\u00daltima Modificador
Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/AbstractAttributable.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/AbstractAttributable.java?rev=1506859&r1=1506858&r2=1506859&view=diff
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/AbstractAttributable.java (original)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/AbstractAttributable.java Thu Jul 25 09:25:09 2013
@@ -25,7 +25,7 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
-public abstract class AbstractAttributable extends AbstractBaseBean {
+public abstract class AbstractAttributable extends AbstractSysInfo {
private static final long serialVersionUID = -4801685541488201119L;
Added: syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/AbstractSysInfo.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/AbstractSysInfo.java?rev=1506859&view=auto
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/AbstractSysInfo.java (added)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/AbstractSysInfo.java Thu Jul 25 09:25:09 2013
@@ -0,0 +1,104 @@
+/*
+ * Copyright 2013 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.syncope.core.persistence.beans;
+
+import java.util.Date;
+import javax.persistence.Column;
+import javax.persistence.EntityListeners;
+import javax.persistence.MappedSuperclass;
+import javax.persistence.Temporal;
+import javax.persistence.TemporalType;
+import org.apache.syncope.core.util.SysInfoListener;
+
+/**
+ * Abstract wrapper for common system information.
+ */
+@MappedSuperclass
+@EntityListeners(value = SysInfoListener.class)
+public abstract class AbstractSysInfo extends AbstractBaseBean {
+
+ private static final long serialVersionUID = -4801685541488201219L;
+
+ /**
+ * Username of the user that has created this profile.
+ * <p>
+ * Cannot be used a reference to an existing user for two main reasons: the creator can be the user <tt>admin</tt>;
+ * the creator could have been removed.
+ */
+ @Column(nullable = false)
+ private String creator;
+
+ /**
+ * Creation date.
+ */
+ @Column(nullable = false)
+ @Temporal(TemporalType.TIMESTAMP)
+ private Date creationDate;
+
+ /**
+ * Username of the user that has performed the last modification to this profile.
+ * <p>
+ * This field cannot be null: at creation time it have to be initialized with the creator username.
+ * <p>
+ * The modifier can be the user itself whether the last performed change has been a self-modification.
+ * <p>
+ * Cannot be used a reference to an existing user for two main reasons: the modifier can be the user <tt>admin</tt>;
+ * the modifier could have been removed.
+ */
+ @Column(nullable = false)
+ private String lastModifier;
+
+ /**
+ * Last change date.
+ * <p>
+ * This field cannot be null: at creation time it has to be initialized with <tt>creationDate</tt> field value.
+ */
+ @Column(nullable = false)
+ @Temporal(TemporalType.TIMESTAMP)
+ private Date lastChangeDate;
+
+ public String getCreator() {
+ return creator;
+ }
+
+ public void setCreator(final String creator) {
+ this.creator = creator;
+ }
+
+ public Date getCreationDate() {
+ return creationDate == null ? null : new Date(creationDate.getTime());
+ }
+
+ public void setCreationDate(final Date creationDate) {
+ this.creationDate = creationDate == null ? null : new Date(creationDate.getTime());
+ }
+
+ public String getLastModifier() {
+ return lastModifier;
+ }
+
+ public void setLastModifier(final String lastModifier) {
+ this.lastModifier = lastModifier;
+ }
+
+ public Date getLastChangeDate() {
+ return lastChangeDate == null ? creationDate : lastChangeDate;
+ }
+
+ public void setLastChangeDate(final Date lastChangeDate) {
+ this.lastChangeDate = lastChangeDate == null ? null : new Date(lastChangeDate.getTime());
+ }
+}
Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/ExternalResource.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/ExternalResource.java?rev=1506859&r1=1506858&r2=1506859&view=diff
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/ExternalResource.java (original)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/ExternalResource.java Thu Jul 25 09:25:09 2013
@@ -50,7 +50,7 @@ import org.identityconnectors.framework.
*/
@Entity
@ExternalResourceCheck
-public class ExternalResource extends AbstractBaseBean {
+public class ExternalResource extends AbstractSysInfo {
private static final long serialVersionUID = -6937712883512073278L;
Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/UserRequest.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/UserRequest.java?rev=1506859&r1=1506858&r2=1506859&view=diff
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/UserRequest.java (original)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/UserRequest.java Thu Jul 25 09:25:09 2013
@@ -60,7 +60,7 @@ public class UserRequest extends Abstrac
public UserTO getUserTO() {
return type != UserRequestType.CREATE
? null
- : XMLSerializer.<UserTO> deserialize(payload);
+ : XMLSerializer.<UserTO>deserialize(payload);
}
public void setUserTO(final UserTO userTO) {
@@ -71,7 +71,7 @@ public class UserRequest extends Abstrac
public UserMod getUserMod() {
return type != UserRequestType.UPDATE
? null
- : XMLSerializer.<UserMod> deserialize(payload);
+ : XMLSerializer.<UserMod>deserialize(payload);
}
public void setUserMod(final UserMod userMod) {
Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/user/SyncopeUser.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/user/SyncopeUser.java?rev=1506859&r1=1506858&r2=1506859&view=diff
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/user/SyncopeUser.java (original)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/user/SyncopeUser.java Thu Jul 25 09:25:09 2013
@@ -59,6 +59,9 @@ import org.apache.syncope.core.persisten
import org.apache.syncope.core.util.PasswordEncoder;
import org.apache.syncope.core.util.SecureRandomUtil;
+/**
+ * Syncope user bean.
+ */
@Entity
@Cacheable
@SyncopeUserCheck
@@ -130,13 +133,6 @@ public class SyncopeUser extends Abstrac
private Date lastLoginDate;
/**
- * Creation date.
- */
- @NotNull
- @Temporal(TemporalType.TIMESTAMP)
- private Date creationDate;
-
- /**
* Change password date.
*/
@Column(nullable = true)
@@ -449,18 +445,6 @@ public class SyncopeUser extends Abstrac
: new Date(changePwdDate.getTime());
}
- public Date getCreationDate() {
- return creationDate == null
- ? null
- : new Date(creationDate.getTime());
- }
-
- public void setCreationDate(final Date creationDate) {
- this.creationDate = creationDate == null
- ? null
- : new Date(creationDate.getTime());
- }
-
public Integer getFailedLogins() {
return failedLogins == null ? 0 : failedLogins;
}
Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/dao/impl/MembershipDAOImpl.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/dao/impl/MembershipDAOImpl.java?rev=1506859&r1=1506858&r2=1506859&view=diff
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/dao/impl/MembershipDAOImpl.java (original)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/dao/impl/MembershipDAOImpl.java Thu Jul 25 09:25:09 2013
@@ -26,7 +26,6 @@ import org.apache.syncope.core.persisten
import org.apache.syncope.core.persistence.beans.role.SyncopeRole;
import org.apache.syncope.core.persistence.beans.user.SyncopeUser;
import org.apache.syncope.core.persistence.dao.MembershipDAO;
-import org.apache.syncope.core.persistence.dao.RoleDAO;
import org.apache.syncope.core.persistence.dao.UserDAO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
@@ -37,9 +36,6 @@ public class MembershipDAOImpl extends A
@Autowired
private UserDAO userDAO;
- @Autowired
- private RoleDAO roleDAO;
-
@Override
public Membership find(final Long id) {
return entityManager.find(Membership.class, id);
Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/rest/data/ResourceDataBinder.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/rest/data/ResourceDataBinder.java?rev=1506859&r1=1506858&r2=1506859&view=diff
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/rest/data/ResourceDataBinder.java (original)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/rest/data/ResourceDataBinder.java Thu Jul 25 09:25:09 2013
@@ -285,6 +285,12 @@ public class ResourceDataBinder {
ResourceTO resourceTO = new ResourceTO();
+ // set sys info
+ resourceTO.setCreator(resource.getCreator());
+ resourceTO.setCreationDate(resource.getCreationDate());
+ resourceTO.setLastModifier(resource.getLastModifier());
+ resourceTO.setLastChangeDate(resource.getLastChangeDate());
+
// set the resource name
resourceTO.setName(resource.getName());
Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/rest/data/RoleDataBinder.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/rest/data/RoleDataBinder.java?rev=1506859&r1=1506858&r2=1506859&view=diff
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/rest/data/RoleDataBinder.java (original)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/rest/data/RoleDataBinder.java Thu Jul 25 09:25:09 2013
@@ -288,6 +288,13 @@ public class RoleDataBinder extends Abst
connObjectUtil.retrieveVirAttrValues(role, AttributableUtil.getInstance(AttributableType.ROLE));
RoleTO roleTO = new RoleTO();
+
+ // set sys info
+ roleTO.setCreator(role.getCreator());
+ roleTO.setCreationDate(role.getCreationDate());
+ roleTO.setLastModifier(role.getLastModifier());
+ roleTO.setLastChangeDate(role.getLastChangeDate());
+
roleTO.setId(role.getId());
roleTO.setName(role.getName());
Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/rest/data/UserDataBinder.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/rest/data/UserDataBinder.java?rev=1506859&r1=1506858&r2=1506859&view=diff
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/rest/data/UserDataBinder.java (original)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/rest/data/UserDataBinder.java Thu Jul 25 09:25:09 2013
@@ -225,9 +225,6 @@ public class UserDataBinder extends Abst
// set username
user.setUsername(userTO.getUsername());
-
- // set creation date (at execution time)
- user.setCreationDate(new Date());
}
/**
@@ -388,6 +385,13 @@ public class UserDataBinder extends Abst
MembershipTO membershipTO;
for (Membership membership : user.getMemberships()) {
membershipTO = new MembershipTO();
+
+ // set sys info
+ membershipTO.setCreator(membership.getCreator());
+ membershipTO.setCreationDate(membership.getCreationDate());
+ membershipTO.setLastModifier(membership.getLastModifier());
+ membershipTO.setLastChangeDate(membership.getLastChangeDate());
+
membershipTO.setId(membership.getId());
membershipTO.setRoleId(membership.getSyncopeRole().getId());
membershipTO.setRoleName(membership.getSyncopeRole().getName());
Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/util/JexlUtil.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/util/JexlUtil.java?rev=1506859&r1=1506858&r2=1506859&view=diff
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/util/JexlUtil.java (original)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/util/JexlUtil.java Thu Jul 25 09:25:09 2013
@@ -18,7 +18,11 @@
*/
package org.apache.syncope.core.util;
+import java.beans.IntrospectionException;
+import java.beans.Introspector;
+import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
+import java.lang.reflect.Method;
import java.util.Collection;
import java.util.Date;
import java.util.List;
@@ -50,7 +54,7 @@ public class JexlUtil {
*/
private static final Logger LOG = LoggerFactory.getLogger(JexlUtil.class);
- private static final String[] IGNORE_FIELDS = {"password", "clearPassword", "serialVersionUID"};
+ private static final String[] IGNORE_FIELDS = {"password", "clearPassword", "serialVersionUID", "class"};
@Autowired
private JexlEngine jexlEngine;
@@ -89,34 +93,45 @@ public class JexlUtil {
}
public JexlContext addFieldsToContext(final Object attributable, final JexlContext jexlContext) {
- JexlContext context = jexlContext == null
- ? new MapContext()
- : jexlContext;
+ JexlContext context = jexlContext == null ? new MapContext() : jexlContext;
- final Field[] fields = attributable.getClass().getDeclaredFields();
- for (int i = 0; i < fields.length; i++) {
- try {
- Field field = fields[i];
- field.setAccessible(true);
- final String fieldName = field.getName();
- if ((!field.isSynthetic()) && (!fieldName.startsWith("pc"))
- && (!ArrayUtils.contains(IGNORE_FIELDS, fieldName))
- && (!Iterable.class.isAssignableFrom(field.getType()))
- && (!field.getType().isArray())) {
-
- final Object fieldValue = field.get(attributable);
-
- context.set(fieldName, fieldValue == null
- ? ""
- : (field.getType().equals(Date.class)
- ? DataFormat.format((Date) fieldValue, false)
- : fieldValue));
+ try {
+ for (PropertyDescriptor desc : Introspector.getBeanInfo(attributable.getClass()).getPropertyDescriptors()) {
+ final Class<?> type = desc.getPropertyType();
+ final String fieldName = desc.getName();
- LOG.debug("Add field {} with value {}", fieldName, fieldValue);
+ if ((!fieldName.startsWith("pc"))
+ && (!ArrayUtils.contains(IGNORE_FIELDS, fieldName))
+ && (!Iterable.class.isAssignableFrom(type))
+ && (!type.isArray())) {
+ try {
+ final Method getter = desc.getReadMethod();
+
+ final Object fieldValue;
+
+ if (getter == null) {
+ final Field field = attributable.getClass().getDeclaredField(fieldName);
+ field.setAccessible(true);
+ fieldValue = field.get(attributable);
+ } else {
+ fieldValue = getter.invoke(attributable);
+ }
+
+ context.set(fieldName, fieldValue == null
+ ? ""
+ : (type.equals(Date.class)
+ ? DataFormat.format((Date) fieldValue, false)
+ : fieldValue));
+
+ LOG.debug("Add field {} with value {}", fieldName, fieldValue);
+
+ } catch (Exception iae) {
+ LOG.error("Reading '{}' value error", fieldName, iae);
+ }
}
- } catch (Exception e) {
- LOG.error("Reading class attributes error", e);
}
+ } catch (IntrospectionException ie) {
+ LOG.error("Reading class attributes error", ie);
}
return context;
Added: syncope/trunk/core/src/main/java/org/apache/syncope/core/util/SysInfoListener.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/util/SysInfoListener.java?rev=1506859&view=auto
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/util/SysInfoListener.java (added)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/util/SysInfoListener.java Thu Jul 25 09:25:09 2013
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2013 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.syncope.core.util;
+
+import java.util.Date;
+import javax.persistence.PrePersist;
+import javax.persistence.PreUpdate;
+import org.apache.syncope.core.persistence.beans.AbstractSysInfo;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class SysInfoListener {
+
+ /**
+ * Logger.
+ */
+ protected static final Logger LOG = LoggerFactory.getLogger(SysInfoListener.class);
+
+ @PrePersist
+ @PreUpdate
+ public void setSysInfo(final AbstractSysInfo entity) {
+ try {
+ final String username = EntitlementUtil.getAuthenticatedUsername();
+ LOG.debug("Set system properties for '{}'", entity);
+
+ final Date now = new Date();
+
+ if (entity.getCreationDate() == null) {
+ LOG.debug("Set creation date '{}' and creator '{}' for '{}'", new Object[] {now, username, entity});
+ entity.setCreationDate(now);
+ entity.setCreator(username);
+ }
+
+ LOG.debug("Set last change date '{}' and modifier '{}' for '{}'", new Object[] {now, username, entity});
+ entity.setLastModifier(username);
+ entity.setLastChangeDate(now);
+ } catch (Exception e) {
+ // In case of exception, do not trace create/update event info: maybe it's an internal management action.
+ // See SyncopeAuthenticationProvider for instance.
+ LOG.info("Unauthenticated user action: no system property to be update");
+ }
+ }
+}
Modified: syncope/trunk/core/src/test/java/org/apache/syncope/core/persistence/dao/DerAttrTest.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/test/java/org/apache/syncope/core/persistence/dao/DerAttrTest.java?rev=1506859&r1=1506858&r2=1506859&view=diff
==============================================================================
--- syncope/trunk/core/src/test/java/org/apache/syncope/core/persistence/dao/DerAttrTest.java (original)
+++ syncope/trunk/core/src/test/java/org/apache/syncope/core/persistence/dao/DerAttrTest.java Thu Jul 25 09:25:09 2013
@@ -192,7 +192,7 @@ public class DerAttrTest extends Abstrac
assertNotNull(value);
assertFalse(value.isEmpty());
assertTrue(value.startsWith("active - vivaldi - 2010-10-20"));
- assertTrue(value.endsWith("[]"));
+ assertTrue(value.endsWith("[0]"));
}
@Test
Modified: syncope/trunk/core/src/test/java/org/apache/syncope/core/persistence/relationships/AttrTest.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/test/java/org/apache/syncope/core/persistence/relationships/AttrTest.java?rev=1506859&r1=1506858&r2=1506859&view=diff
==============================================================================
--- syncope/trunk/core/src/test/java/org/apache/syncope/core/persistence/relationships/AttrTest.java (original)
+++ syncope/trunk/core/src/test/java/org/apache/syncope/core/persistence/relationships/AttrTest.java Thu Jul 25 09:25:09 2013
@@ -157,6 +157,6 @@ public class AttrTest extends AbstractDA
assertNotNull(value);
assertFalse(value.isEmpty());
assertTrue(value.startsWith("vivaldi - 2010-10-20"));
- assertTrue(value.endsWith("[]"));
+ assertTrue(value.endsWith("[0]"));
}
}
Modified: syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/AuthenticationTestITCase.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/AuthenticationTestITCase.java?rev=1506859&r1=1506858&r2=1506859&view=diff
==============================================================================
--- syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/AuthenticationTestITCase.java (original)
+++ syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/AuthenticationTestITCase.java Thu Jul 25 09:25:09 2013
@@ -24,7 +24,6 @@ import static org.junit.Assert.assertNot
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
-import java.net.Authenticator;
import java.security.AccessControlException;
import java.util.HashSet;
import java.util.List;
@@ -32,7 +31,6 @@ import java.util.Set;
import javax.ws.rs.core.Response;
-import org.apache.cxf.transport.http.CXFAuthenticator;
import org.apache.syncope.common.search.AttributeCond;
import org.apache.syncope.common.search.NodeCond;
import org.apache.syncope.common.services.InvalidSearchConditionException;
Modified: syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/RoleTestITCase.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/RoleTestITCase.java?rev=1506859&r1=1506858&r2=1506859&view=diff
==============================================================================
--- syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/RoleTestITCase.java (original)
+++ syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/RoleTestITCase.java Thu Jul 25 09:25:09 2013
@@ -291,6 +291,12 @@ public class RoleTestITCase extends Abst
// 1. read role as admin
RoleTO roleTO = roleService.read(7L);
+ // issue SYNCOPE-15
+ assertNotNull(roleTO.getCreationDate());
+ assertNotNull(roleTO.getLastChangeDate());
+ assertEquals("admin", roleTO.getCreator());
+ assertEquals("admin", roleTO.getLastModifier());
+
// 2. prepare update
RoleMod roleMod = new RoleMod();
roleMod.setId(roleTO.getId());
@@ -313,6 +319,13 @@ public class RoleTestITCase extends Abst
roleTO = roleService3.update(roleMod.getId(), roleMod);
assertEquals("Managing Director", roleTO.getName());
+
+ // issue SYNCOPE-15
+ assertNotNull(roleTO.getCreationDate());
+ assertNotNull(roleTO.getLastChangeDate());
+ assertEquals("admin", roleTO.getCreator());
+ assertEquals("puccini", roleTO.getLastModifier());
+ assertTrue(roleTO.getCreationDate().before(roleTO.getLastChangeDate()));
}
/**
Modified: syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/UserTestITCase.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/UserTestITCase.java?rev=1506859&r1=1506858&r2=1506859&view=diff
==============================================================================
--- syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/UserTestITCase.java (original)
+++ syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/UserTestITCase.java Thu Jul 25 09:25:09 2013
@@ -418,6 +418,14 @@ public class UserTestITCase extends Abst
UserTO newUserTO = createUser(userTO);
assertNotNull(newUserTO);
+
+ // issue SYNCOPE-15
+ assertNotNull(newUserTO.getCreationDate());
+ assertNotNull(newUserTO.getCreator());
+ assertNotNull(newUserTO.getLastChangeDate());
+ assertNotNull(newUserTO.getLastModifier());
+ assertEquals(newUserTO.getCreationDate(), newUserTO.getLastChangeDate());
+
assertFalse(newUserTO.getAttributes().contains(attrWithInvalidSchemaTO));
// check for changePwdDate
@@ -452,8 +460,7 @@ public class UserTestITCase extends Abst
assertEquals(maxTaskExecutions, taskTO.getExecutions().size());
// 3. verify password
- UserService userService1 = createServiceInstance(UserService.class, newUserTO.getUsername(),
- "password123");
+ UserService userService1 = createServiceInstance(UserService.class, newUserTO.getUsername(), "password123");
try {
UserTO user = userService1.readSelf();
assertNotNull(user);
@@ -461,8 +468,7 @@ public class UserTestITCase extends Abst
fail("Credentials should be valid and not cause AccessControlException");
}
- UserService userService2 = createServiceInstance(UserService.class, newUserTO.getUsername(),
- "passwordXX");
+ UserService userService2 = createServiceInstance(UserService.class, newUserTO.getUsername(), "passwordXX");
try {
userService2.readSelf();
fail("Credentials are invalid, thus request should raise AccessControlException");
@@ -877,6 +883,13 @@ public class UserTestITCase extends Abst
userTO = userService.update(userMod.getId(), userMod);
assertNotNull(userTO);
+ // issue SYNCOPE-15
+ assertNotNull(userTO.getCreationDate());
+ assertNotNull(userTO.getCreator());
+ assertNotNull(userTO.getLastChangeDate());
+ assertNotNull(userTO.getLastModifier());
+ assertTrue(userTO.getCreationDate().before(userTO.getLastChangeDate()));
+
SyncopeUser passwordTestUser = new SyncopeUser();
passwordTestUser.setPassword("new2Password", CipherAlgorithm.SHA1, 0);
assertEquals(passwordTestUser.getPassword(), userTO.getPassword());
@@ -1822,7 +1835,7 @@ public class UserTestITCase extends Abst
userTO.getResources().clear();
userTO.addResource(RESOURCE_NAME_TESTDB);
userTO.addResource("resource-testdb2");
-
+
userTO = createUser(userTO);
assertNotNull(userTO);
assertTrue(userTO.getResources().contains(RESOURCE_NAME_TESTDB));