001/* 002 * Sonar, open source software quality management tool. 003 * Copyright (C) 2008-2012 SonarSource 004 * mailto:contact AT sonarsource DOT com 005 * 006 * Sonar is free software; you can redistribute it and/or 007 * modify it under the terms of the GNU Lesser General Public 008 * License as published by the Free Software Foundation; either 009 * version 3 of the License, or (at your option) any later version. 010 * 011 * Sonar is distributed in the hope that it will be useful, 012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 014 * Lesser General Public License for more details. 015 * 016 * You should have received a copy of the GNU Lesser General Public 017 * License along with Sonar; if not, write to the Free Software 018 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 019 */ 020package org.sonar.server.ui; 021 022import com.google.common.collect.ImmutableSet; 023import com.google.common.collect.Maps; 024import org.apache.commons.lang.ArrayUtils; 025import org.apache.commons.lang.StringUtils; 026import org.apache.commons.lang.builder.CompareToBuilder; 027import org.apache.commons.lang.builder.EqualsBuilder; 028import org.apache.commons.lang.builder.ToStringBuilder; 029import org.sonar.api.utils.AnnotationUtils; 030import org.sonar.api.web.DefaultTab; 031import org.sonar.api.web.Description; 032import org.sonar.api.web.GwtPage; 033import org.sonar.api.web.NavigationSection; 034import org.sonar.api.web.RequiredMeasures; 035import org.sonar.api.web.ResourceLanguage; 036import org.sonar.api.web.ResourceQualifier; 037import org.sonar.api.web.ResourceScope; 038import org.sonar.api.web.UserRole; 039import org.sonar.api.web.View; 040import org.sonar.api.web.Widget; 041import org.sonar.api.web.WidgetCategory; 042import org.sonar.api.web.WidgetLayout; 043import org.sonar.api.web.WidgetLayoutType; 044import org.sonar.api.web.WidgetProperties; 045import org.sonar.api.web.WidgetProperty; 046import org.sonar.api.web.WidgetScope; 047 048import java.util.Collection; 049import java.util.Map; 050 051@SuppressWarnings("rawtypes") 052public class ViewProxy<V extends View> implements Comparable<ViewProxy> { 053 054 private V view; 055 private String[] sections = {NavigationSection.HOME}; 056 private String[] userRoles = {}; 057 private String[] resourceScopes = {}; 058 private String[] resourceQualifiers = {}; 059 private String[] resourceLanguages = {}; 060 private String[] defaultForMetrics = {}; 061 private String description = ""; 062 private Map<String, WidgetProperty> widgetPropertiesByKey = Maps.newHashMap(); 063 private String[] widgetCategories = {}; 064 private WidgetLayoutType widgetLayout = WidgetLayoutType.DEFAULT; 065 private boolean isDefaultTab = false; 066 private boolean isWidget = false; 067 private boolean isGlobal = false; 068 private String[] mandatoryMeasures = {}; 069 private String[] needOneOfMeasures = {}; 070 071 public ViewProxy(final V view) { 072 this.view = view; 073 074 initUserRoles(view); 075 initSections(view); 076 initResourceScope(view); 077 initResourceQualifier(view); 078 initResourceLanguage(view); 079 initDefaultTabInfo(view); 080 initDescription(view); 081 initWidgetProperties(view); 082 initWidgetCategory(view); 083 initWidgetLayout(view); 084 initWidgetGlobal(view); 085 initRequiredMeasures(view); 086 087 isWidget = (view instanceof Widget); 088 } 089 090 private void initRequiredMeasures(V view) { 091 RequiredMeasures requiredMeasuresAnnotation = AnnotationUtils.getAnnotation(view, RequiredMeasures.class); 092 if (requiredMeasuresAnnotation != null) { 093 mandatoryMeasures = requiredMeasuresAnnotation.allOf(); 094 needOneOfMeasures = requiredMeasuresAnnotation.anyOf(); 095 } 096 } 097 098 private void initWidgetLayout(final V view) { 099 WidgetLayout layoutAnnotation = AnnotationUtils.getAnnotation(view, WidgetLayout.class); 100 if (layoutAnnotation != null) { 101 widgetLayout = layoutAnnotation.value(); 102 } 103 } 104 105 private void initWidgetCategory(final V view) { 106 WidgetCategory categAnnotation = AnnotationUtils.getAnnotation(view, WidgetCategory.class); 107 if (categAnnotation != null) { 108 widgetCategories = categAnnotation.value(); 109 } 110 } 111 112 private void initWidgetGlobal(V view) { 113 WidgetScope scopeAnnotation = AnnotationUtils.getAnnotation(view, WidgetScope.class); 114 if (scopeAnnotation != null) { 115 checkValidScope(view, scopeAnnotation); 116 isGlobal = ImmutableSet.copyOf(scopeAnnotation.value()).contains(WidgetScope.GLOBAL); 117 } 118 } 119 120 private static <V> void checkValidScope(V view, WidgetScope scopeAnnotation) { 121 for (String scope : scopeAnnotation.value()) { 122 if (!scope.equals(WidgetScope.PROJECT) && !scope.equalsIgnoreCase(WidgetScope.GLOBAL)) { 123 throw new IllegalArgumentException(String.format("Invalid widget scope %s for widget %s", scope, view.getClass().getSimpleName())); 124 } 125 } 126 } 127 128 private void initWidgetProperties(final V view) { 129 WidgetProperties propAnnotation = AnnotationUtils.getAnnotation(view, WidgetProperties.class); 130 if (propAnnotation != null) { 131 for (WidgetProperty property : propAnnotation.value()) { 132 widgetPropertiesByKey.put(property.key(), property); 133 } 134 } 135 } 136 137 private void initDescription(final V view) { 138 Description descriptionAnnotation = AnnotationUtils.getAnnotation(view, Description.class); 139 if (descriptionAnnotation != null) { 140 description = descriptionAnnotation.value(); 141 } 142 } 143 144 private void initDefaultTabInfo(final V view) { 145 DefaultTab defaultTabAnnotation = AnnotationUtils.getAnnotation(view, DefaultTab.class); 146 if (defaultTabAnnotation != null) { 147 if (defaultTabAnnotation.metrics().length == 0) { 148 isDefaultTab = true; 149 defaultForMetrics = new String[0]; 150 151 } else { 152 isDefaultTab = false; 153 defaultForMetrics = defaultTabAnnotation.metrics(); 154 } 155 } 156 } 157 158 private void initResourceLanguage(final V view) { 159 ResourceLanguage languageAnnotation = AnnotationUtils.getAnnotation(view, ResourceLanguage.class); 160 if (languageAnnotation != null) { 161 resourceLanguages = languageAnnotation.value(); 162 } 163 } 164 165 private void initResourceQualifier(final V view) { 166 ResourceQualifier qualifierAnnotation = AnnotationUtils.getAnnotation(view, ResourceQualifier.class); 167 if (qualifierAnnotation != null) { 168 resourceQualifiers = qualifierAnnotation.value(); 169 } 170 } 171 172 private void initResourceScope(final V view) { 173 ResourceScope scopeAnnotation = AnnotationUtils.getAnnotation(view, ResourceScope.class); 174 if (scopeAnnotation != null) { 175 resourceScopes = scopeAnnotation.value(); 176 } 177 } 178 179 private void initSections(final V view) { 180 NavigationSection sectionAnnotation = AnnotationUtils.getAnnotation(view, NavigationSection.class); 181 if (sectionAnnotation != null) { 182 sections = sectionAnnotation.value(); 183 } 184 } 185 186 private void initUserRoles(final V view) { 187 UserRole userRoleAnnotation = AnnotationUtils.getAnnotation(view, UserRole.class); 188 if (userRoleAnnotation != null) { 189 userRoles = userRoleAnnotation.value(); 190 } 191 } 192 193 public V getTarget() { 194 return view; 195 } 196 197 public String getId() { 198 return view.getId(); 199 } 200 201 public boolean isController() { 202 String id = view.getId(); 203 return id !=null && id.length()>0 && id.charAt(0)=='/'; 204 } 205 206 public String getTitle() { 207 return view.getTitle(); 208 } 209 210 public String getDescription() { 211 return description; 212 } 213 214 public Collection<WidgetProperty> getWidgetProperties() { 215 return widgetPropertiesByKey.values(); 216 } 217 218 public WidgetProperty getWidgetProperty(String propertyKey) { 219 return widgetPropertiesByKey.get(propertyKey); 220 } 221 222 public String[] getWidgetCategories() { 223 return widgetCategories; 224 } 225 226 public String[] getSections() { 227 return sections; 228 } 229 230 public String[] getUserRoles() { 231 return userRoles; 232 } 233 234 public String[] getResourceScopes() { 235 return resourceScopes; 236 } 237 238 public String[] getResourceQualifiers() { 239 return resourceQualifiers; 240 } 241 242 public String[] getResourceLanguages() { 243 return resourceLanguages; 244 } 245 246 public boolean isDefaultTab() { 247 return isDefaultTab; 248 } 249 250 public String[] getDefaultTabForMetrics() { 251 return defaultForMetrics; 252 } 253 254 public boolean supportsMetric(String metricKey) { 255 return ArrayUtils.contains(defaultForMetrics, metricKey); 256 } 257 258 public boolean acceptsAvailableMeasures(String[] availableMeasures) { 259 for (String mandatoryMeasure : mandatoryMeasures) { 260 if (!ArrayUtils.contains(availableMeasures, mandatoryMeasure)) { 261 return false; 262 } 263 } 264 if (needOneOfMeasures.length == 0) { 265 return true; 266 } else { 267 for (String neededMeasure : needOneOfMeasures) { 268 if (ArrayUtils.contains(availableMeasures, neededMeasure)) { 269 return true; 270 } 271 } 272 return false; 273 } 274 } 275 276 public boolean isWidget() { 277 return isWidget; 278 } 279 280 public boolean isGlobal() { 281 return isGlobal; 282 } 283 284 public boolean isGwt() { 285 return view instanceof GwtPage; 286 } 287 288 public WidgetLayoutType getWidgetLayout() { 289 return widgetLayout; 290 } 291 292 public boolean isEditable() { 293 return !widgetPropertiesByKey.isEmpty(); 294 } 295 296 public boolean hasRequiredProperties() { 297 boolean requires = false; 298 for (WidgetProperty property : getWidgetProperties()) { 299 if (!property.optional() && StringUtils.isEmpty(property.defaultValue())) { 300 requires = true; 301 } 302 } 303 return requires; 304 } 305 306 @Override 307 public int hashCode() { 308 return getId().hashCode(); 309 } 310 311 @Override 312 public boolean equals(Object obj) { 313 if (obj == null) { 314 return false; 315 } 316 if (obj == this) { 317 return true; 318 } 319 if (obj.getClass() != getClass()) { 320 return false; 321 } 322 ViewProxy rhs = (ViewProxy) obj; 323 return new EqualsBuilder() 324 .append(getId(), rhs.getId()) 325 .isEquals(); 326 } 327 328 @Override 329 public String toString() { 330 return new ToStringBuilder(this) 331 .append("id", view.getId()) 332 .append("sections", sections) 333 .append("userRoles", userRoles) 334 .append("scopes", resourceScopes) 335 .append("qualifiers", resourceQualifiers) 336 .append("languages", resourceLanguages) 337 .append("metrics", defaultForMetrics) 338 .toString(); 339 340 } 341 342 public int compareTo(ViewProxy other) { 343 return new CompareToBuilder() 344 .append(getTitle(), other.getTitle()) 345 .append(getId(), other.getId()) 346 .toComparison(); 347 348 } 349}