<commit_before>/*
 * Licensed to the Sakai Foundation (SF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The SF licenses this file
 * to you 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.sakaiproject.kernel.jcr.jackrabbit;

import com.google.inject.Inject;


import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.jackrabbit.core.observation.EventImpl;
import org.sakaiproject.kernel.api.jcr.EventRegistration;
import org.sakaiproject.kernel.api.jcr.JCRConstants;
import org.sakaiproject.kernel.api.jcr.JCRService;
import org.sakaiproject.kernel.api.locking.Lock;
import org.sakaiproject.kernel.api.locking.LockTimeoutException;
import org.sakaiproject.kernel.api.memory.CacheManagerService;
import org.sakaiproject.kernel.api.memory.CacheScope;
import org.sakaiproject.kernel.util.PathUtils;

import java.util.GregorianCalendar;

import javax.jcr.LoginException;
import javax.jcr.Node;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.observation.Event;
import javax.jcr.observation.EventIterator;
import javax.jcr.observation.EventListener;
import javax.jcr.observation.ObservationManager;

/**
 * 
 */
public class NodeUpdateListener implements EventListener, EventRegistration {

  private static final Log LOG = LogFactory.getLog(NodeUpdateListener.class);
  private JCRService jcrService;
  private CacheManagerService cacheManagerService;

  /**
   * @param listeners
   * @throws RepositoryException
   * 
   */
  @Inject
  public NodeUpdateListener(JCRService jcrService,
      CacheManagerService cacheManagerService)
      throws RepositoryException {
    this.jcrService = jcrService;
    this.cacheManagerService = cacheManagerService;
  }

  /**
   * {@inheritDoc}
   * 
   * @throws RepositoryException
   * 
   * @see org.sakaiproject.kernel.api.jcr.EventRegistration#register(javax.jcr.observation.ObservationManager)
   */
  public void register(ObservationManager observationManager) throws RepositoryException {
    observationManager.addEventListener(this, Event.PROPERTY_ADDED
        | Event.PROPERTY_CHANGED | Event.NODE_ADDED, "/", true, null, new String[] {
        JCRConstants.NT_FILE, JCRConstants.NT_FOLDER}, false);
    LOG.info("Registered " + this.getClass().getName());
  }

  /**
   * {@inheritDoc}
   * 
   * @see javax.jcr.observation.EventListener#onEvent(javax.jcr.observation.EventIterator)
   */
  public void onEvent(EventIterator events) {
    try {
      Session s = jcrService.loginSystem();

      for (; events.hasNext();) {

        EventImpl e = (EventImpl) events.nextEvent();
        if (e.isExternal()) {
          continue;
        }
        try {
          String nodePath = e.getPath();
          switch (e.getType()) {
          case Event.PROPERTY_ADDED:
          case Event.PROPERTY_CHANGED:
            nodePath = PathUtils.getParentReference(nodePath);
          }
          if (nodePath.endsWith(JCRConstants.JCR_CONTENT)) {
            nodePath = PathUtils.getParentReference(nodePath);
          }
          Session session = jcrService.getSession();
          Node n = (Node) session.getItem(nodePath);

          if (!n.hasProperty(JCRConstants.JCR_CREATEDBY)) {
            Lock lock = jcrService.lock(n);
            try {
              n.setProperty(JCRConstants.JCR_CREATEDBY, e.getUserID());
              LOG.info("Node created by " + e.getUserID());
              if (!n.hasProperty(JCRConstants.JCR_CREATED)) {
                GregorianCalendar now = new GregorianCalendar();
                n.setProperty(JCRConstants.JCR_CREATED, now);
              }
              n.save();
            } finally {
              lock.unlock();
            }
          } else {
            if (!n.hasProperty(JCRConstants.JCR_MODIFIEDBY)) {
              Lock lock = jcrService.lock(n);
              try {
                n.setProperty(JCRConstants.JCR_MODIFIEDBY, e.getUserID());
                LOG.info("Node modified by " + e.getUserID());
                n.save();
              } finally {
                lock.unlock();
              }

            } else {
              String userId = n.getProperty(JCRConstants.JCR_MODIFIEDBY).getString();
              if (!e.getUserID().equals(userId)) {
                Lock lock = jcrService.lock(n);
                try {
                  n.setProperty(JCRConstants.JCR_MODIFIEDBY, e.getUserID());
                  LOG.info("Node modified by " + e.getUserID() + " previously " + userId);
                  n.save();<commit_msg>The modified by property was being set as a result of the listener, overwriting the real value.<commit_after>/*
 * Licensed to the Sakai Foundation (SF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The SF licenses this file
 * to you 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.sakaiproject.kernel.jcr.jackrabbit;

import com.google.inject.Inject;


import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.jackrabbit.core.observation.EventImpl;
import org.sakaiproject.kernel.api.jcr.EventRegistration;
import org.sakaiproject.kernel.api.jcr.JCRConstants;
import org.sakaiproject.kernel.api.jcr.JCRService;
import org.sakaiproject.kernel.api.locking.Lock;
import org.sakaiproject.kernel.api.locking.LockTimeoutException;
import org.sakaiproject.kernel.api.memory.CacheManagerService;
import org.sakaiproject.kernel.api.memory.CacheScope;
import org.sakaiproject.kernel.util.PathUtils;

import java.util.GregorianCalendar;

import javax.jcr.LoginException;
import javax.jcr.Node;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.observation.Event;
import javax.jcr.observation.EventIterator;
import javax.jcr.observation.EventListener;
import javax.jcr.observation.ObservationManager;

/**
 * 
 */
public class NodeUpdateListener implements EventListener, EventRegistration {

  private static final Log LOG = LogFactory.getLog(NodeUpdateListener.class);
  private JCRService jcrService;
  private CacheManagerService cacheManagerService;

  /**
   * @param listeners
   * @throws RepositoryException
   * 
   */
  @Inject
  public NodeUpdateListener(JCRService jcrService,
      CacheManagerService cacheManagerService)
      throws RepositoryException {
    this.jcrService = jcrService;
    this.cacheManagerService = cacheManagerService;
  }

  /**
   * {@inheritDoc}
   * 
   * @throws RepositoryException
   * 
   * @see org.sakaiproject.kernel.api.jcr.EventRegistration#register(javax.jcr.observation.ObservationManager)
   */
  public void register(ObservationManager observationManager) throws RepositoryException {
    observationManager.addEventListener(this, Event.PROPERTY_ADDED
        | Event.PROPERTY_CHANGED | Event.NODE_ADDED, "/", true, null, new String[] {
        JCRConstants.NT_FILE, JCRConstants.NT_FOLDER}, false);
    LOG.info("Registered " + this.getClass().getName());
  }

  /**
   * {@inheritDoc}
   * 
   * @see javax.jcr.observation.EventListener#onEvent(javax.jcr.observation.EventIterator)
   */
  public void onEvent(EventIterator events) {
    try {
      Session s = jcrService.loginSystem();

      for (; events.hasNext();) {

        EventImpl e = (EventImpl) events.nextEvent();
        if (e.isExternal()) {
          continue;
        }
        try {
          String nodePath = e.getPath();
          switch (e.getType()) {
          case Event.PROPERTY_ADDED:
          case Event.PROPERTY_CHANGED:
            nodePath = PathUtils.getParentReference(nodePath);
          }
          if (nodePath.endsWith(JCRConstants.JCR_CONTENT)) {
            nodePath = PathUtils.getParentReference(nodePath);
          }
          Session session = jcrService.getSession();
          Node n = (Node) session.getItem(nodePath);

          if (!n.hasProperty(JCRConstants.JCR_CREATEDBY)) {
            Lock lock = jcrService.lock(n);
            try {
              n.setProperty(JCRConstants.JCR_CREATEDBY, e.getUserID());
              LOG.info("Node created by " + e.getUserID());
              if (!n.hasProperty(JCRConstants.JCR_CREATED)) {
                GregorianCalendar now = new GregorianCalendar();
                n.setProperty(JCRConstants.JCR_CREATED, now);
              }
              n.save();
            } finally {
              lock.unlock();
            }
          } else {
            if (!n.hasProperty(JCRConstants.JCR_MODIFIEDBY)) {
              Lock lock = jcrService.lock(n);
              try {
                n.setProperty(JCRConstants.JCR_MODIFIEDBY, e.getUserID());
                LOG.info("Node modified by " + e.getUserID());
                n.save();
              } finally {
                lock.unlock();
              }

            } else {
              String userId = n.getProperty(JCRConstants.JCR_MODIFIEDBY).getString();
              if (!s.getUserID().equals(e.getUserID()) && !e.getUserID().equals(userId) ) {
                Lock lock = jcrService.lock(n);
                try {
                  n.setProperty(JCRConstants.JCR_MODIFIEDBY, e.getUserID());
                  LOG.info("Node modified by " + e.getUserID() + " previously " + userId);
                  n.save();
{'fraction_non_alphanumeric': 0.10148681055155875, 'fraction_numerical': 0.0007673860911270983, 'mean_word_length': 2.791272727272727, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3319998', 'n_tokens_mistral': 2992, 'n_tokens_neox': 2933, 'n_words': 646}