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}