Search in sources :

Example 1 with ResourceChange

use of org.apache.sling.api.resource.observation.ResourceChange in project sling by apache.

the class JcrResourceListener method onEvent.

/**
     * @see javax.jcr.observation.EventListener#onEvent(javax.jcr.observation.EventIterator)
     */
@Override
public void onEvent(final EventIterator events) {
    final Map<String, ResourceChange> addedEvents = new HashMap<String, ResourceChange>();
    final Map<String, ResourceChange> changedEvents = new HashMap<String, ResourceChange>();
    final Map<String, ResourceChange> removedEvents = new HashMap<String, ResourceChange>();
    while (events.hasNext()) {
        final Event event = events.nextEvent();
        final String identifier;
        final String path;
        try {
            identifier = event.getIdentifier();
            path = event.getPath();
        } catch (final RepositoryException e) {
            // there is nothing we can do about it anyway
            continue;
        }
        final String eventPath = (identifier != null && identifier.startsWith("/") ? identifier : path);
        final int type = event.getType();
        if (type == PROPERTY_ADDED && path.endsWith("/jcr:primaryType")) {
            final int lastSlash = path.lastIndexOf('/');
            final String rsrcPath = path.substring(0, lastSlash);
            // add is stronger than update
            changedEvents.remove(rsrcPath);
            addedEvents.put(rsrcPath, createResourceChange(event, rsrcPath, ChangeType.ADDED));
        } else if (type == PROPERTY_ADDED || type == PROPERTY_REMOVED || type == PROPERTY_CHANGED) {
            final String rsrcPath;
            if (identifier == null || !identifier.startsWith("/")) {
                final int lastSlash = eventPath.lastIndexOf('/');
                rsrcPath = eventPath.substring(0, lastSlash);
            } else {
                rsrcPath = eventPath;
            }
            if (!addedEvents.containsKey(rsrcPath) && !removedEvents.containsKey(rsrcPath) && !changedEvents.containsKey(rsrcPath)) {
                changedEvents.put(rsrcPath, createResourceChange(event, rsrcPath, ChangeType.CHANGED));
            }
        } else if (type == NODE_ADDED) {
            // add is stronger than update
            changedEvents.remove(eventPath);
            addedEvents.put(eventPath, createResourceChange(event, eventPath, ChangeType.ADDED));
        } else if (type == NODE_REMOVED) {
            // remove is stronger than add and change
            addedEvents.remove(eventPath);
            changedEvents.remove(eventPath);
            removedEvents.put(eventPath, createResourceChange(event, eventPath, ChangeType.REMOVED));
        }
    }
    final List<ResourceChange> changes = new ArrayList<ResourceChange>();
    changes.addAll(addedEvents.values());
    changes.addAll(removedEvents.values());
    changes.addAll(changedEvents.values());
    this.baseConfig.getReporter().reportChanges(this.config, changes, false);
}
Also used : HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) Event(javax.jcr.observation.Event) JackrabbitEvent(org.apache.jackrabbit.api.observation.JackrabbitEvent) RepositoryException(javax.jcr.RepositoryException) ResourceChange(org.apache.sling.api.resource.observation.ResourceChange)

Example 2 with ResourceChange

use of org.apache.sling.api.resource.observation.ResourceChange in project sling by apache.

the class MapEntries method onChange.

// ---------- ResourceChangeListener interface
/**
     * Handles the change to any of the node properties relevant for vanity URL
     * mappings. The {@link #MapEntries(ResourceResolverFactoryImpl, BundleContext, EventAdmin)}
     * constructor makes sure the event listener is registered to only get
     * appropriate events.
     */
@Override
public void onChange(final List<ResourceChange> changes) {
    final AtomicBoolean resolverRefreshed = new AtomicBoolean(false);
    // the config needs to be reloaded only once
    final AtomicBoolean hasReloadedConfig = new AtomicBoolean(false);
    for (final ResourceChange rc : changes) {
        final String path = rc.getPath();
        log.debug("onChange, type={}, path={}", rc.getType(), path);
        // don't care for system area
        if (path.startsWith(JCR_SYSTEM_PREFIX)) {
            continue;
        }
        boolean changed = false;
        // removal of a resource is handled differently
        if (rc.getType() == ResourceChange.ChangeType.REMOVED) {
            final Boolean result = handleConfigurationUpdate(path, hasReloadedConfig, resolverRefreshed, true);
            if (result != null) {
                if (result) {
                    changed = true;
                } else {
                    changed |= removeResource(path, resolverRefreshed);
                }
            }
        //session.move() is handled differently see also SLING-3713 and
        } else if (rc.getType() == ResourceChange.ChangeType.ADDED) {
            final Boolean result = handleConfigurationUpdate(path, hasReloadedConfig, resolverRefreshed, false);
            if (result != null) {
                if (result) {
                    changed = true;
                } else {
                    changed |= addResource(path, resolverRefreshed);
                }
            }
        } else if (rc.getType() == ResourceChange.ChangeType.CHANGED) {
            final Boolean result = handleConfigurationUpdate(path, hasReloadedConfig, resolverRefreshed, false);
            if (result != null) {
                if (result) {
                    changed = true;
                } else {
                    changed |= updateResource(path, resolverRefreshed);
                }
            }
        }
        if (changed) {
            this.sendChangeEvent();
        }
    }
}
Also used : AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) ResourceChange(org.apache.sling.api.resource.observation.ResourceChange) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean)

Example 3 with ResourceChange

use of org.apache.sling.api.resource.observation.ResourceChange in project sling by apache.

the class BasicObservationReporter method filterChanges.

/**
     * Filter the change list based on the configuration
     * @param changes The list of changes
     * @param config The configuration
     * @return The filtered list.
     */
private List<ResourceChange> filterChanges(final Iterable<ResourceChange> changes, final ObserverConfiguration config) {
    final ResourceChangeListImpl filtered = new ResourceChangeListImpl(this.searchPath);
    for (final ResourceChange c : changes) {
        if (matches(c, config)) {
            filtered.add(c);
        }
    }
    filtered.lock();
    return filtered;
}
Also used : ResourceChange(org.apache.sling.api.resource.observation.ResourceChange)

Example 4 with ResourceChange

use of org.apache.sling.api.resource.observation.ResourceChange in project sling by apache.

the class MapEntriesTest method test_vanity_path_updates.

@Test
public void test_vanity_path_updates() throws Exception {
    Resource parent = mock(Resource.class, "parent");
    when(parent.getPath()).thenReturn("/foo/parent");
    when(parent.getName()).thenReturn("parent");
    when(parent.getValueMap()).thenReturn(new ValueMapDecorator(Collections.<String, Object>emptyMap()));
    when(resourceResolver.getResource(parent.getPath())).thenReturn(parent);
    Resource child = mock(Resource.class, "jcrcontent");
    when(child.getPath()).thenReturn("/foo/parent/jcr:content");
    when(child.getName()).thenReturn("jcr:content");
    when(child.getValueMap()).thenReturn(buildValueMap("sling:vanityPath", "/target/found"));
    when(child.getParent()).thenReturn(parent);
    when(parent.getChild(child.getName())).thenReturn(child);
    when(resourceResolver.getResource(child.getPath())).thenReturn(child);
    when(resourceResolver.findResources(anyString(), eq("sql"))).thenAnswer(new Answer<Iterator<Resource>>() {

        @Override
        public Iterator<Resource> answer(InvocationOnMock invocation) throws Throwable {
            return Collections.<Resource>emptySet().iterator();
        }
    });
    mapEntries.doInit();
    mapEntries.initializeVanityPaths();
    // map entries should have no alias atm
    assertTrue(mapEntries.getResolveMaps().isEmpty());
    // add parent
    mapEntries.onChange(Arrays.asList(new ResourceChange(ChangeType.ADDED, parent.getPath(), false)));
    assertTrue(mapEntries.getResolveMaps().isEmpty());
    // add child
    mapEntries.onChange(Arrays.asList(new ResourceChange(ChangeType.ADDED, child.getPath(), false)));
    // two entries for the vanity path
    List<MapEntry> entries = mapEntries.getResolveMaps();
    assertEquals(2, entries.size());
    for (MapEntry entry : entries) {
        assertTrue(entry.getPattern().contains("/target/found"));
    }
    // update parent - no change
    mapEntries.onChange(Arrays.asList(new ResourceChange(ChangeType.CHANGED, parent.getPath(), false)));
    entries = mapEntries.getResolveMaps();
    assertEquals(2, entries.size());
    for (MapEntry entry : entries) {
        assertTrue(entry.getPattern().contains("/target/found"));
    }
    // update child - no change
    mapEntries.onChange(Arrays.asList(new ResourceChange(ChangeType.CHANGED, child.getPath(), false)));
    entries = mapEntries.getResolveMaps();
    assertEquals(2, entries.size());
    for (MapEntry entry : entries) {
        assertTrue(entry.getPattern().contains("/target/found"));
    }
    // remove child - empty again
    when(resourceResolver.getResource(child.getPath())).thenReturn(null);
    when(parent.getChild(child.getName())).thenReturn(null);
    mapEntries.onChange(Arrays.asList(new ResourceChange(ChangeType.REMOVED, child.getPath(), false)));
    assertTrue(mapEntries.getResolveMaps().isEmpty());
    // remove parent - still empty
    when(resourceResolver.getResource(parent.getPath())).thenReturn(null);
    mapEntries.onChange(Arrays.asList(new ResourceChange(ChangeType.REMOVED, parent.getPath(), false)));
    assertTrue(mapEntries.getResolveMaps().isEmpty());
}
Also used : InvocationOnMock(org.mockito.invocation.InvocationOnMock) Resource(org.apache.sling.api.resource.Resource) ValueMapDecorator(org.apache.sling.api.wrappers.ValueMapDecorator) Iterator(java.util.Iterator) Matchers.anyString(org.mockito.Matchers.anyString) ResourceChange(org.apache.sling.api.resource.observation.ResourceChange) Test(org.junit.Test)

Example 5 with ResourceChange

use of org.apache.sling.api.resource.observation.ResourceChange in project sling by apache.

the class BasicObservationReporterTest method assertListener.

@SuppressWarnings("unchecked")
private static void assertListener(ResourceChangeListenerInfo info, String... paths) {
    Set<String> expectedPaths = ImmutableSet.copyOf(paths);
    ArgumentCaptor<List<ResourceChange>> argument = (ArgumentCaptor) ArgumentCaptor.forClass(List.class);
    if (paths.length == 0) {
        verifyNoMoreInteractions(info.getListener());
    } else {
        verify(info.getListener(), atLeastOnce()).onChange(argument.capture());
        Set<String> actualPaths = new HashSet<>();
        for (List<ResourceChange> changeList : argument.getAllValues()) {
            for (ResourceChange change : changeList) {
                actualPaths.add(change.getPath());
            }
        }
        assertEquals(expectedPaths, actualPaths);
    }
}
Also used : ArgumentCaptor(org.mockito.ArgumentCaptor) ArrayList(java.util.ArrayList) List(java.util.List) ImmutableList(com.google.common.collect.ImmutableList) ResourceChange(org.apache.sling.api.resource.observation.ResourceChange) HashSet(java.util.HashSet)

Aggregations

ResourceChange (org.apache.sling.api.resource.observation.ResourceChange)38 Test (org.junit.Test)20 File (java.io.File)17 HashSet (java.util.HashSet)4 ArrayList (java.util.ArrayList)3 Event (org.osgi.service.event.Event)2 ImmutableList (com.google.common.collect.ImmutableList)1 SoftReference (java.lang.ref.SoftReference)1 Dictionary (java.util.Dictionary)1 HashMap (java.util.HashMap)1 Hashtable (java.util.Hashtable)1 Iterator (java.util.Iterator)1 List (java.util.List)1 Map (java.util.Map)1 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)1 Node (javax.jcr.Node)1 RepositoryException (javax.jcr.RepositoryException)1 Session (javax.jcr.Session)1 Event (javax.jcr.observation.Event)1 JackrabbitEvent (org.apache.jackrabbit.api.observation.JackrabbitEvent)1