/*
* Copyright 2013 Hewlett-Packard Development Company, L.P
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.hp.alm.ali.idea.entity.table;
import com.hp.alm.ali.idea.entity.EntityFilterModel;
import com.hp.alm.ali.idea.entity.EntityQuery;
import com.hp.alm.ali.idea.cfg.AliProjectConfiguration;
import com.hp.alm.ali.idea.entity.FilterListener;
import com.hp.alm.ali.idea.services.WeakListeners;
import org.apache.commons.lang.mutable.MutableBoolean;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.WeakHashMap;
public class QuerySharingManager {
private Map<String, WeakListeners<FilterListener<EntityQuery>>> listeners = new HashMap<String, WeakListeners<FilterListener<EntityQuery>>>();
private WeakHashMap<QuerySharing, FilterListener<EntityQuery>> ref = new WeakHashMap<QuerySharing, FilterListener<EntityQuery>>();
private AliProjectConfiguration conf;
public QuerySharingManager(AliProjectConfiguration conf) {
this.conf = conf;
}
public void addSharedQuery(final QuerySharing model, final String id) {
final MutableBoolean ignore = new MutableBoolean(false);
model.addFilterListener(new FilterListener<EntityQuery>() {
@Override
public void filterChanged(EntityQuery query) {
if (!ignore.booleanValue()) {
fireChangedEvent(query, id);
}
}
});
FilterListener<EntityQuery> listener = new FilterListener<EntityQuery>() {
@Override
public void filterChanged(EntityQuery query) {
LinkedHashMap<String, Integer> columns = query.getColumns();
if (query == model.getFilter()) {
conf.getFilter(id).setColumns(columns);
return; // ignore our own event (only store in project configuration)
}
ignore.setValue(true);
try {
model.setColumns(columns);
} finally {
ignore.setValue(false);
}
}
};
addListener(id, listener);
ref.put(model, listener); // make sure the listener is not garbage collected
}
public void removeSharedQuery(QuerySharing model, final String id) {
FilterListener<EntityQuery> listener = ref.remove(model);
if(listener != null) {
getOrCreate(id).remove(listener);
}
}
private void addListener(String id, FilterListener<EntityQuery> listener) {
getOrCreate(id).add(listener);
}
private void fireChangedEvent(final EntityQuery query, String id) {
getOrCreate(id).fire(new WeakListeners.Action<FilterListener<EntityQuery>>() {
@Override
public void fire(FilterListener<EntityQuery> listener) {
listener.filterChanged(query);
}
});
}
private synchronized WeakListeners<FilterListener<EntityQuery>> getOrCreate(String queryId) {
WeakListeners<FilterListener<EntityQuery>> entityListeners = listeners.get(queryId);
if(entityListeners == null) {
entityListeners = new WeakListeners<FilterListener<EntityQuery>>();
listeners.put(queryId, entityListeners);
}
return entityListeners;
}
interface QuerySharing extends EntityFilterModel<EntityQuery> {
void setColumns(LinkedHashMap<String, Integer> columns);
}
}