/*******************************************************************************
* Copyright (c) 2015 Red Hat, Inc.
* Distributed under license by Red Hat, Inc. All rights reserved.
* This program is 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
*
* Contributors:
* Red Hat, Inc. - initial API and implementation
******************************************************************************/
package org.jboss.tools.batch.ui.editor.internal.model;
import java.text.MessageFormat;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.eclipse.core.resources.IProject;
import org.eclipse.sapphire.ElementList;
import org.eclipse.sapphire.Event;
import org.eclipse.sapphire.Listener;
import org.eclipse.sapphire.Property;
import org.eclipse.sapphire.Value;
import org.eclipse.sapphire.modeling.Status;
import org.eclipse.sapphire.services.ValidationService;
import org.jboss.tools.batch.core.BatchArtifactType;
import org.jboss.tools.batch.core.BatchCorePlugin;
import org.jboss.tools.batch.core.BatchProjectChangeEvent;
import org.jboss.tools.batch.core.IBatchArtifact;
import org.jboss.tools.batch.core.IBatchProject;
import org.jboss.tools.batch.core.IBatchProjectChangeListener;
import org.jboss.tools.batch.internal.core.validation.BatchValidator;
import org.jboss.tools.batch.ui.editor.internal.util.ModelToBatchArtifactsMapping;
/**
*
* @author Viacheslav Kabanovich
*
*/
public class RefValidationService extends ValidationService {
private Property property;
private Listener listener;
private IBatchProject batchProject;
BatchArtifactType type = null;
boolean isChunkListener = false;
@Override
@SuppressWarnings("unchecked")
protected void initValidationService() {
property = context(Property.class);
IProject project = context(Job.class).adapt(IProject.class);
batchProject = BatchCorePlugin.getBatchProject(project, true);
listener = new Listener() {
@Override
public void handle( final Event event ) {
refresh();
}
};
attach(listener);
if(batchProject != null) {
Listeners.getListener(batchProject).add(this);
}
Class<? extends RefAttributeElement> cls = (Class<? extends RefAttributeElement>) property.element().type().getModelElementClass();
List<BatchArtifactType> types = ModelToBatchArtifactsMapping.getBatchArtifactTypes(cls);
if(types.size() == 1) {
type = types.get(0);
} else if(types.size() > 1) {
type = BatchArtifactType.STEP_LISTENER;
Step e = (Step)property.element().parent().element();
ElementList<BatchletOrChunk> ch = e.getBatchletOrChunk();
if(ch.isEmpty() || ch.get(0) instanceof Chunk) {
isChunkListener = true;
}
}
}
@Override
protected Status compute() {
if(batchProject == null) {
return Status.createOkStatus();
}
String message = null;
if(property instanceof Value<?>) {
Object c = ((Value<?>)property).content();
if(c != null) {
String ref = c.toString();
Collection<IBatchArtifact> as = batchProject.getArtifacts(ref);
if(as.isEmpty()) {
message = type == null ? "" : BatchValidator.TypeToValidationMessage.getNotFoundMessage(type);
message = MessageFormat.format(message, ref);
} else if(type != null) {
IBatchArtifact a = as.iterator().next();
if(isChunkListener) {
if(!type.getTag().equals(a.getArtifactType().getTag())) {
message = BatchValidator.TypeToValidationMessage.getWrongTypeMessage(type);
message = MessageFormat.format(message, ref);
}
} else if(!type.equals(a.getArtifactType())) {
message = BatchValidator.TypeToValidationMessage.getWrongTypeMessage(type);
}
}
}
}
return message == null ? Status.createOkStatus() : Status.createErrorStatus(message);
}
@Override
public void dispose() {
super.dispose();
if(this.listener != null) {
detach(this.listener);
}
if(batchProject != null) {
Listeners.getListener(batchProject).remove(this);
}
}
static class Listeners {
static Map<String, BatchChangeListener> listeners = new HashMap<String, BatchChangeListener>();
static synchronized BatchChangeListener getListener(IBatchProject batchProject) {
String name = batchProject.getProject().getName();
BatchChangeListener listener = listeners.get(name);
if(listener == null) {
listener = new BatchChangeListener();
listeners.put(name, listener);
batchProject.addBatchProjectListener(listener);
}
return listener;
}
}
static class BatchChangeListener implements IBatchProjectChangeListener {
Set<RefValidationService> refs = new HashSet<RefValidationService>();
synchronized void add(RefValidationService ref) {
refs.add(ref);
}
synchronized void remove(RefValidationService ref) {
refs.remove(ref);
}
synchronized RefValidationService[] getRefs() {
return refs.toArray(new RefValidationService[refs.size()]);
}
@Override
public void projectChanged(BatchProjectChangeEvent event) {
for (RefValidationService ref: getRefs()) {
ref.refresh();
}
}
}
}