mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-24 17:32:48 +00:00
Merge from HEAD to WCM-DEV2.
git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/BRANCHES/WCM-DEV2/root@3659 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -0,0 +1,439 @@
|
||||
/*
|
||||
* Copyright (C) 2005 Alfresco, Inc.
|
||||
*
|
||||
* Licensed under the Mozilla Public License version 1.1
|
||||
* with a permitted attribution clause. You may obtain a
|
||||
* copy of the License at
|
||||
*
|
||||
* http://www.alfresco.org/legal/license.txt
|
||||
*
|
||||
* 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.alfresco.repo.audit.hibernate;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.Serializable;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.GregorianCalendar;
|
||||
import java.util.HashMap;
|
||||
|
||||
import org.alfresco.error.AlfrescoRuntimeException;
|
||||
import org.alfresco.repo.audit.AuditConfiguration;
|
||||
import org.alfresco.repo.audit.AuditDAO;
|
||||
import org.alfresco.repo.audit.AuditInfo;
|
||||
import org.alfresco.repo.content.AbstractContentStore;
|
||||
import org.alfresco.repo.content.ContentStore;
|
||||
import org.alfresco.repo.content.MimetypeMap;
|
||||
import org.alfresco.repo.transaction.TransactionalDao;
|
||||
import org.alfresco.service.cmr.repository.ContentReader;
|
||||
import org.alfresco.service.cmr.repository.ContentWriter;
|
||||
import org.alfresco.service.cmr.repository.datatype.Duration;
|
||||
import org.alfresco.util.EqualsHelper;
|
||||
import org.alfresco.util.GUID;
|
||||
import org.hibernate.Session;
|
||||
import org.springframework.orm.hibernate3.HibernateCallback;
|
||||
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
|
||||
|
||||
/**
|
||||
* Assumes mimetype and encoding sent to the content store (we are not saving this anywhere)
|
||||
*
|
||||
* @author Andy Hind
|
||||
*/
|
||||
public class HibernateAuditDAO extends HibernateDaoSupport implements AuditDAO, TransactionalDao
|
||||
{
|
||||
public static final String QUERY_LAST_AUDIT_DATE = "audit.GetLatestAuditDate";
|
||||
|
||||
public static final String QUERY_LAST_AUDIT_CONFIG = "audit.GetLatestAuditConfig";
|
||||
|
||||
public static final String QUERY_AUDIT_APP_SOURCE = "audit.GetAuditSourceByApplication";
|
||||
|
||||
public static final String QUERY_AUDIT_METHOD_SOURCE = "audit.GetAuditSourceByApplicationServiceMethod";
|
||||
|
||||
public static final String QUERY_AUDIT_APP_SOURCE_APP = "application";
|
||||
|
||||
public static final String QUERY_AUDIT_APP_SOURCE_SER = "service";
|
||||
|
||||
public static final String QUERY_AUDIT_APP_SOURCE_MET = "method";
|
||||
|
||||
/** a uuid identifying this unique instance */
|
||||
private String uuid;
|
||||
|
||||
private ContentStore contentStore;
|
||||
|
||||
private ThreadLocal<AuditConfiguration> auditConfiguration = new ThreadLocal<AuditConfiguration>();
|
||||
|
||||
private ThreadLocal<Long> auditConfigImplId = new ThreadLocal<Long>();
|
||||
|
||||
private ThreadLocal<Long> auditDateImplId = new ThreadLocal<Long>();
|
||||
|
||||
private ThreadLocal<HashMap<SourceKey, Long>> sourceIds = new ThreadLocal<HashMap<SourceKey, Long>>();
|
||||
|
||||
public HibernateAuditDAO()
|
||||
{
|
||||
super();
|
||||
this.uuid = GUID.generate();
|
||||
}
|
||||
|
||||
public ContentStore getContentStore()
|
||||
{
|
||||
return contentStore;
|
||||
}
|
||||
|
||||
public void setContentStore(ContentStore contentStore)
|
||||
{
|
||||
this.contentStore = contentStore;
|
||||
}
|
||||
|
||||
public void audit(AuditInfo auditInfo)
|
||||
{
|
||||
// Find/Build the configuraton entry
|
||||
AuditConfigImpl auditConfig = getAuditConfig(auditInfo);
|
||||
|
||||
// Find/Build any dates
|
||||
AuditDateImpl auditDate = getAuditDate(auditInfo);
|
||||
|
||||
// Find/Build the source
|
||||
AuditSourceImpl auditSource = getAuditSource(auditInfo);
|
||||
|
||||
// Build the new audit fact information
|
||||
AuditFactImpl auditFact = new AuditFactImpl();
|
||||
auditFact.setAuditConfig(auditConfig);
|
||||
auditFact.setAuditDate(auditDate);
|
||||
auditFact.setAuditSource(auditSource);
|
||||
|
||||
// Properties
|
||||
|
||||
Serializable[] args = auditInfo.getMethodArguments();
|
||||
|
||||
if (args != null)
|
||||
{
|
||||
switch (args.length)
|
||||
{
|
||||
default:
|
||||
case 5:
|
||||
auditFact.setArg5(getStringOrNull(args[4]));
|
||||
case 4:
|
||||
auditFact.setArg4(getStringOrNull(args[3]));
|
||||
case 3:
|
||||
auditFact.setArg3(getStringOrNull(args[2]));
|
||||
case 2:
|
||||
auditFact.setArg2(getStringOrNull(args[1]));
|
||||
case 1:
|
||||
auditFact.setArg1(getStringOrNull(args[0]));
|
||||
case 0:
|
||||
}
|
||||
}
|
||||
|
||||
auditFact.setClientInetAddress(auditInfo.getClientAddress() == null ? null : auditInfo.getClientAddress()
|
||||
.toString());
|
||||
auditFact.setDate(auditInfo.getDate());
|
||||
auditFact.setException(auditInfo.getThrowable() == null ? null : auditInfo.getThrowable().getMessage());
|
||||
auditFact.setFail(auditInfo.isFail());
|
||||
auditFact.setFiltered(auditInfo.isFiltered());
|
||||
auditFact.setHostInetAddress(auditInfo.getHostAddress() == null ? null : auditInfo.getHostAddress().toString());
|
||||
auditFact.setMessage(auditInfo.getMessage());
|
||||
auditFact.setNodeUUID(auditInfo.getKeyGUID());
|
||||
auditFact.setPath(auditInfo.getPath());
|
||||
auditFact.setReturnValue(auditInfo.getReturnObject() == null ? null : auditInfo.getReturnObject().toString());
|
||||
// auditFact.setSerialisedURL()
|
||||
auditFact.setSessionId(auditInfo.getSessionId());
|
||||
if (auditInfo.getKeyStore() != null)
|
||||
{
|
||||
auditFact.setStoreId(auditInfo.getKeyStore().getIdentifier());
|
||||
auditFact.setStoreProtocol(auditInfo.getKeyStore().getProtocol());
|
||||
}
|
||||
auditFact.setTransactionId(auditInfo.getTxId());
|
||||
auditFact.setUserId(auditInfo.getUserIdentifier());
|
||||
|
||||
// Save
|
||||
getSession().save(auditFact);
|
||||
|
||||
}
|
||||
|
||||
private String getStringOrNull(Object o)
|
||||
{
|
||||
if (o == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
return o.toString();
|
||||
}
|
||||
}
|
||||
|
||||
private AuditSourceImpl getAuditSource(AuditInfo auditInfo)
|
||||
{
|
||||
AuditSourceImpl auditSourceImpl;
|
||||
|
||||
SourceKey sourceKey = new SourceKey(auditInfo.getAuditApplication(), auditInfo.getAuditService(), auditInfo.getAuditMethod());
|
||||
if(sourceIds.get() == null)
|
||||
{
|
||||
sourceIds.set(new HashMap<SourceKey, Long>());
|
||||
}
|
||||
Long id = sourceIds.get().get(sourceKey);
|
||||
if(id != null)
|
||||
{
|
||||
auditSourceImpl = (AuditSourceImpl) getSession().get(AuditSourceImpl.class, id.longValue());
|
||||
if(auditSourceImpl != null)
|
||||
{
|
||||
return auditSourceImpl;
|
||||
}
|
||||
}
|
||||
|
||||
if ((auditInfo.getAuditService() != null)
|
||||
&& (auditInfo.getAuditService().length() > 0) && (auditInfo.getAuditMethod() != null)
|
||||
&& (auditInfo.getAuditMethod().length() > 0))
|
||||
{
|
||||
auditSourceImpl = AuditSourceImpl.getApplicationSource(getSession(), auditInfo.getAuditApplication(),
|
||||
auditInfo.getAuditService(), auditInfo.getAuditMethod());
|
||||
if (auditSourceImpl == null)
|
||||
{
|
||||
auditSourceImpl = new AuditSourceImpl();
|
||||
auditSourceImpl.setApplication(auditInfo.getAuditApplication());
|
||||
auditSourceImpl.setService(auditInfo.getAuditService());
|
||||
auditSourceImpl.setMethod(auditInfo.getAuditMethod());
|
||||
getSession().save(auditSourceImpl);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
auditSourceImpl = AuditSourceImpl.getApplicationSource(getSession(), auditInfo.getAuditApplication());
|
||||
if (auditSourceImpl == null)
|
||||
{
|
||||
auditSourceImpl = new AuditSourceImpl();
|
||||
auditSourceImpl.setApplication(auditInfo.getAuditApplication());
|
||||
getSession().save(auditSourceImpl);
|
||||
}
|
||||
}
|
||||
sourceIds.get().put(sourceKey, Long.valueOf(auditSourceImpl.getId()));
|
||||
return auditSourceImpl;
|
||||
}
|
||||
|
||||
private AuditDateImpl getAuditDate(AuditInfo auditInfo)
|
||||
{
|
||||
Calendar cal = GregorianCalendar.getInstance();
|
||||
cal.setTime(auditInfo.getDate());
|
||||
cal.set(Calendar.MILLISECOND, 0);
|
||||
cal.set(Calendar.SECOND, 0);
|
||||
cal.set(Calendar.MINUTE, 0);
|
||||
cal.set(Calendar.HOUR_OF_DAY, 0);
|
||||
Date required = cal.getTime();
|
||||
|
||||
AuditDateImpl auditDate;
|
||||
if (auditDateImplId.get() == null)
|
||||
{
|
||||
auditDate = AuditDateImpl.getLatestDate(getSession());
|
||||
if (auditDate == null)
|
||||
{
|
||||
// The first entry ever so we just make it
|
||||
auditDate = new AuditDateImpl(auditInfo.getDate());
|
||||
getSession().save(auditDate);
|
||||
}
|
||||
auditDateImplId.set(Long.valueOf(auditDate.getId()));
|
||||
}
|
||||
else
|
||||
{
|
||||
auditDate = (AuditDateImpl) getSession().get(AuditDateImpl.class, auditDateImplId.get().longValue());
|
||||
if ((auditDate == null) || (!required.equals(auditDate.getDate())))
|
||||
{
|
||||
auditDate = AuditDateImpl.getLatestDate(getSession());
|
||||
if (auditDate == null)
|
||||
{
|
||||
// The first entry ever so we just make it
|
||||
auditDate = new AuditDateImpl(auditInfo.getDate());
|
||||
getSession().save(auditDate);
|
||||
}
|
||||
auditDateImplId.set(Long.valueOf(auditDate.getId()));
|
||||
}
|
||||
}
|
||||
while (!required.equals(auditDate.getDate()))
|
||||
{
|
||||
Date nextDate = Duration.add(auditDate.getDate(), new Duration("P1D"));
|
||||
auditDate = new AuditDateImpl(nextDate);
|
||||
getSession().save(auditDate);
|
||||
auditDateImplId.set(Long.valueOf(auditDate.getId()));
|
||||
}
|
||||
return auditDate;
|
||||
}
|
||||
|
||||
private AuditConfigImpl getAuditConfig(AuditInfo auditInfo)
|
||||
{
|
||||
AuditConfigImpl auditConfig;
|
||||
if ((auditConfiguration.get() == null) || (auditConfiguration.get() != auditInfo.getAuditConfiguration()))
|
||||
{
|
||||
auditConfig = AuditConfigImpl.getLatestConfig(getSession());
|
||||
if (auditConfig == null)
|
||||
{
|
||||
auditConfig = createNewAuditConfigImpl(auditInfo);
|
||||
}
|
||||
else
|
||||
{
|
||||
InputStream current = new BufferedInputStream(auditInfo.getAuditConfiguration().getInputStream());
|
||||
ContentReader reader = contentStore.getReader(auditConfig.getConfigURL());
|
||||
reader.setMimetype(MimetypeMap.MIMETYPE_XML);
|
||||
reader.setEncoding("UTF-8");
|
||||
InputStream last = new BufferedInputStream(reader.getContentInputStream());
|
||||
int currentValue = -2;
|
||||
int lastValue = -2;
|
||||
try
|
||||
{
|
||||
while ((currentValue != -1) && (lastValue != -1) && (currentValue == lastValue))
|
||||
{
|
||||
currentValue = current.read();
|
||||
lastValue = last.read();
|
||||
|
||||
}
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
throw new AlfrescoRuntimeException(
|
||||
"Failed to read and validate current audit configuration against the last", e);
|
||||
}
|
||||
if (currentValue != lastValue)
|
||||
{
|
||||
// Files are different - require a new entry
|
||||
auditConfig = createNewAuditConfigImpl(auditInfo);
|
||||
}
|
||||
else
|
||||
{
|
||||
// No change
|
||||
}
|
||||
}
|
||||
auditConfigImplId.set(Long.valueOf(auditConfig.getId()));
|
||||
auditConfiguration.set(auditInfo.getAuditConfiguration());
|
||||
}
|
||||
else
|
||||
{
|
||||
auditConfig = (AuditConfigImpl) getSession()
|
||||
.get(AuditConfigImpl.class, auditConfigImplId.get().longValue());
|
||||
if (auditConfig == null)
|
||||
{
|
||||
auditConfig = createNewAuditConfigImpl(auditInfo);
|
||||
}
|
||||
}
|
||||
return auditConfig;
|
||||
}
|
||||
|
||||
private AuditConfigImpl createNewAuditConfigImpl(AuditInfo auditInfo)
|
||||
{
|
||||
AuditConfigImpl auditConfig = new AuditConfigImpl();
|
||||
InputStream is = new BufferedInputStream(auditInfo.getAuditConfiguration().getInputStream());
|
||||
String url = AbstractContentStore.createNewUrl();
|
||||
ContentWriter writer = contentStore.getWriter(null, url);
|
||||
writer.setMimetype(MimetypeMap.MIMETYPE_XML);
|
||||
writer.setEncoding("UTF-8");
|
||||
writer.putContent(is);
|
||||
auditConfig.setConfigURL(url);
|
||||
getSession().save(auditConfig);
|
||||
return auditConfig;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks equality by type and uuid
|
||||
*/
|
||||
public boolean equals(Object obj)
|
||||
{
|
||||
if (obj == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else if (!(obj instanceof HibernateAuditDAO))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
HibernateAuditDAO that = (HibernateAuditDAO) obj;
|
||||
return this.uuid.equals(that.uuid);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see #uuid
|
||||
*/
|
||||
public int hashCode()
|
||||
{
|
||||
return uuid.hashCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Does this <tt>Session</tt> contain any changes which must be synchronized with the store?
|
||||
*
|
||||
* @return true => changes are pending
|
||||
*/
|
||||
public boolean isDirty()
|
||||
{
|
||||
// create a callback for the task
|
||||
HibernateCallback callback = new HibernateCallback()
|
||||
{
|
||||
public Object doInHibernate(Session session)
|
||||
{
|
||||
return session.isDirty();
|
||||
}
|
||||
};
|
||||
// execute the callback
|
||||
return ((Boolean) getHibernateTemplate().execute(callback)).booleanValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Just flushes the session
|
||||
*/
|
||||
public void flush()
|
||||
{
|
||||
getSession().flush();
|
||||
}
|
||||
|
||||
static class SourceKey
|
||||
{
|
||||
String application;
|
||||
|
||||
String service;
|
||||
|
||||
String method;
|
||||
|
||||
SourceKey(String application, String service, String method)
|
||||
{
|
||||
this.application = application;
|
||||
this.service = service;
|
||||
this.method = method;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o)
|
||||
{
|
||||
if (this == o)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (!(this instanceof SourceKey))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
SourceKey other = (SourceKey) o;
|
||||
return EqualsHelper.nullSafeEquals(this.application, other.application)
|
||||
&& EqualsHelper.nullSafeEquals(this.service, other.service)
|
||||
&& EqualsHelper.nullSafeEquals(this.method, other.method);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode()
|
||||
{
|
||||
int hash = application.hashCode();
|
||||
if (service != null)
|
||||
{
|
||||
hash = (hash * 37) + service.hashCode();
|
||||
}
|
||||
if (method != null)
|
||||
{
|
||||
hash = (hash * 37) + method.hashCode();
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user