001/**
002 * Copyright 2014 Tampere University of Technology, Pori Department
003 * 
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 * 
008 *   http://www.apache.org/licenses/LICENSE-2.0
009 * 
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package service.tut.pori.contentstorage;
017
018import java.util.Collection;
019import java.util.EnumSet;
020import java.util.List;
021
022import service.tut.pori.contentanalysis.AbstractTaskDetails;
023import service.tut.pori.contentanalysis.AccessDetails;
024import service.tut.pori.contentanalysis.AnalysisBackend;
025import service.tut.pori.contentanalysis.AnalysisBackend.Capability;
026import service.tut.pori.contentanalysis.AsyncTask.TaskStatus;
027import service.tut.pori.contentanalysis.AsyncTask.TaskType;
028import service.tut.pori.contentanalysis.BackendStatus;
029import service.tut.pori.contentanalysis.BackendStatusList;
030import service.tut.pori.contentanalysis.CAContentCore.ServiceType;
031import core.tut.pori.users.UserIdentity;
032
033/**
034 * Abstract base class for ContentStorage handlers.
035 * 
036 * Note that sub-classing this class does not automatically add the storage handler as an usable handler, changes to the ContentStorageCore are also required.
037 */
038public abstract class ContentStorage {
039  private boolean _autoSchedule = true;
040  private ContentStorageListener _listener = null;
041  private BackendStatusList _backends = null;
042  
043  /**
044   * 
045   * @param autoSchedule
046   */
047  public ContentStorage(boolean autoSchedule){
048    _autoSchedule = autoSchedule;
049  }
050  
051  
052  
053  /**
054   * @return the backends
055   */
056  public BackendStatusList getBackends() {
057    return _backends;
058  }
059
060  /**
061   * 
062   * @param allOf
063   * @return backend statuses for all backends with all of the given capabilities
064   */
065  public BackendStatusList getBackends(EnumSet<Capability> allOf) {
066    if(_backends == null){
067      return null;
068    }
069    return BackendStatusList.getBackendStatusList(_backends.getBackendStatuses(allOf));
070  }
071
072  /**
073   * @param backends the backends to set
074   */
075  public void setBackends(BackendStatusList backends) {
076    if(BackendStatusList.isEmpty(backends)){
077      _backends = null;
078    }else{
079      _backends = backends;
080    }
081  }
082
083  /**
084   * 
085   * @param backends all backends will be added with status NOT_STARTED
086   */
087  public void setBackends(List<AnalysisBackend> backends){
088    if(backends == null || backends.isEmpty()){
089      _backends = null;
090      return;
091    }
092    if(_backends == null){
093      _backends = new BackendStatusList();
094    }
095    for(AnalysisBackend backend : backends){
096      _backends.setBackendStatus(new BackendStatus(backend, TaskStatus.NOT_STARTED));
097    }
098  }
099
100  /**
101   * Create new storage with autoschedule set to true
102   */
103  public ContentStorage() {
104    // nothing needed
105  }
106
107  /**
108   * @return the autoSchedule
109   */
110  public boolean isAutoSchedule() {
111    return _autoSchedule;
112  }
113  
114  /**
115   * @return the listener
116   */
117  public ContentStorageListener getContentStorageListener() {
118    return _listener;
119  }
120
121  /**
122   * @param listener the listener to set
123   */
124  public void setContentStorageListener(ContentStorageListener listener) {
125    _listener = listener;
126  }
127  
128  /**
129   * helper for notifying listener (if given) about a new photo task
130   * 
131   * @param details
132   * @throws IllegalArgumentException on invalid details
133   */
134  protected void notifyFeedbackTaskCreated(AbstractTaskDetails details) throws IllegalArgumentException{
135    if(details == null || details.getTaskType() != TaskType.FEEDBACK){
136      throw new IllegalArgumentException("Invalid task details.");
137    }
138    
139    ContentStorageListener listener = getContentStorageListener();
140    if(listener != null){
141      listener.feedbackTaskCreated(details);
142    }
143  }
144  
145  /**
146   * helper for notifying listener (if given) about a new photo task
147   * 
148   * @param details
149   * @throws IllegalArgumentException on invalid details
150   */
151  protected void notifyAnalysisTaskCreated(AbstractTaskDetails details) throws IllegalArgumentException{
152    if(details == null || details.getTaskType() != TaskType.ANALYSIS){
153      throw new IllegalArgumentException("Invalid task details.");
154    }
155    
156    ContentStorageListener listener = getContentStorageListener();
157    if(listener != null){
158      listener.analysisTaskCreated(details);
159    }
160  }
161
162  /**
163   * 
164   * @return service type of the storage
165   */
166  public abstract ServiceType getServiceType();
167  
168  /**
169   * 
170   * @param details
171   * @return static target URL or null if not available
172   */
173  public abstract String getTargetUrl(AccessDetails details);
174  
175  /**
176   * Remove the synchronized content
177   * 
178   * @param userId this user's metadata will be removed from the front-end
179   * @param guids optional list of GUIDs, if null, everything is removed
180   */
181  public abstract void removeMetadata(UserIdentity userId, Collection<String> guids);
182  
183  /**
184   * 
185   * @param userId
186   * @return true on success
187   */
188  public abstract boolean synchronizeAccount(UserIdentity userId);
189  
190  /**
191   * 
192   * @return set of accepted back-end capabilities for this storage
193   */
194  public abstract EnumSet<Capability> getBackendCapabilities();
195  
196  /**
197   * A listener interface, which can be used in combination with ContentStorage, either with or without task auto schedule.
198   * 
199   */
200  public interface ContentStorageListener {
201    /**
202     * Called when a new analyze task has been created. Note that this may be called multiple times, if multiple tasks are created.
203     * 
204     * @param details
205     */
206    public void analysisTaskCreated(AbstractTaskDetails details);
207    
208    /**
209     * Called when a new feedback task has been created. Note that this may be called multiple times, if multiple tasks are created.
210     * 
211     * @param details
212     */
213    public void feedbackTaskCreated(AbstractTaskDetails details);
214  } // interface ContentStorageListener
215}