Commit ef280938 by Yiming Liu

Add audit for services

parent 7795a848
......@@ -41,7 +41,7 @@ public class AppController {
public void delete(@PathVariable("appId") String appId) {
App entity = appService.findOne(appId);
if (entity == null) throw new NotFoundException("app not found for appId " + appId);
appService.delete(entity.getId());
appService.delete(entity.getId(), "who");
}
@RequestMapping("/apps")
......
......@@ -42,7 +42,7 @@ public class ClusterController {
Cluster entity = clusterService.findOne(appId, clusterName);
if (entity == null)
throw new NotFoundException("cluster not found for clusterName " + clusterName);
clusterService.delete(entity.getId());
clusterService.delete(entity.getId(), "who");
}
@RequestMapping("/apps/{appId}/clusters")
......
......@@ -39,7 +39,7 @@ public class ItemController {
public void delete(@PathVariable("itemId") long itemId) {
Item entity = itemService.findOne(itemId);
if (entity == null) throw new NotFoundException("item not found for itemId " + itemId);
itemService.delete(entity.getId());
itemService.delete(entity.getId(), "who");
}
@RequestMapping("/apps/{appId}/clusters/{clusterName}/namespaces/{namespaceName}/items")
......
......@@ -51,7 +51,7 @@ public class NamespaceController {
Namespace entity = namespaceService.findOne(appId, clusterName, namespaceName);
if (entity == null) throw new NotFoundException(
String.format("namespace not found for %s %s %s", appId, clusterName, namespaceName));
namespaceService.delete(entity.getId());
namespaceService.delete(entity.getId(), "who");
}
@RequestMapping("/apps/{appId}/clusters/{clusterName}/namespaces")
......
......@@ -63,7 +63,7 @@ public class ReleaseController {
@PathVariable("clusterName") String clusterName,
@PathVariable("namespaceName") String namespaceName, @RequestParam("name") String name,
@RequestParam(name = "comment", required = false) String comment) {
Release release = releaseService.buildRelease(name, comment, appId, clusterName, namespaceName);
Release release = releaseService.buildRelease(name, comment, appId, clusterName, namespaceName, "who");
return BeanUtils.transfrom(ReleaseDTO.class, release);
}
}
package com.ctrip.apollo.biz.entity;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Table;
import org.hibernate.annotations.SQLDelete;
import org.hibernate.annotations.Where;
@Entity
@Table(name = "Audit")
@SQLDelete(sql = "Update Audit set isDeleted = 1 where id = ?")
@Where(clause = "isDeleted = 0")
public class Audit extends BaseEntity {
public enum OP {
INSERT, UPDATE, DELETE
}
@Column(name = "EntityName", nullable = false)
private String entityName;
@Column(name="EntityId")
private Long entityId;
@Column(name = "OpName", nullable = false)
private String opName;
@Column(name = "Comment")
private String comment;
public String getComment() {
return comment;
}
public Long getEntityId() {
return entityId;
}
public String getEntityName() {
return entityName;
}
public String getOpName() {
return opName;
}
public void setComment(String comment) {
this.comment = comment;
}
public void setEntityId(Long entityId) {
this.entityId = entityId;
}
public void setEntityName(String entityName) {
this.entityName = entityName;
}
public void setOpName(String opName) {
this.opName = opName;
}
}
......@@ -12,6 +12,8 @@ import javax.persistence.PrePersist;
import javax.persistence.PreRemove;
import javax.persistence.PreUpdate;
import com.ctrip.apollo.core.utils.ToStringHelper;
@MappedSuperclass
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public abstract class BaseEntity {
......@@ -24,10 +26,10 @@ public abstract class BaseEntity {
@Column(name = "IsDeleted", columnDefinition = "Bit default '0'")
protected boolean isDeleted = false;
@Column(name = "DataChange_CreatedBy")
@Column(name = "DataChange_CreatedBy", nullable = false)
private String dataChangeCreatedBy;
@Column(name = "DataChange_CreatedTime")
@Column(name = "DataChange_CreatedTime", nullable = false)
private Date dataChangeCreatedTime;
@Column(name = "DataChange_LastModifiedBy")
......@@ -85,18 +87,21 @@ public abstract class BaseEntity {
}
@PrePersist
private void prePersist() {
protected void prePersist() {
if (this.dataChangeCreatedTime == null) dataChangeCreatedTime = new Date();
}
@PreUpdate
private void preUpdate() {
protected void preUpdate() {
this.dataChangeLastModifiedTime = new Date();
}
@PreRemove
private void preRemove() {
protected void preRemove() {
this.dataChangeLastModifiedTime = new Date();
}
public String toString() {
return ToStringHelper.toString(this);
}
}
package com.ctrip.apollo.biz.repository;
import java.util.List;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.data.repository.query.Param;
import com.ctrip.apollo.biz.entity.Audit;
public interface AuditRepository extends PagingAndSortingRepository<Audit, Long> {
@Query("SELECT a from Audit a WHERE a.dataChangeCreatedBy = :owner")
List<Audit> findByOwner(@Param("owner") String owner);
@Query("SELECT a from Audit a WHERE a.dataChangeCreatedBy = :owner AND a.entityName =:entity AND a.opName = :op")
List<Audit> findAudits(@Param("owner") String owner, @Param("entity") String entity,
@Param("op") String op);
}
......@@ -6,6 +6,7 @@ import org.springframework.transaction.annotation.Transactional;
import com.ctrip.apollo.biz.entity.App;
import com.ctrip.apollo.biz.entity.AppNamespace;
import com.ctrip.apollo.biz.entity.Audit;
import com.ctrip.apollo.biz.entity.Cluster;
import com.ctrip.apollo.biz.entity.Namespace;
import com.ctrip.apollo.biz.repository.AppNamespaceRepository;
......@@ -14,9 +15,6 @@ import com.ctrip.apollo.biz.repository.ClusterRepository;
import com.ctrip.apollo.biz.repository.NamespaceRepository;
import com.ctrip.apollo.core.ConfigConsts;
import java.util.Date;
@Service
public class AdminService {
......@@ -32,10 +30,16 @@ public class AdminService {
@Autowired
private ClusterRepository clusterRepository;
@Autowired
private AuditService auditService;
@Transactional
public App createNewApp(App app) {
String createBy = app.getDataChangeCreatedBy();
App createdApp = appRepository.save(app);
auditService.audit(App.class.getSimpleName(), createdApp.getId(), Audit.OP.INSERT, createBy);
String appId = createdApp.getAppId();
createDefaultAppNamespace(appId, createBy);
......@@ -47,36 +51,39 @@ public class AdminService {
return app;
}
private void createDefaultAppNamespace(String appId, String createBy){
private void createDefaultAppNamespace(String appId, String createBy) {
AppNamespace appNs = new AppNamespace();
appNs.setAppId(appId);
appNs.setName(ConfigConsts.NAMESPACE_APPLICATION);
appNs.setComment("default app namespace");
appNs.setDataChangeCreatedBy(createBy);
appNs.setDataChangeCreatedTime(new Date());
appNs.setDataChangeLastModifiedBy(createBy);
appNamespaceRepository.save(appNs);
auditService.audit(AppNamespace.class.getSimpleName(), appNs.getId(), Audit.OP.INSERT,
createBy);
}
private void createDefaultCluster(String appId, String createBy){
private void createDefaultCluster(String appId, String createBy) {
Cluster cluster = new Cluster();
cluster.setName(ConfigConsts.CLUSTER_NAME_DEFAULT);
cluster.setAppId(appId);
cluster.setDataChangeCreatedBy(createBy);
cluster.setDataChangeCreatedTime(new Date());
cluster.setDataChangeLastModifiedBy(createBy);
clusterRepository.save(cluster);
auditService.audit(Cluster.class.getSimpleName(), cluster.getId(), Audit.OP.INSERT, createBy);
}
private void createDefaultNamespace(String appId, String createBy){
private void createDefaultNamespace(String appId, String createBy) {
Namespace ns = new Namespace();
ns.setAppId(appId);
ns.setClusterName(ConfigConsts.CLUSTER_NAME_DEFAULT);
ns.setNamespaceName(ConfigConsts.NAMESPACE_APPLICATION);
ns.setDataChangeCreatedBy(createBy);
ns.setDataChangeCreatedTime(new Date());
ns.setDataChangeLastModifiedBy(createBy);
namespaceRepository.save(ns);
auditService.audit(Namespace.class.getSimpleName(), ns.getId(), Audit.OP.INSERT, createBy);
}
}
......@@ -9,6 +9,7 @@ import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.ctrip.apollo.biz.entity.App;
import com.ctrip.apollo.biz.entity.Audit;
import com.ctrip.apollo.biz.repository.AppRepository;
import com.ctrip.apollo.common.utils.BeanUtils;
......@@ -18,9 +19,14 @@ public class AppService {
@Autowired
private AppRepository appRepository;
@Autowired
private AuditService auditService;
@Transactional
public void delete(long id) {
public void delete(long id, String owner) {
appRepository.delete(id);
auditService.audit(App.class.getSimpleName(), id, Audit.OP.DELETE, owner);
}
public List<App> findAll(Pageable pageable) {
......@@ -38,13 +44,23 @@ public class AppService {
@Transactional
public App save(App entity) {
return appRepository.save(entity);
App app = appRepository.save(entity);
auditService.audit(App.class.getSimpleName(), app.getId(), Audit.OP.INSERT,
app.getDataChangeCreatedBy());
return app;
}
@Transactional
public App update(App app) {
App managedApp = appRepository.findByAppId(app.getAppId());
BeanUtils.copyEntityProperties(app, managedApp);
return appRepository.save(managedApp);
managedApp = appRepository.save(managedApp);
auditService.audit(App.class.getSimpleName(), managedApp.getId(), Audit.OP.UPDATE,
managedApp.getDataChangeLastModifiedBy());
return managedApp;
}
}
package com.ctrip.apollo.biz.service;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.ctrip.apollo.biz.entity.Audit;
import com.ctrip.apollo.biz.repository.AuditRepository;
@Service
public class AuditService {
@Autowired
private AuditRepository auditRepository;
List<Audit> findByOwner(String owner) {
return auditRepository.findByOwner(owner);
}
List<Audit> find(String owner, String entity, String op) {
return auditRepository.findAudits(owner, entity, op);
}
@Transactional
void audit(String entityName, Long entityId, Audit.OP op, String owner) {
Audit audit = new Audit();
audit.setEntityName(entityName);
audit.setEntityId(entityId);
audit.setOpName(op.name());
audit.setDataChangeCreatedBy(owner);
auditRepository.save(audit);
}
@Transactional
void audit(Audit audit){
auditRepository.save(audit);
}
}
......@@ -4,6 +4,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.ctrip.apollo.biz.entity.Audit;
import com.ctrip.apollo.biz.entity.Cluster;
import com.ctrip.apollo.biz.repository.ClusterRepository;
import com.ctrip.apollo.common.utils.BeanUtils;
......@@ -14,18 +15,28 @@ public class ClusterService {
@Autowired
private ClusterRepository clusterRepository;
@Autowired
private AuditService auditService;
public Cluster findOne(String appId, String name) {
return clusterRepository.findByAppIdAndName(appId, name);
}
@Transactional
public Cluster save(Cluster entity) {
return clusterRepository.save(entity);
Cluster cluster = clusterRepository.save(entity);
auditService.audit(Cluster.class.getSimpleName(), cluster.getId(), Audit.OP.INSERT,
cluster.getDataChangeCreatedBy());
return cluster;
}
@Transactional
public void delete(long id) {
public void delete(long id, String owner) {
clusterRepository.delete(id);
auditService.audit(Cluster.class.getSimpleName(), id, Audit.OP.DELETE, owner);
}
@Transactional
......@@ -33,6 +44,11 @@ public class ClusterService {
Cluster managedCluster =
clusterRepository.findByAppIdAndName(cluster.getAppId(), cluster.getName());
BeanUtils.copyEntityProperties(cluster, managedCluster);
return clusterRepository.save(managedCluster);
managedCluster = clusterRepository.save(managedCluster);
auditService.audit(Cluster.class.getSimpleName(), managedCluster.getId(), Audit.OP.UPDATE,
managedCluster.getDataChangeLastModifiedBy());
return managedCluster;
}
}
......@@ -4,6 +4,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.ctrip.apollo.biz.entity.Audit;
import com.ctrip.apollo.biz.entity.Item;
import com.ctrip.apollo.biz.repository.ItemRepository;
import com.ctrip.apollo.common.utils.BeanUtils;
......@@ -14,9 +15,14 @@ public class ItemService {
@Autowired
private ItemRepository itemRepository;
@Autowired
private AuditService auditService;
@Transactional
public void delete(long id) {
public void delete(long id, String owner) {
itemRepository.delete(id);
auditService.audit(Item.class.getSimpleName(), id, Audit.OP.DELETE, owner);
}
public Item findOne(long itemId) {
......@@ -25,15 +31,25 @@ public class ItemService {
}
@Transactional
public Item save(Item item) {
return itemRepository.save(item);
public Item save(Item entity) {
Item item = itemRepository.save(entity);
auditService.audit(Item.class.getSimpleName(), item.getId(), Audit.OP.INSERT,
item.getDataChangeCreatedBy());
return item;
}
@Transactional
public Item update(Item item) {
Item managedItem = itemRepository.findOne(item.getId());
BeanUtils.copyEntityProperties(item, managedItem);
return itemRepository.save(managedItem);
managedItem = itemRepository.save(managedItem);
auditService.audit(Item.class.getSimpleName(), managedItem.getId(), Audit.OP.UPDATE,
managedItem.getDataChangeLastModifiedBy());
return managedItem;
}
}
......@@ -4,6 +4,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.ctrip.apollo.biz.entity.Audit;
import com.ctrip.apollo.biz.entity.Item;
import com.ctrip.apollo.biz.repository.ItemRepository;
import com.ctrip.apollo.common.utils.BeanUtils;
......@@ -16,6 +17,9 @@ public class ItemSetService {
@Autowired
private ItemRepository itemRepository;
@Autowired
private AuditService auditService;
@Transactional
public void updateSet(ItemChangeSets changeSet) {
if (changeSet.getCreateItems() != null) {
......@@ -25,6 +29,7 @@ public class ItemSetService {
entity.setDataChangeLastModifiedBy(changeSet.getModifyBy());
itemRepository.save(entity);
}
auditService.audit("ItemSet", null, Audit.OP.INSERT, changeSet.getModifyBy());
}
if (changeSet.getUpdateItems() != null) {
......@@ -35,6 +40,7 @@ public class ItemSetService {
managedItem.setDataChangeLastModifiedBy(changeSet.getModifyBy());
itemRepository.save(managedItem);
}
auditService.audit("ItemSet", null, Audit.OP.UPDATE, changeSet.getModifyBy());
}
if (changeSet.getDeleteItems() != null) {
......@@ -44,6 +50,7 @@ public class ItemSetService {
itemRepository.save(entity);
itemRepository.delete(item.getId());
}
auditService.audit("ItemSet", null, Audit.OP.DELETE, changeSet.getModifyBy());
}
}
}
......@@ -4,6 +4,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.ctrip.apollo.biz.entity.Audit;
import com.ctrip.apollo.biz.entity.Namespace;
import com.ctrip.apollo.biz.repository.NamespaceRepository;
import com.ctrip.apollo.common.utils.BeanUtils;
......@@ -14,9 +15,14 @@ public class NamespaceService {
@Autowired
private NamespaceRepository namespaceRepository;
@Autowired
private AuditService auditService;
@Transactional
public void delete(long id) {
public void delete(long id, String owner) {
namespaceRepository.delete(id);
auditService.audit(Namespace.class.getSimpleName(), id, Audit.OP.DELETE, owner);
}
public Namespace findOne(Long namespaceId) {
......@@ -30,7 +36,12 @@ public class NamespaceService {
@Transactional
public Namespace save(Namespace entity) {
return namespaceRepository.save(entity);
Namespace namespace = namespaceRepository.save(entity);
auditService.audit(Namespace.class.getSimpleName(), namespace.getId(), Audit.OP.INSERT,
namespace.getDataChangeCreatedBy());
return namespace;
}
@Transactional
......@@ -38,6 +49,11 @@ public class NamespaceService {
Namespace managedNamespace = namespaceRepository.findByAppIdAndClusterNameAndNamespaceName(
namespace.getAppId(), namespace.getClusterName(), namespace.getNamespaceName());
BeanUtils.copyEntityProperties(namespace, managedNamespace);
return namespaceRepository.save(managedNamespace);
managedNamespace = namespaceRepository.save(managedNamespace);
auditService.audit(Namespace.class.getSimpleName(), managedNamespace.getId(), Audit.OP.UPDATE,
managedNamespace.getDataChangeLastModifiedBy());
return managedNamespace;
}
}
package com.ctrip.apollo.biz.service;
import com.ctrip.apollo.biz.entity.Audit;
import com.ctrip.apollo.biz.entity.Privilege;
import com.ctrip.apollo.biz.repository.PrivilegeRepository;
......@@ -19,6 +20,9 @@ public class PrivilegeService {
@Autowired
private PrivilegeRepository privilRepo;
@Autowired
private AuditService auditService;
@Transactional
public Privilege addPrivilege(long namespaceId, String name, PrivilType privilType) {
Privilege privil =
......@@ -29,6 +33,8 @@ public class PrivilegeService {
privil.setPrivilType(privilType.name());
privil.setName(name);
privilRepo.save(privil);
auditService.audit(Privilege.class.getSimpleName(), privil.getId(), Audit.OP.INSERT, name);
}
return privil;
}
......@@ -47,6 +53,10 @@ public class PrivilegeService {
public void removePrivilege(long namespaceId, String name, PrivilType privilType) {
Privilege privil =
privilRepo.findByNamespaceIdAndNameAndPrivilType(namespaceId, name, privilType.name());
if (privil != null) privilRepo.delete(privil);
if (privil != null) {
privilRepo.delete(privil);
auditService.audit(Privilege.class.getSimpleName(), privil.getId(), Audit.OP.DELETE, name);
}
}
}
......@@ -9,6 +9,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.ctrip.apollo.biz.entity.Audit;
import com.ctrip.apollo.biz.entity.Item;
import com.ctrip.apollo.biz.entity.Namespace;
import com.ctrip.apollo.biz.entity.Release;
......@@ -34,6 +35,9 @@ public class ReleaseService {
@Autowired
private ItemRepository itemRepository;
@Autowired
private AuditService auditService;
private Gson gson = new Gson();
public Release findOne(long releaseId) {
......@@ -43,7 +47,7 @@ public class ReleaseService {
@Transactional
public Release buildRelease(String name, String comment, String appId, String clusterName,
String namespaceName) {
String namespaceName, String owner) {
Namespace namespace = namespaceRepository.findByAppIdAndClusterNameAndNamespaceName(appId,
clusterName, namespaceName);
if (namespace == null) {
......@@ -61,15 +65,19 @@ public class ReleaseService {
Release release = new Release();
release.setDataChangeCreatedTime(new Date());
release.setDataChangeCreatedBy(name);
release.setDataChangeLastModifiedBy(name);
release.setDataChangeCreatedBy(owner);
release.setName(name);
release.setComment(comment);
release.setAppId(appId);
release.setClusterName(clusterName);
release.setNamespaceName(namespaceName);
release.setConfigurations(gson.toJson(configurations));
return releaseRepository.save(release);
release = releaseRepository.save(release);
auditService.audit(Release.class.getSimpleName(), release.getId(), Audit.OP.INSERT,
release.getDataChangeCreatedBy());
return release;
}
}
......@@ -14,6 +14,7 @@ import org.springframework.transaction.annotation.Transactional;
import com.ctrip.apollo.biz.BizTestConfiguration;
import com.ctrip.apollo.biz.entity.App;
import com.ctrip.apollo.biz.entity.Audit;
import com.ctrip.apollo.biz.entity.Cluster;
import com.ctrip.apollo.biz.entity.Namespace;
......@@ -29,6 +30,9 @@ public class AdminServiceTest {
@Autowired
private ViewService viewService;
@Autowired
private AuditService auditService;
@Test
public void testCreateNewApp() {
String appId = "someAppId";
......@@ -52,6 +56,9 @@ public class AdminServiceTest {
List<Namespace> namespaces = viewService.findNamespaces(appId, clusters.get(0).getName());
Assert.assertEquals(1, namespaces.size());
Assert.assertEquals("application", namespaces.get(0).getNamespaceName());
List<Audit> audits = auditService.findByOwner(owner);
Assert.assertEquals(4, audits.size());
}
}
package com.ctrip.apollo.core.utils;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Calendar;
public final class ToStringHelper {
private ToStringHelper() {
}
/**
* For a given class object, return a string representation which contains the implementation of
* POJO's get methods only. This should be used for POJO's (Plain Old Java Objects) only.
*
* @param objectInstance java.lang.Object of the POJO for which toString implementation should be
* returned.
*
* @return POJO getters are invoked and appended to a string which is returned from this method.
*
* @since Project v1.1
* @see #getStringUsingBean(Object)
*/
public static String toString(Object objectInstance) {
return getStringUsingBean(objectInstance);
}
/**
* Uses java.beans.PropertyDescriptor to get the getters. This way, we avoid using filters like in
* {@link #getString(Object)}
*
* @param objectInstance Instance of an object for which tostring is required.
*
* @return toString implementation of this.
*
* @see #toString(Object)
*/
private static String getStringUsingBean(Object objectInstance) {
StringBuilder buildString = null;
try {
PropertyDescriptor[] propertyDescriptors =
Introspector.getBeanInfo(objectInstance.getClass()).getPropertyDescriptors();
buildString = new StringBuilder(propertyDescriptors.length * 4);
for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {
Method method = propertyDescriptor.getReadMethod();
if (method != null && !"class".equals(propertyDescriptor.getName())) {
String methodName = method.getName().substring(3);
buildString.append(methodName);
buildString.append(" = ");
// Check if there exists any parent. This check will avoid stack over flow if any.
if (isParent(methodName, method, buildString)) {
continue;
} else {
Object objectReturned = method.invoke(objectInstance);
if (objectReturned instanceof Calendar) {
// No need to print the entire Calendar object. just print the date and time.
buildString.append(getCalendarString((Calendar) objectReturned));
} else {
// Print the entire object.
buildString.append(objectReturned);
}
}
buildString.append(", ");
}
}
} catch (IntrospectionException | IllegalAccessException | IllegalArgumentException
| InvocationTargetException ex1) {
// getLogger().error("IntrospectionException while executing toString...", ex1);
}
return buildString.toString();
}
/**
* Check if there exists any parent in the methodName if so, get the declaraingClass just to
* indicate that this is a parent. Append to the buildString.
*
* @param methodName Name of the method (substring to 3 - to avoid get).
* @param method {@link Method}
* @param buildString {@link StringBuilder} to append
*
* @return True if an only if there exists a recursion.
*
* @see #toString(Object)
*/
private static boolean isParent(String methodName, Method method, StringBuilder buildString) {
// If methodName is one of the following, its going to go for infinite loop as its going to
// refer to
// the parent.
switch (methodName) {
case "ParentItem":
case "ParentRoot":
// Avoiding stackOverFlow.
buildString.append(method.getDeclaringClass());
return true;
default:
return false;
}
}
/**
* @return calendarReturned
*
* @see #toString(Object)
*/
private static String getCalendarString(Calendar calendarReturned) {
StringBuilder buildString = new StringBuilder(13);
buildString.append(calendarReturned.get(Calendar.YEAR));
buildString.append("-");
buildString.append(calendarReturned.get(Calendar.MONTH) + 1);
buildString.append("-");
buildString.append(calendarReturned.get(Calendar.DAY_OF_MONTH));
buildString.append(" ");
buildString.append(calendarReturned.get(Calendar.HOUR_OF_DAY));
buildString.append(":");
buildString.append(calendarReturned.get(Calendar.MINUTE));
buildString.append(":");
buildString.append(calendarReturned.get(Calendar.SECOND));
buildString.append(".");
buildString.append(calendarReturned.get(Calendar.MILLISECOND));
return buildString.toString();
}
/**
* Uses a typical reflection to get the methods of a given instance. Once we get the methods, we
* filter out the methods by set, get and invoke only get methods to append to the string which
* will later result into tostring-implementation.
*
* @param objectInstance Instance of an object for which tostring is required.
*
* @return toString implementation of this.
*
* @see #getString(Object)
*/
private static String getString(Object objectInstance) {
Class classObject = objectInstance.getClass();
// Get all the methods
Method[] methods = classObject.getDeclaredMethods();
int noOfMethods = methods.length;
StringBuilder buildString = new StringBuilder(noOfMethods + 2);
buildString.append(classObject);
buildString.append(" -->> ");
for (Method method : methods) {
String methodName = method.getName();
switch (methodName) {
case "toString":
case "main":
case "getLogger":
// Do Nothing
break;
default:
try {
buildString.append(extractMethodNames(classObject, objectInstance, methodName, method));
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException
| InstantiationException ex) {
// Do nothing as this is just printing the POJO implementations...
// getLogger().error("Exception while executing toString...", ex);
}
break;
}
}
return buildString.toString();
}
/**
* Executes a get method and returns the output as a string representing methodName = methodValue.
*
* @param methodName methodName for which method needs to be executed.
* @param method java.lang.reflect.Method
*
* @return A String value with methodName = methodValue.
*
* @throws IllegalAccessException if this Method object is enforcing Java language access control
* and the underlying method is inaccessible.
* @throws IllegalArgumentException if the method is an instance method and the specified object
* argument is not an instance of the class or interface declaring the underlying method
* (or of a subclass or implementor thereof); if the number of actual and formal
* parameters differ; if an unwrapping conversion for primitive arguments fails; or if,
* after possible unwrapping, a parameter value cannot be converted to the corresponding
* formal parameter type by a method invocation conversion.
* @throws InvocationTargetException if the underlying method throws an exception.
* @throws InstantiationException if this Class represents an abstract class, an interface, an
* array class, a primitive type, or void; or if the class has no nullary constructor; or
* if the instantiation fails for some other reason.
*
* @since Project v1.0
* @see #getString(Object)
*/
private static String extractMethodNames(Class classObject, Object objectInstance,
String methodName, Method method) throws IllegalAccessException, IllegalArgumentException,
InvocationTargetException, InstantiationException {
if (methodName.startsWith("set")) {
// Do nothing. We are interested only on get methods in toString method.
} else {
return methodName.substring(3) + " = " + method.invoke(objectInstance, (Object[]) null)
+ ", ";
}
return "";
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment