1 /*
2  * aTunes
3  * Copyright (C) Alex Aranda, Sylvain Gaudard and contributors
4  *
5  * See http://www.atunes.org/wiki/index.php?title=Contributing for information about contributors
6  *
7  * http://www.atunes.org
8  * http://sourceforge.net/projects/atunes
9  *
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public License
12  * as published by the Free Software Foundation; either version 2
13  * of the License, or (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  */
20 
21 package net.sourceforge.atunes.kernel.actions;
22 
23 import java.awt.event.ActionEvent;
24 import java.lang.reflect.ParameterizedType;
25 import java.util.ArrayList;
26 import java.util.List;
27 
28 import javax.swing.Icon;
29 
30 import net.sourceforge.atunes.model.IAudioObject;
31 import net.sourceforge.atunes.model.IAudioObjectsSource;
32 import net.sourceforge.atunes.utils.CollectionUtils;
33 import net.sourceforge.atunes.utils.Logger;
34 
35 /**
36  * An action called after selecting audio objects which are parameters of action
37  *
38  * @author alex
39  *
40  * @param <T>
41  */
42 
43 public abstract class AbstractActionOverSelectedObjects<T extends IAudioObject>
44 		extends CustomAbstractAction {
45 
46 	private static final long serialVersionUID = 1673432955671008277L;
47 
48 	private IAudioObjectsSource audioObjectsSource;
49 
50 	private final Class<?> clazz;
51 
52 	/**
53 	 * @param name
54 	 */
AbstractActionOverSelectedObjects(String name)55 	public AbstractActionOverSelectedObjects(String name) {
56 		super(name);
57 		clazz = (Class<?>) ((ParameterizedType) getClass()
58 				.getGenericSuperclass()).getActualTypeArguments()[0];
59 	}
60 
61 	/**
62 	 * @param name
63 	 * @param icon
64 	 */
AbstractActionOverSelectedObjects(String name, Icon icon)65 	public AbstractActionOverSelectedObjects(String name, Icon icon) {
66 		super(name, icon);
67 		clazz = (Class<?>) ((ParameterizedType) getClass()
68 				.getGenericSuperclass()).getActualTypeArguments()[0];
69 	}
70 
71 	/**
72 	 * Returns if preprocess is needed
73 	 *
74 	 * Default implementation does not need preprocess
75 	 *
76 	 * @return
77 	 */
isPreprocessNeeded()78 	protected boolean isPreprocessNeeded() {
79 		return false;
80 	}
81 
82 	/**
83 	 * Given an audio object performs a pre-process returning audio object to
84 	 * include in list or null if given audio object must be excluded from list
85 	 *
86 	 * Default implementation returns the same object
87 	 *
88 	 * @param audioObject
89 	 * @return
90 	 */
preprocessObject(T audioObject)91 	protected T preprocessObject(T audioObject) {
92 		return audioObject;
93 	}
94 
95 	/**
96 	 * @param audioObjectsSource
97 	 */
setAudioObjectsSource( IAudioObjectsSource audioObjectsSource)98 	public final void setAudioObjectsSource(
99 			IAudioObjectsSource audioObjectsSource) {
100 		this.audioObjectsSource = audioObjectsSource;
101 	}
102 
executeAction(List<T> objects)103 	protected abstract void executeAction(List<T> objects);
104 
105 	@Override
executeAction()106 	protected final void executeAction() {
107 		// Use executionAction(List<T> objects)
108 	}
109 
110 	@SuppressWarnings("unchecked")
111 	@Override
actionPerformed(ActionEvent e)112 	public final void actionPerformed(ActionEvent e) {
113 		Logger.debug("Executing action: ", this.getClass().getName());
114 
115 		if (this.audioObjectsSource == null) {
116 			return;
117 		}
118 
119 		List<IAudioObject> audioObjects = this.audioObjectsSource
120 				.getSelectedAudioObjects();
121 
122 		if (audioObjects == null || audioObjects.isEmpty()) {
123 			return;
124 		}
125 
126 		List<T> selectedObjects = new ArrayList<T>();
127 
128 		for (IAudioObject ao : audioObjects) {
129 			if (clazz.isAssignableFrom(ao.getClass())) {
130 				if (isPreprocessNeeded()) {
131 					T processedAudioObject = preprocessObject((T) ao);
132 					if (processedAudioObject != null) {
133 						selectedObjects.add(processedAudioObject);
134 					}
135 				} else {
136 					selectedObjects.add((T) ao);
137 				}
138 			}
139 		}
140 
141 		// Call to perform action if some object is selected and valid
142 		if (!CollectionUtils.isEmpty(selectedObjects)) {
143 			executeAction(selectedObjects);
144 		}
145 	}
146 
147 	@Override
isEnabledForPlayListSelection( List<IAudioObject> selection)148 	public final boolean isEnabledForPlayListSelection(
149 			List<IAudioObject> selection) {
150 		if (selection.isEmpty()) {
151 			return false;
152 		}
153 
154 		for (IAudioObject ao : selection) {
155 			if (!clazz.isAssignableFrom(ao.getClass())) {
156 				return false;
157 			}
158 		}
159 		return true;
160 	}
161 }
162