Skip to content

Commit

Permalink
Fix #142 Add onException method on WaveType to manage custom exception
Browse files Browse the repository at this point in the history
handling
  • Loading branch information
sbordes committed Feb 25, 2015
1 parent 66ea721 commit 767d4b4
Show file tree
Hide file tree
Showing 13 changed files with 229 additions and 26 deletions.
Expand Up @@ -18,8 +18,10 @@
package org.jrebirth.af.api.wave.contract;

import java.util.List;
import java.util.Map;

import org.jrebirth.af.api.command.Command;
import org.jrebirth.af.api.wave.Wave;

/**
*
Expand Down Expand Up @@ -148,4 +150,31 @@ public interface WaveType {
*/
List<WaveItem<?>> parameters();

/**
* Return the map of wave exception handler.
*
* @return the waveExceptionHandler map
*/
Map<Class<? extends Throwable>, Wave> waveExceptionHanler();

/**
* Define the Command to call in order to handle given exception types.
*
* @param exceptionCommandClass the command class to use
* @param exceptionTypes the types of exception to manage (none = all)
*
* @return the wave type to chain method call
*/
WaveType onException(Class<? extends Command> exceptionCommandClass, Class<? extends Throwable>... exceptionTypes);

/**
* Define the {@link WaveType} to send in order to manage given exception types.
*
* @param exceptionWaveType the WaveType to send to handle the exception
* @param exceptionTypes the types of exception to manage (none = all)
*
* @return the wave type to chain method call
*/
WaveType onException(WaveType exceptionWaveType, Class<? extends Throwable>... exceptionTypes);

}
Expand Up @@ -200,7 +200,7 @@ public final void init() throws CoreException {
notifyPreloader(new ProgressNotification(1000));
notifyPreloader(new ProgressNotification(1.0));

} catch (final Exception e) {
} catch (final Exception e) { // NOSONAR Catch all exception during init phase
LOGGER.error(ApplicationMessages.INIT_ERROR, e, this.getClass().getSimpleName());
throw new CoreException(e);
}
Expand Down Expand Up @@ -320,7 +320,7 @@ public final void stop() throws CoreException {

LOGGER.log(STOPPED_SUCCESSFULLY, this.getClass().getSimpleName());

} catch (final Exception e) {
} catch (final Exception e) { // NOSONAR Catch all exception during stopping phase
LOGGER.error(STOP_ERROR, e, this.getClass().getSimpleName(), e);
throw new CoreException(e);
}
Expand Down Expand Up @@ -533,7 +533,7 @@ private String getShortClassName() {
* @param scene the scene to check
*/
private void manageDefaultStyleSheet(final Scene scene) {
if (scene.getStylesheets().size() < 1) {
if (scene.getStylesheets().isEmpty()) {
// No style sheet has been added to the scene
LOGGER.log(NO_CSS_DEFINED);
addCSS(scene, JRebirthStyles.DEFAULT);
Expand Down
Expand Up @@ -160,16 +160,11 @@ public void setEventData(final String eventData) {
@Override
public String toString() {
final StringBuilder sb = new StringBuilder();
sb.append(getSequence());
sb.append(ClassUtility.SEPARATOR);
sb.append(getEventType());
sb.append(ClassUtility.SEPARATOR);
sb.append(getSource());
sb.append(ClassUtility.SEPARATOR);
sb.append(getTarget());
sb.append(ClassUtility.SEPARATOR);
sb.append(getEventData());
sb.append(ClassUtility.SEPARATOR);
sb.append(getSequence()).append(ClassUtility.SEPARATOR)
.append(getEventType()).append(ClassUtility.SEPARATOR)
.append(getSource()).append(ClassUtility.SEPARATOR)
.append(getTarget()).append(ClassUtility.SEPARATOR)
.append(getEventData()).append(ClassUtility.SEPARATOR);
return sb.toString();
}

Expand All @@ -181,7 +176,7 @@ public String toString() {
private void parseString(final String eventSerialized) {
final StringTokenizer st = new StringTokenizer(eventSerialized, ClassUtility.SEPARATOR);
if (st.countTokens() >= 5) {
setSequence(Integer.valueOf(st.nextToken()));
setSequence(Integer.parseInt(st.nextToken()));
setEventType(JRebirthEventType.valueOf(st.nextToken()));
setSource(st.nextToken());
setTarget(st.nextToken());
Expand Down
Expand Up @@ -64,6 +64,12 @@ public interface ServiceMessages extends MessageContainer {
/** "{0} - thrown by the Service Task {1}" . */
MessageItem SERVICE_TASK_EXCEPTION = create(new LogMessage("jrebirth.service.serviceTaskException", JRLevel.Warn, JRebirthMarkers.SERVICE));

/** "{0} - thrown by the Service Task {1} and handled with a Wave" . */
MessageItem SERVICE_TASK_HANDLE_EXCEPTION = create(new LogMessage("jrebirth.service.serviceTaskHandleException", JRLevel.Warn, JRebirthMarkers.SERVICE));

/** "{0} - thrown by the Service Task {1} and not managed" . */
MessageItem SERVICE_TASK_NOT_MANAGED_EXCEPTION = create(new LogMessage("jrebirth.service.serviceTaskNotManagedException", JRLevel.Warn, JRebirthMarkers.SERVICE));

/** ServiceUtility. */

/** "Impossible to count lines for file: {0}" . */
Expand Down
Expand Up @@ -171,10 +171,39 @@ protected T call() throws CoreException {
} catch (final ServiceException se) {
LOGGER.log(SERVICE_TASK_EXCEPTION, se, se.getExplanation(), getServiceHandlerName());
this.wave.status(Status.Failed);
} catch (final Exception e) { // NOSONAR, catch all to try to do something smart !

handleException(e);
}
return res;
}

/**
* Handle all exception occurred while doing the task.TODO To complete.
*
* @param e the exception to handle
*/
private void handleException(final Exception e) {
this.wave.status(Status.Failed);

// Get the exact exception type
final Wave exceptionHandlerWave = this.wave.waveType().waveExceptionHanler().get(e.getClass());

if (exceptionHandlerWave != null) {
// Fill the wave with useful data
exceptionHandlerWave.fromClass(this.service.getClass())
.add(JRebirthItems.exceptionItem, e)
.relatedWave(this.wave);

LOGGER.log(SERVICE_TASK_HANDLE_EXCEPTION, e, e.getClass().getSimpleName(), getServiceHandlerName());

// Send the exception wave to interested components
this.service.sendWave(exceptionHandlerWave);
} else {
LOGGER.log(SERVICE_TASK_NOT_MANAGED_EXCEPTION, e, e.getClass().getSimpleName(), getServiceHandlerName());
}
}

/**
* Send a wave that will carry the service result.
*
Expand Down
Expand Up @@ -9,25 +9,46 @@

import org.jrebirth.af.api.concurrent.RunnablePriority;

/**
* The class <strong>MultiMap</strong>.
*
* @author Sébastien Bordes
*
* @param <K> The object used as a Key
* @param <V> The object stored as a value
*/
public class MultiMap<K, V> implements Map<K, List<V>> {

/** The internal map that store multiple data per key. */
private final Map<K, List<V>> map = new HashMap<>();

/**
* {@inheritDoc}
*/
@Override
public int size() {
return this.map.size();
}

/**
* {@inheritDoc}
*/
@Override
public boolean isEmpty() {
return this.map.isEmpty();
}

/**
* {@inheritDoc}
*/
@Override
public boolean containsKey(final Object key) {
return this.map.containsKey(key);
}

/**
* {@inheritDoc}
*/
@Override
public boolean containsValue(final Object value) {
boolean res = false;
Expand All @@ -40,6 +61,9 @@ public boolean containsValue(final Object value) {
return res;
}

/**
* {@inheritDoc}
*/
@Override
public List<V> get(final Object key) {
return this.map.get(key);
Expand All @@ -52,49 +76,77 @@ public boolean add(final K key, final V value) {
return this.map.get(key).add(value);
}

/**
* {@inheritDoc}
*/
@Override
public List<V> put(final K key, final List<V> value) {
return this.map.put(key, value);
}

/**
* {@inheritDoc}
*/
@Override
public List<V> remove(final Object key) {
return this.map.remove(key);
}

/**
* {@inheritDoc}
*/
@Override
public void clear() {
this.map.clear();
}

/**
* {@inheritDoc}
*/
@Override
public Set<K> keySet() {
return this.map.keySet();
}

/**
* {@inheritDoc}
*/
@Override
public Collection<List<V>> values() {
return this.map.values();
}

/**
* {@inheritDoc}
*/
@Override
public Set<java.util.Map.Entry<K, List<V>>> entrySet() {
return this.map.entrySet();
}

/**
* {@inheritDoc}
*/
@Override
public void putAll(final Map<? extends K, ? extends List<V>> m) {
this.map.putAll(m);
}

public class Entry<V> {
/**
* The class <strong>Entry</strong>.
*
* @author Sébastien Bordes
*
* @param <E> the type of the value stored
*/
public class Entry<E> {

private final String id;
private final String description;
private final RunnablePriority priority;
private final V value;
private final E value;

public Entry(final String id, final String description, final RunnablePriority priority, final V value) {
public Entry(final String id, final String description, final RunnablePriority priority, final E value) {
super();
this.id = id;
this.description = description;
Expand Down Expand Up @@ -126,7 +178,7 @@ public RunnablePriority getPriority() {
/**
* @return the value
*/
public V getValue() {
public E getValue() {
return this.value;
}

Expand Down
@@ -1,3 +1,20 @@
/**
* Get more info at : www.jrebirth.org .
* Copyright JRebirth.org © 2011-2015
* Contact : sebastien.bordes@jrebirth.org
*
* Licensed 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.jrebirth.af.core.wave;

import org.jrebirth.af.api.command.Command;
Expand All @@ -7,33 +24,58 @@
import org.jrebirth.af.api.wave.contract.WaveItem;
import org.jrebirth.af.api.wave.contract.WaveType;

/**
* The Interface Builders used as a convenient wrapper to build a large variety of JRebirth Internal objects.
*/
public interface Builders {

/**
* Build a fresh Wave type.
*
* @return the wave type
*/
static WaveType waveType() {
return new WaveTypeBase();
}

static WaveType waveType(final String action/* , final WaveItem<?>... waveItems */) {
return waveType().action(action/* , waveItems */);
/**
* Build a fresh Wave type with action name.
*
* @param action the action
* @return the wave type
*/
static WaveType waveType(final String action) {
return waveType().action(action);
}

/**
* Build a fresh Wave.
*
* @return the wave
*/
static Wave wave() {
return new WaveBase();
}

/**
* Build a fresh Wave use to call the given command.
*
* @param commandClass the command class
*
* @return the wave
*/
static Wave callCommand(final Class<? extends Command> commandClass) {
return wave().waveGroup(WaveGroup.CALL_COMMAND).componentClass(commandClass);
}

/**
* Build a wave data.
*
* @param <T> the type of the object wrapped by this WaveData
* @param waveItem the wave item used as the key into the wave
* @param value the data hold by he wave data wrapper
*
*
* @return a new fresh wave Data object
*
* @param <T> the type of the object wrapped by this WaveData
*/
static <T extends Object> WaveData<T> waveData(final WaveItem<T> waveItem, final T value) {
return new WaveDataBase<>(waveItem, value);
Expand Down
Expand Up @@ -28,6 +28,10 @@ public interface JRebirthItems {
WaveItem<Void> voidItem = new WaveItemBase<Void>(false) {
};

/** The exception wave item (not a parameter). */
WaveItem<Throwable> exceptionItem = new WaveItemBase<Throwable>(false) {
};

/** The class wave item. */
WaveItem<Class<?>> classItem = new WaveItemBase<Class<?>>() {
};
Expand Down

0 comments on commit 767d4b4

Please sign in to comment.