/**
* (C) Copyright 2013 Jabylon (http://www.jabylon.org) and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.jabylon.rest.ui.wicket.panels;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.jabylon.common.review.ReviewParticipant;
import org.jabylon.common.util.PreferencesUtil;
import org.jabylon.properties.Project;
import org.jabylon.properties.Property;
import org.jabylon.properties.Review;
import org.jabylon.rest.ui.model.PropertyPair;
import org.osgi.service.prefs.Preferences;
/**
* Replaces the old PropertyListMode ENUM.<br>
* Allows for dynamically adding {@link PropertyListMode}s based on {@link ReviewParticipant}s.<br>
* The "old" default {@link PropertyListMode}s are still there:<br>
* {@link #ALL}, {@link #MISSING} and {@link #FUZZY}.<br>
*
* @author c.samulski
*/
public final class PropertyListModeFactory {
/**
* No instantiation necessary. No state, purely functional.<br>
*/
private PropertyListModeFactory() {}
/**
* Holds the default {@link PropertyListMode}s: {@link: #ALL}, {@link #MISSING} and
* {@link #FUZZY}.<br>
*/
private static final Map<String, PropertyListMode> MODES = new LinkedHashMap<>();
/**
* Default {@link PropertyListMode} for *ALL*, i.e. no filter at all.<br>
*/
public static final PropertyListMode ALL = new PropertyListMode() {
@Override
public boolean apply(PropertyPair pair, Collection<Review> reviews) {
return true;
}
@Override
public String name() {
return "All";
}
};
/**
* Default {@link PropertyListMode} for *MISSING*, i.e. a missing value for either the template,
* or the translation {@link Property}.<br>
*/
public static final PropertyListMode MISSING = new PropertyListMode() {
@Override
public boolean apply(PropertyPair pair, Collection<Review> reviews) {
return pair.getOriginal() == null || pair.getTranslated() == null || pair.getOriginal().isEmpty()
|| pair.getTranslated().isEmpty();
}
@Override
public String name() {
return "Missing";
}
};
/**
* Default {@link PropertyListMode} for *FUZZY*. {@link #MISSING} applies, or a {@link Review}
* is present for this {@link PropertyPair}.<br>
*/
public static final PropertyListMode FUZZY = new PropertyListMode() {
@Override
public boolean apply(PropertyPair pair, Collection<Review> reviews) {
if (MISSING.apply(pair, reviews)) {
return true;
}
return reviews != null && !reviews.isEmpty();
}
@Override
public String name() {
return "Fuzzy";
}
};
/*
* Add defaults. These should always be available.
*/
static {
MODES.put(ALL.name(), ALL);
MODES.put(MISSING.name(), MISSING);
MODES.put(FUZZY.name(), FUZZY);
}
/**
* Creates a {@link PropertyListMode} implementation for the given {@link ReviewParticipant}.<br>
*/
public static final PropertyListMode forReviewParticipant(final ReviewParticipant participant) {
return new PropertyListMode() {
@Override
public String name() {
return participant.getID();
}
@Override
public boolean apply(PropertyPair pair, Collection<Review> reviews) {
if (reviews == null) {
return false;
}
/* apply call is true if any review for *this* ReviewParticipant exists. */
for (Review review : reviews) {
if (review.getReviewType().equals(participant.getReviewType())) {
return true;
}
}
return false;
}
@Override
public ReviewParticipant getParticipant() {
return participant;
}
};
}
/**
* Return populated {@link Map} filled with the default {@link PropertyListMode}s AND the passed
* {@link ReviewParticipant}s as {@link PropertyListMode}s.<br>
*
* Note: We subclass {@link LinkedHashMap} to override {@link Map#get(Object)} to allow
* returning the default {@link PropertyListModeFactory#ALL} instead of null if
* {@link LinkedHashMap#get(Object)} returns null.<br>
*/
public static final Map<String, PropertyListMode> allAsMap(final List<ReviewParticipant> participants) {
return new LinkedHashMap<String, PropertyListMode>() {
private static final long serialVersionUID = 1L;
@Override
public PropertyListMode get(Object key) {
PropertyListMode mode = super.get(key);
if (mode == null) {
return ALL; // default
}
return mode;
}
/*
* Here be initializer. Fill map with defaults and PropertyListModes for the given
* ReviewParticipants.
*/
{
putAll(MODES);
for (ReviewParticipant participant : participants) {
put(participant.getID(), forReviewParticipant(participant));
}
}
};
}
/**
* @return populated {@link List} of {@link PropertyListMode} containing the defaults
* {@link #ALL}, {@link #MISSING} and {@link #FUZZY}, plus the ones generated via
* {@link #forReviewParticipant(ReviewParticipant)} for the passed
* {@link ReviewParticipant}s.<br>
*/
public static final List<PropertyListMode> all(List<ReviewParticipant> participants) {
List<PropertyListMode> ret = new ArrayList<>();
ret.addAll(MODES.values());
/* Enforce standard sorting. */
sortReviewParticipants(participants);
/* Add PropertyListMode implementation for each ReviewParticipant. */
for (ReviewParticipant participant : participants) {
ret.add(forReviewParticipant(participant));
}
return ret;
}
/**
* @return populated {@link List} of {@link PropertyListMode} containing the defaults
* {@link #ALL}, {@link #MISSING} and {@link #FUZZY}.<br>
*/
public static final List<PropertyListMode> all() {
List<PropertyListMode> ret = new ArrayList<>();
ret.addAll(MODES.values());
return ret;
}
/**
* For UI Callers we maintain the same sorting of {@link ReviewParticipant}s.<br>
*/
private static void sortReviewParticipants(List<ReviewParticipant> participants) {
Collections.sort(participants, new Comparator<ReviewParticipant>() {
@Override
public int compare(ReviewParticipant one, ReviewParticipant two) {
return one.getReviewType().compareTo(two.getReviewType());
}
});
}
/**
* filters the given participant lists depending on which of them are active for the project in question
* @param project
* @param participants
* @return filtered list of active participants
*/
public static List<ReviewParticipant> filterActiveReviews(Project project, List<ReviewParticipant> participants) {
List<ReviewParticipant> activeParticipants = new ArrayList<ReviewParticipant>();
Preferences node = PreferencesUtil.scopeFor(project).node(PreferencesUtil.NODE_CHECKS);
for (ReviewParticipant participant : participants) {
if (node.getBoolean(participant.getID(), false))
activeParticipants.add(participant);
}
return activeParticipants;
}
}