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);
}
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();
}
}
}
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;
}
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());
}
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);
}
}
Aggregations