package ch.fusun.baron.serverapp.view;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.Platform;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.part.ViewPart;
import ch.fusun.baron.core.injection.Inject;
import ch.fusun.baron.core.injection.ReInjector;
import ch.fusun.baron.core.rmi.User;
import ch.fusun.baron.core.service.UserListener;
import ch.fusun.baron.core.service.UserService;
import ch.fusun.baron.data.DataUpdate;
import ch.fusun.baron.serverapp.Activator;
import ch.fusun.baron.turn.TurnListener;
import ch.fusun.baron.turn.TurnService;
/**
* A view to show all the logged in users
*/
public class UsersView extends ViewPart implements TurnListener, UserListener {
/**
* The View ID
*/
public static final String ID = "ch.fusun.baron.serverapp.usersview"; //$NON-NLS-1$
private TreeViewer viewer;
private ViewContentProvider contentProvider;
private UserService userService;
private TurnService turnService;
private final List<UserChildrenProvider> childrenProvider = new ArrayList<UserChildrenProvider>();
private static final String UI_USER_CHILDREN_PROVIDER = "ch.fusun.baron.serverapp.userchildren"; //$NON-NLS-1$
private static final String PROVIDER = "provider"; //$NON-NLS-1$
/**
* Constructor
*
*/
public UsersView() {
ReInjector.getInstance().reInject(this);
IConfigurationElement[] config = Platform.getExtensionRegistry()
.getConfigurationElementsFor(UI_USER_CHILDREN_PROVIDER);
try {
for (IConfigurationElement e : config) {
UserChildrenProvider bean = (UserChildrenProvider) e
.createExecutableExtension(PROVIDER);
childrenProvider.add(bean);
ReInjector.getInstance().reInject(bean);
}
} catch (CoreException ex) {
System.err.println("Handle this error with log or so: " //$NON-NLS-1$
+ ex.getMessage());
}
}
/**
* @return the {@link UserService}
*/
public UserService getUserService() {
return userService;
}
/**
* @param userService
* the new user Service
*/
@Inject
public void setUserService(UserService userService) {
this.userService = userService;
this.userService.addDataListener(this);
if (viewer != null) {
viewer.setInput(new UsersViewRoot(userService));
}
}
/**
* @param turnService
* The new turn service
*/
@Inject
public void setTurnService(TurnService turnService) {
this.turnService = turnService;
this.turnService.addDataListener(this);
}
/**
* The content provider class is responsible for providing objects to the
* view. It can wrap existing objects in adapters or simply return objects
* as-is. These objects may be sensitive to the current input of the view,
* or ignore it and always show the same content (like Task List, for
* example).
*/
class ViewContentProvider implements ITreeContentProvider {
@Override
public void dispose() {
// Do nothing
}
@Override
public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
// TODO Auto-generated method stub
}
@Override
public Object[] getChildren(Object parentElement) {
if (parentElement instanceof UsersViewRoot) {
return ((UsersViewRoot) parentElement).getUsers();
}
if (parentElement instanceof User) {
return getAllChildren((User) parentElement).toArray();
}
return null;
}
@Override
public Object getParent(Object element) {
return null;
}
@Override
public boolean hasChildren(Object element) {
if (element instanceof UsersViewRoot) {
return ((UsersViewRoot) element).getUsers().length > 0;
}
if (element instanceof User) {
List<Object> children = getAllChildren((User) element);
if (!children.isEmpty()) {
return true;
}
}
return false;
}
private List<Object> getAllChildren(User user) {
List<Object> children = new ArrayList<Object>();
for (UserChildrenProvider provider : childrenProvider) {
List<?> temp = provider.getChildren(user);
if (temp != null) {
children.addAll(temp);
}
}
return children;
}
@Override
public Object[] getElements(Object inputElement) {
return getChildren(inputElement);
}
}
class ViewLabelProvider extends LabelProvider {
@Override
public String getText(Object element) {
if (element instanceof User) {
User user = (User) element;
return user.getName();
}
return element == null ? "" : element.toString(); //$NON-NLS-1$
}
@Override
public Image getImage(Object obj) {
if (obj instanceof User) {
if (getUserService().isLoggedIn((User) obj)) {
return Activator.getImageDescriptor(Activator.USER_ONLINE)
.createImage();
}
return Activator.getImageDescriptor(Activator.USER_OFFLINE)
.createImage();
}
for (UserChildrenProvider provider : childrenProvider) {
Image image = provider.getImage(obj);
if (image != null) {
return image;
}
}
return null;
}
}
private Display getDisplay() {
return getSite().getShell().getDisplay();
}
@Override
public void onTurn() {
getDisplay().syncExec(new Runnable() {
@Override
public void run() {
viewer.refresh();
}
});
}
@Override
public void userLoggedOut(final User user) {
getDisplay().syncExec(new Runnable() {
@Override
public void run() {
viewer.refresh();
}
});
}
@Override
public void userLoggedIn(final User user) {
getDisplay().syncExec(new Runnable() {
@Override
public void run() {
viewer.refresh();
}
});
}
@Override
public void userCreated(final User user) {
getDisplay().syncExec(new Runnable() {
@Override
public void run() {
viewer.refresh();
}
});
}
/**
* This is a call back that will allow us to create the viewer and
* initialize it.
*/
@Override
public void createPartControl(Composite parent) {
viewer = new TreeViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL);
contentProvider = new ViewContentProvider();
viewer.setContentProvider(contentProvider);
viewer.setLabelProvider(new ViewLabelProvider());
// Provide the input to the ContentProvider
viewer.setInput(new UsersViewRoot(userService));
}
/**
* Passing the focus request to the viewer's control.
*/
@Override
public void setFocus() {
viewer.getControl().setFocus();
}
@Override
public void dataChanged(DataUpdate update) {
getDisplay().syncExec(new Runnable() {
@Override
public void run() {
viewer.refresh();
}
});
}
}