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.contentanalysis;
017
018import java.util.ArrayList;
019import java.util.Collection;
020import java.util.Iterator;
021import java.util.List;
022import java.util.Set;
023
024import javax.xml.bind.annotation.XmlAccessType;
025import javax.xml.bind.annotation.XmlAccessorType;
026import javax.xml.bind.annotation.XmlElement;
027import javax.xml.bind.annotation.XmlRootElement;
028
029import org.apache.log4j.Logger;
030
031import service.tut.pori.contentanalysis.AnalysisBackend.Capability;
032import service.tut.pori.contentanalysis.AsyncTask.TaskStatus;
033
034
035/**
036 * Contains back-end specific status information.
037 * 
038 * <h3>XML Example</h3>
039 * 
040 * {@doc.restlet service="[service.tut.pori.contentanalysis.reference.Definitions#SERVICE_CA_REFERENCE_EXAMPLE]" method="[service.tut.pori.contentanalysis.Definitions#ELEMENT_BACKEND_STATUS_LIST]" type="GET" query="" body_uri=""}
041 * 
042 * @see service.tut.pori.contentanalysis.BackendStatus
043 */
044@XmlRootElement(name=Definitions.ELEMENT_BACKEND_STATUS_LIST)
045@XmlAccessorType(XmlAccessType.NONE)
046public class BackendStatusList{
047  private static final Logger LOGGER = Logger.getLogger(BackendStatusList.class);
048  @XmlElement(name = Definitions.ELEMENT_BACKEND_STATUS)
049  private List<BackendStatus> _backendStatuses = null;     
050
051  /**
052   * 
053   * @return list of back-end statuses
054   * @see #setBackendStatus(BackendStatus)
055   */
056  public List<BackendStatus> getBackendStatuses() {
057    return _backendStatuses;
058  }
059
060  /**
061   * 
062   * @return true if all back-ends in this list have completed their task
063   */
064  public boolean isCompleted(){
065    if(_backendStatuses == null){
066      LOGGER.warn("No back-ends.");
067      return false;
068    }else{
069      for(Iterator<BackendStatus> iter = _backendStatuses.iterator(); iter.hasNext();){
070        if(iter.next().getStatus() != TaskStatus.COMPLETED){
071          return false;
072        }
073      }
074      return true;
075    }
076  }
077
078  /**
079   * 
080   * @param allOf
081   * @return all back-ends that have all of the given capabilities or null if none found
082   */
083  public List<BackendStatus> getBackendStatuses(Set<Capability> allOf){
084    if(isEmpty()){
085      LOGGER.debug("No statuses.");
086      return null;
087    }
088    if(allOf == null || allOf.isEmpty()){
089      LOGGER.warn("Empty capability list.");
090      return null;
091    }
092    List<BackendStatus> statusesWithCapability = new ArrayList<>();
093    for(BackendStatus status : _backendStatuses){
094      AnalysisBackend backend = status.getBackend();
095      if(backend.hasCapabilities(allOf)){
096        statusesWithCapability.add(status);
097      }
098    }
099    return (statusesWithCapability.isEmpty() ? null : statusesWithCapability);
100  }
101
102  /**
103   * 
104   * @return the overall (combined) status for all backends
105   * 
106   */
107  public TaskStatus getCombinedStatus(){
108    if(_backendStatuses != null){
109      List<TaskStatus> statusList = new ArrayList<>();
110      for(Iterator<BackendStatus> iter = _backendStatuses.iterator(); iter.hasNext();){
111        statusList.add(iter.next().getStatus());
112      }  // for
113      return TaskStatus.getCombinedTaskStatus(statusList);
114    }else{
115      return TaskStatus.UNKNOWN;
116    }
117  }
118
119  /**
120   * If a status for the given backend already exists, it is replaced
121   * 
122   * @param backendStatus
123   * @see #getBackendStatuses()
124   */
125  public void setBackendStatus(BackendStatus backendStatus) {
126    if(_backendStatuses == null){
127      _backendStatuses = new ArrayList<>();
128    }else{
129      Integer backendId = backendStatus.getBackend().getBackendId();
130      for(Iterator<BackendStatus> iter = _backendStatuses.iterator(); iter.hasNext();){ // remove old one if it exists
131        BackendStatus status = iter.next();
132        if(status.getBackend().getBackendId().equals(backendId)){
133          iter.remove();
134          break;
135        }
136      } // for
137    }
138    _backendStatuses.add(backendStatus);
139  }
140
141  /**
142   * 
143   * @param backendId
144   * @return status for the backend, or null if none available
145   */
146  public BackendStatus getBackendStatus(Integer backendId){
147    if(_backendStatuses == null){
148      return null;
149    }
150    for(Iterator<BackendStatus> iter = _backendStatuses.iterator(); iter.hasNext();){ // remove old one if it exists
151      BackendStatus status = iter.next();
152      if(status.getBackend().getBackendId().equals(backendId)){
153        return status;
154      }
155    } // for
156    return null;
157  }
158
159  /**
160   * 
161   * @param container 
162   * @return true if the container is null or empty
163   */
164  public static boolean isEmpty(BackendStatusList container){
165    if(container == null){
166      return true;
167    }else{
168      return container.isEmpty();
169    }
170  }
171
172  /**
173   * use the static, this is only for sub-classing
174   * @return true if this container is empty
175   * @see #isEmpty(BackendStatusList)
176   */
177  protected boolean isEmpty(){
178    return (_backendStatuses == null || _backendStatuses.isEmpty() ? true : false);
179  }
180
181  /**
182   * 
183   * @param statuses
184   * @return new status list or null if empty or null list was passed
185   */
186  public static BackendStatusList getBackendStatusList(List<BackendStatus> statuses){
187    if(statuses == null || statuses.isEmpty()){
188      return null;
189    }
190    BackendStatusList list = new BackendStatusList();
191    list._backendStatuses = statuses;
192    return list;
193  }
194
195  /**
196   * Add all back-ends with the given status
197   * 
198   * @param ends
199   * @param status
200   * @see #setBackendStatus(BackendStatus)
201   */
202  public void setBackendStatus(Collection<AnalysisBackend> ends, TaskStatus status) {
203    if(ends == null || ends.isEmpty()){
204      LOGGER.debug("Empty back-end list.");
205      return;
206    }
207    for(AnalysisBackend end : ends){
208      setBackendStatus(new BackendStatus(end, status));
209    }
210  }
211}