/**
* Copyright 1999-2009 The Pegadi Team
*
* 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.
*/
/**
* An application for listing and selecting articles. This is mostly built
* around the {@link ArticleList pegadi.articlelist.ArticleList} component.
*
* @author Jørgen Binningsbø <jb@underdusken.no>
* @author Håvard Wigtil <havardw at pvv.org>
*/
package org.pegadi.lister;
import com.kitfox.svg.SVGCache;
import com.kitfox.svg.app.beans.SVGIcon;
import no.dusken.common.model.Person;
import org.apache.fop.apps.FOUserAgent;
import org.apache.fop.apps.Fop;
import org.apache.fop.apps.FopFactory;
import org.apache.xmlgraphics.util.MimeConstants;
import org.pegadi.articlelist.ArticleList;
import org.pegadi.articlelist.Grouper;
import org.pegadi.articlesearch.SearchPanel;
import org.pegadi.artis.Artis;
import org.pegadi.artis.Artis.PrintDialog;
import org.pegadi.maildialog.MailDialog;
import org.pegadi.model.*;
import org.pegadi.permissions.ArticlePermissions;
import org.pegadi.permissions.GlobalPermissions;
import org.pegadi.publisher.FOPPrintPublisher;
import org.pegadi.publisher.FOPPrintRenderer;
import org.pegadi.server.NoAccessException;
import org.pegadi.sqlsearch.SearchTerm;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.sax.SAXResult;
import javax.xml.transform.sax.SAXTransformerFactory;
import javax.xml.transform.sax.TransformerHandler;
import javax.xml.transform.stream.StreamSource;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowEvent;
import java.awt.print.PrinterJob;
import java.net.InetAddress;
import java.net.URI;
import java.net.URL;
import java.net.UnknownHostException;
import java.rmi.RemoteException;
import java.text.MessageFormat;
import java.util.*;
public class Lister extends JFrame {
JPanel contentPane;
JPanel topPanel = new JPanel();
BorderLayout borderLayout1 = new BorderLayout();
JMenuBar jMenuBar1 = new JMenuBar();
JMenu mainMenu = new JMenu();
JMenu editMenu = new JMenu();
JMenuItem groupMenuItem = new JMenuItem();
JMenuItem columnsMenuItem = new JMenuItem();
JMenuItem chooseArticlesMenuItem = new JMenuItem();
JMenuItem prefsMenuItem = new JMenuItem();
JMenu changeArticleStatusMenu = new JMenu();
JScrollPane jScrollPane1 = new JScrollPane();
ArticleList articleList;
int[] myColumns = {0, 2, 3, 1, 5, 6, 8, 7};
Person mySelf;
Locale currentLocale;
ResourceBundle messages;
/**
* The string describeing the current selection
*/
String artSelString;
/**
* Application preferences.
*/
protected Properties prefs;
/**
* Preferences domain.
*/
static final String PREFS_DOMAIN = "Lister";
static final String PREFS_SEL_CLASS = "SelectionClass";
static final String PREFS_SEL_ID = "SelectionID";
static final String PREFS_SEL_DESC = "SelectionDescription";
static final String PREFS_SEL_REMEMBER = "RememberSelection";
JPopupMenu popup;
JMenu sendMailTo;
AbstractAction refreshAction;
AbstractAction editAction;
AbstractAction newAction;
AbstractAction aboutAction;
AbstractAction publishAction;
AbstractAction printListAction;
AbstractAction printArticleAction;
AbstractAction deleteAction;
AbstractAction sendMailToJournalistAction;
AbstractAction exitAction;
AbstractAction[] changeArticleStatusActions;
protected JToolBar toolBar = new JToolBar();
String lastPublishedToDir;
/**
* The panel used to contruct searchTerms and initate a search
*/
SearchPanel searchPanel;
/**
* The current searh term
*/
SearchTerm searchTerm;
private final Logger log = LoggerFactory.getLogger(getClass());
/**
* Constructs the frame and initalizes the articlelist with
* the authenticated user's articles.
*/
public Lister() {
enableEvents(AWTEvent.WINDOW_EVENT_MASK);
ImageIcon icon = new ImageIcon(getClass().getResource("/images/pegadi.gif"));
setIconImage(icon.getImage());
currentLocale = Locale.getDefault();
try {
messages = ResourceBundle.getBundle("org.pegadi.lister.ListerStrings", currentLocale);
} catch (Exception e) {
log.error("Error getting resources", e);
}
articleList = new ArticleList();
articleList.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
articleList_actionPerformed(e);
}
});
try {
createActions();
jbInit();
}
catch (Exception e) {
log.error("Error initialising GUI", e);
}
try {
searchTerm = searchPanel.getSearchTerm();
refreshArticles();
} catch (Exception e) {
log.error("Error getting articles", e);
}
// check if this user is layout, and thus can publish.
try {
if (LoginContext.server.hasGlobalPermission(LoginContext.server.getUserID(LoginContext.sessionKey), GlobalPermissions.LEGACY_PUBLISH_ARTICLES, LoginContext.sessionKey))
publishAction.setEnabled(true);
else
publishAction.setEnabled(false);
} catch (Exception se) {
log.error("Error checking user publishing privileges", se);
}
articleList.addChangeListener(new ChangeListener() {
public void stateChanged(ChangeEvent e) {
articleList_stateChanged(e);
}
});
loadPrefs();
try {
mySelf = LoginContext.server.getSessionUser(LoginContext.sessionKey);
} catch (Exception e) {
log.error("Error getting myself from server", e);
}
validate();
articleList.updateColumns(myColumns);
articleList.revalidate();
refreshArticles();
}
/**
* Load prefs from the server and apply.
*/
protected void loadPrefs() {
try {
prefs = LoginContext.server.getPreferences(PREFS_DOMAIN, LoginContext.sessionKey);
} catch (Exception e) {
log.error("Exception getting preferences for domain {}", PREFS_DOMAIN, e);
prefs = new Properties();
}
String sclass = prefs.getProperty(PREFS_SEL_CLASS);
if (sclass == null) {
sclass = Person.class.toString();
prefs.put(PREFS_SEL_CLASS, sclass);
}
String sID = prefs.getProperty(PREFS_SEL_ID);
if (sID == null) {
sID = "26"; // Hey, it's me! (havardw)
prefs.put(PREFS_SEL_ID, sID);
}
artSelString = prefs.getProperty(PREFS_SEL_DESC);
String remember = prefs.getProperty(PREFS_SEL_REMEMBER);
if (remember == null) {
remember = "false";
prefs.put(PREFS_SEL_REMEMBER, remember);
}
// Reset last selection to "My articles"
if (!Boolean.valueOf(remember)) {
prefs.put(PREFS_SEL_CLASS, Person.class.toString());
try {
prefs.put(PREFS_SEL_ID, String.valueOf(LoginContext.server.getUserID(LoginContext.sessionKey)));
} catch (Exception e) {
log.error("Unable to get user ID, setting to 0", e);
prefs.put(PREFS_SEL_ID, "0");
}
artSelString = messages.getString("selection_myself");
}
}
/**
* Refreshes the article list by re-reading from server.
*/
protected void refreshArticles() {
try {
java.util.List<Article> articles = LoginContext.server.getArticlesBySearchTerm(searchTerm, LoginContext.sessionKey);
articleList.regroup(articles);
articleList.revalidate();
articleList.repaint();
} catch (Exception ex) {
log.error("Exception updating articles.", ex);
}
// Currently no selection, update the actions
editAction.setEnabled(false);
aboutAction.setEnabled(false);
publishAction.setEnabled(false);
deleteAction.setEnabled(false);
printArticleAction.setEnabled(false);
sendMailTo.setEnabled(false);
changeArticleStatusMenu.setEnabled(false);
}
protected boolean displayDeleteWarning() {
//JOptionPane warning = new JoptionPane();
int warning = JOptionPane.showConfirmDialog(this,
messages.getString("confirm_delete"),
messages.getString("delete_articleitem"),
JOptionPane.YES_NO_OPTION,
JOptionPane.ERROR_MESSAGE);
if (warning == JOptionPane.YES_OPTION) {
return true;
} else {
log.debug("article deletion cancelled by user");
return false;
}//end if
}
/**
* Creates an SVGIcon that can be used by the UI.
* @param iconPath the path of the svg file
* @return an SVGIcon
*/
protected SVGIcon initSvgIcon(URL iconPath) {
URI iconURI = SVGCache.getSVGUniverse().loadSVG(iconPath);
SVGIcon icon = new SVGIcon();
icon.setSvgURI(iconURI);
icon.setAntiAlias(true);
icon.setPreferredSize(new Dimension(32,32));
icon.setScaleToFit(true);
return icon;
}
/**
* Create all actions used by the UI.
*/
protected void createActions() {
//ImageIcon refreshIcon = new ImageIcon(getClass().getResource(messages.getString("icon_refresh")));
SVGIcon refreshIcon = initSvgIcon(getClass().getResource(messages.getString("icon_refresh")));
refreshAction = new AbstractAction(messages.getString("refresh"), refreshIcon) {
public void actionPerformed(ActionEvent e) {
refreshArticles();
}
};
//ImageIcon editIcon = new ImageIcon(getClass().getResource(messages.getString("icon_edit")));
SVGIcon editIcon = initSvgIcon(getClass().getResource(messages.getString("icon_edit")));
editAction = new AbstractAction(messages.getString("edit_button"), editIcon) {
public void actionPerformed(ActionEvent e) {
editAction_actionPerformed(e);
}
};
//ImageIcon newIcon = new ImageIcon(getClass().getResource(messages.getString("icon_new")));
SVGIcon newIcon = initSvgIcon(getClass().getResource(messages.getString("icon_new")));
newAction = new AbstractAction(messages.getString("new_button"), newIcon) {
public void actionPerformed(ActionEvent e) {
newAction_actionPerformed(e);
}
};
//ImageIcon aboutIcon = new ImageIcon(getClass().getResource(messages.getString("icon_about")));
SVGIcon aboutIcon = initSvgIcon(getClass().getResource(messages.getString("icon_about")));
aboutAction = new AbstractAction(messages.getString("about_button"), aboutIcon) {
public void actionPerformed(ActionEvent e) {
aboutAction_actionPerformed(e);
}
};
//ImageIcon publishIcon = new ImageIcon(getClass().getResource(messages.getString("icon_publish")));
SVGIcon publishIcon = initSvgIcon(getClass().getResource(messages.getString("icon_publish")));
publishAction = new AbstractAction(messages.getString("publish_button"), publishIcon) {
public void actionPerformed(ActionEvent e) {
publishAction_actionPerformed(e);
}
};
//ImageIcon printIcon = new ImageIcon(getClass().getResource(messages.getString("icon_print")));
SVGIcon printIcon = initSvgIcon(getClass().getResource(messages.getString("icon_print")));
printListAction = new AbstractAction(messages.getString("print_button"), printIcon) {
public void actionPerformed(ActionEvent e) {
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
printArticleList();
setCursor(Cursor.getDefaultCursor());
}
};
printArticleAction = new AbstractAction(messages.getString("print_articleitem"), printIcon) {
public void actionPerformed(ActionEvent e) {
printArticleAction_actionPerformed(e);
}
};
//ImageIcon deleteIcon = new ImageIcon(getClass().getResource(messages.getString("icon_delete")));
SVGIcon deleteIcon = initSvgIcon(getClass().getResource(messages.getString("icon_delete")));
deleteAction = new AbstractAction(messages.getString("delete_articleitem"), deleteIcon) {
public void actionPerformed(ActionEvent e) {
deleteAction_actionPerformed(e);
}
};
sendMailToJournalistAction = new AbstractAction(messages.getString("sendmail_journalist"), null) {
public void actionPerformed(ActionEvent e) {
sendMailToJournalistAction_actionPerformed(e);
}
};
//ImageIcon exitIcon = new ImageIcon(getClass().getResource(messages.getString("icon_close")));
SVGIcon exitIcon = initSvgIcon(getClass().getResource(messages.getString("icon_close")));
exitAction = new AbstractAction(messages.getString("quit_button"), exitIcon) {
public void actionPerformed(ActionEvent e) {
exitAction_actionPerformed(e);
}
};
java.util.List<ArticleStatus> statuses = null;
try {
statuses = LoginContext.server.getArticleStatuses(LoginContext.sessionKey);
} catch (java.rmi.RemoteException e) {
log.error("Error getting statuses from server", e);
}
changeArticleStatusActions = new AbstractAction[statuses.size()];
for (int i = 0; i < changeArticleStatusActions.length; i++) {
changeArticleStatusActions[i] = new ChangeArticleStatusAction(statuses.get(i));
}
}
//Component initialization
private void jbInit() {
contentPane = (JPanel) this.getContentPane();
contentPane.setLayout(borderLayout1);
this.setSize(new Dimension(790, 573));
this.setTitle("Lister");
mainMenu.setText(messages.getString("main_menu"));
editMenu.setText(messages.getString("edit_menu"));
changeArticleStatusMenu.setText(messages.getString("changearticlestatus_menu"));
SVGIcon statusIcon = initSvgIcon(getClass().getResource(messages.getString("icon_changearticlestatus")));
changeArticleStatusMenu.setIcon(statusIcon);
//changeArticleStatusMenu.setIcon(new ImageIcon(getClass().getResource(messages.getString("icon_changearticlestatus"))));
groupMenuItem.setText(messages.getString("group_menuitem"));
groupMenuItem.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(ActionEvent e) {
groupMenuItem_actionPerformed(e);
}
});
prefsMenuItem.setText(messages.getString("prefs_menuitem"));
SVGIcon prefsIcon = initSvgIcon(getClass().getResource(messages.getString("icon_prefs")));
prefsMenuItem.setIcon(prefsIcon);
//prefsMenuItem.setIcon(new ImageIcon(getClass().getResource(messages.getString("icon_prefs"))));
prefsMenuItem.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(ActionEvent e) {
prefsMenuItem_actionPerformed(e);
}
});
columnsMenuItem.setText(messages.getString("columns_menuitem"));
JMenuItem quitMenuItem = new JMenuItem(messages.getString("quit_button"),
new ImageIcon(getClass().getResource(messages.getString("icon_close"))));
quitMenuItem.setToolTipText(messages.getString("tip_quit_button"));
quitMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(87, java.awt.event.KeyEvent.CTRL_MASK, false));
quitMenuItem.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(ActionEvent e) {
quitMenuItem_actionPerformed(e);
}
});
jMenuBar1.add(mainMenu);
jMenuBar1.add(editMenu);
editMenu.add(groupMenuItem);
//FIXME: This is now obsolete because of the new search panel.
//editMenu.add(prefsMenuItem);
JMenuItem newMenuItem = mainMenu.add(newAction);
newMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(78, java.awt.event.KeyEvent.CTRL_MASK, false));
JMenuItem aboutMenuItem = mainMenu.add(aboutAction);
aboutMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(73, java.awt.event.KeyEvent.CTRL_MASK, false));
JMenuItem editMenuItem = mainMenu.add(editAction);
editMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(69, java.awt.event.KeyEvent.CTRL_MASK, false));
JMenuItem deleteMenuItem = mainMenu.add(deleteAction);
deleteMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(68, java.awt.event.KeyEvent.CTRL_MASK, false));
JMenuItem publishMenuItem = mainMenu.add(publishAction);
publishMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(83, java.awt.event.KeyEvent.CTRL_MASK, false));
JMenuItem printMenuItem = mainMenu.add(printListAction);
printMenuItem.setMnemonic(messages.getString("print_menuitem").charAt(0));
printMenuItem.setText(messages.getString("print_menuitem"));
printMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(80, java.awt.event.KeyEvent.CTRL_MASK, false));
mainMenu.addSeparator();
mainMenu.add(quitMenuItem);
setJMenuBar(jMenuBar1);
searchPanel = new SearchPanel();
searchPanel.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
setCursor(new Cursor(Cursor.WAIT_CURSOR));
searchPanel_actionPerformed();
setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
}
});
JSplitPane splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
splitPane.setRightComponent(jScrollPane1);
splitPane.setLeftComponent(searchPanel);
contentPane.add(splitPane, BorderLayout.CENTER);
jScrollPane1.getViewport().add(articleList, null);
contentPane.add(topPanel, BorderLayout.NORTH);
topPanel.setLayout(new GridLayout(0, 1));
topPanel.add(toolBar);
popup = new JPopupMenu();
popup.add(editAction);
popup.add(aboutAction);
for (AbstractAction changeArticleStatusAction : changeArticleStatusActions) {
JMenuItem item = new JMenuItem(changeArticleStatusAction);
changeArticleStatusMenu.add(item);
}
popup.add(changeArticleStatusMenu);
popup.add(publishAction);
popup.add(deleteAction);
popup.add(printArticleAction);
sendMailTo = new JMenu(messages.getString("sendmail"));
//ImageIcon sendMailIcon = new ImageIcon(getClass().getResource(messages.getString("icon_sendmail")));
SVGIcon mailIcon = initSvgIcon(getClass().getResource(messages.getString("icon_sendmail")));
sendMailTo.setIcon(mailIcon);
sendMailTo.add(sendMailToJournalistAction);
popup.add(sendMailTo);
articleList.setPopupMenu(popup);
JButton tempButton;
tempButton = toolBar.add(refreshAction);
tempButton.setToolTipText((String) refreshAction.getValue(Action.NAME));
SVGIcon refreshIconDisabled = initSvgIcon(getClass().getResource(messages.getString("icon_refresh_disabled")));
tempButton.setDisabledIcon(refreshIconDisabled);
tempButton = toolBar.add(printListAction);
tempButton.setToolTipText((String) printListAction.getValue(Action.NAME));
SVGIcon printIconDisabled = initSvgIcon(getClass().getResource(messages.getString("icon_print_disabled")));
tempButton.setDisabledIcon(printIconDisabled);
toolBar.addSeparator();
tempButton = toolBar.add(newAction);
tempButton.setToolTipText((String) newAction.getValue(Action.NAME));
SVGIcon newIconDisabled = initSvgIcon(getClass().getResource(messages.getString("icon_new_disabled")));
tempButton.setDisabledIcon(newIconDisabled);
tempButton = toolBar.add(editAction);
tempButton.setToolTipText((String) editAction.getValue(Action.NAME));
SVGIcon editIconDisabled = initSvgIcon(getClass().getResource(messages.getString("icon_edit_disabled")));
tempButton.setDisabledIcon(editIconDisabled);
tempButton = toolBar.add(aboutAction);
tempButton.setToolTipText((String) aboutAction.getValue(Action.NAME));
SVGIcon aboutIconDisabled = initSvgIcon(getClass().getResource(messages.getString("icon_about_disabled")));
tempButton.setDisabledIcon(aboutIconDisabled);
tempButton = toolBar.add(publishAction);
tempButton.setToolTipText((String) publishAction.getValue(Action.NAME));
SVGIcon publishIconDisabled = initSvgIcon(getClass().getResource(messages.getString("icon_publish_disabled")));
tempButton.setDisabledIcon(publishIconDisabled);
toolBar.addSeparator();
tempButton = toolBar.add(exitAction);
tempButton.setToolTipText((String) exitAction.getValue(Action.NAME));
SVGIcon exitIconDisabled = initSvgIcon(getClass().getResource(messages.getString("icon_close_disabled")));
tempButton.setDisabledIcon(exitIconDisabled);
tempButton.setContentAreaFilled(true);
toolBar.setAlignmentX(0);
}
public void searchPanel_actionPerformed() {
searchTerm = searchPanel.getSearchTerm();
refreshArticles();
}
//Overridden so we can exit when window is closed
protected void processWindowEvent(WindowEvent e) {
super.processWindowEvent(e);
if (e.getID() == WindowEvent.WINDOW_CLOSING) {
dispose();
}
}
void newAction_actionPerformed(ActionEvent e) {
this.setCursor(new Cursor(Cursor.WAIT_CURSOR));
Article newArt = new Article();
java.util.List<Publication> publist = null;
try {
publist = LoginContext.server.getActivePublications(LoginContext.sessionKey);
}
catch (java.rmi.RemoteException ex) {
log.error("Exception getting active publications", ex);
}
if (publist != null && publist.size() > 0)
newArt.setPublication(publist.get(0));
ArticleDialog artDialog = new ArticleDialog(this, newArt);
artDialog.pack();
artDialog.setLocation(this.getLocation().x + 50, this.getLocation().y + 50);
this.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
artDialog.setVisible(true);
if (artDialog.dialogResult()) {
boolean saved = false;
Article article = artDialog.getArticle();
int articleID;
while (!saved) {
try {
articleID = LoginContext.server.saveArticle(article, LoginContext.sessionKey);
if (articleID > 0) { // Save was successful, and article got an ID
saved = true;
article.setId(articleID);
LoginContext.server.setCoJournalistsForArticle(articleID, artDialog.getCoJournalists(), LoginContext.sessionKey);
} else if (articleID == 0) { // Save was successful
saved = true;
}
} catch (Exception ee) {
log.error("Exception saving changed article", ee);
int d = JOptionPane.showConfirmDialog(this,
messages.getString("save_error_msg"),
messages.getString("save_error_caption"),
JOptionPane.YES_NO_OPTION,
JOptionPane.ERROR_MESSAGE);
if (d == JOptionPane.NO_OPTION) {
saved = true;
}
}
}
}
refreshArticles();
}
void openArticleInArtis(Article art) {
boolean canEdit = false;
try {
canEdit = LoginContext.server.hasArticlePermission(LoginContext.server.getUserID(LoginContext.sessionKey), ArticlePermissions.EDIT_ARTICLE, art.getId(), LoginContext.sessionKey);
} catch (RemoteException e1) {
log.error("Connection error", e1);
}
if (canEdit) {
this.setCursor(new Cursor(Cursor.WAIT_CURSOR));
ArticleLock lock = null;
try {
lock = LoginContext.server.getArticleLock(art.getId(), false, LoginContext.sessionKey);
} catch (RemoteException rme) {
log.error("Connection error", rme);
}
boolean lockIsMine = lock.getSessionKey().equals(LoginContext.sessionKey);
// Is this lock owned by user?
boolean isSameUser = false;
try {
isSameUser = lock.getUsername().equals(LoginContext.server.getSessionUser(LoginContext.sessionKey).getUsername());
} catch (RemoteException rme) {
log.error("Connection error", rme);
}
if (!lockIsMine && isSameUser) {
String hostname;
try {
InetAddress address = InetAddress.getByName(lock.getHost());
hostname = address.getHostName();
} catch (UnknownHostException e) {
hostname = lock.getHost();
}
String rawmessage = messages.getString("hijack_lock_msg");
Object[] args = {hostname};
String message = MessageFormat.format(rawmessage, args);
int d = JOptionPane.showConfirmDialog(this,
message,
messages.getString("hijack_lock_caption"),
JOptionPane.YES_NO_OPTION,
JOptionPane.ERROR_MESSAGE);
if (d == JOptionPane.YES_OPTION) {
try {
lock = LoginContext.server.getArticleLock(art.getId(), true, LoginContext.sessionKey);
} catch (RemoteException rme) {
log.error("Connecion error", rme);
}
lockIsMine = true;
}
if (d == JOptionPane.NO_OPTION) {
this.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
return;
}
}
Article fresh;
try {
fresh = LoginContext.server.getArticleByID(art.getId(), LoginContext.sessionKey);
}
catch (Exception e) {
log.error("Could not get article from server!", e);
JOptionPane.showMessageDialog(this,
"Sorry Mac. Could not get articlelock",
messages.getString("locked_error"),
JOptionPane.ERROR_MESSAGE);
return;
}
Artis anArtis;
//If article is already opened in an Artis window do not mess with its size and position
if (Artis.isOpen(fresh)) {
anArtis = Artis.fetchUniqueArtis(fresh, lock);
} else {
anArtis = Artis.fetchUniqueArtis(fresh, lock);
anArtis.setSize(new Dimension((int) (getSize().getWidth() + 100), (int) (getSize().getHeight() + 50)));
Point location = getLocation();
location.translate(20, 20);
anArtis.setLocation(location);
}
this.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
if(!lockIsMine) {
String hostname;
try {
InetAddress address = InetAddress.getByName(lock.getHost());
hostname = address.getHostName();
} catch(UnknownHostException e) {
hostname = lock.getHost();
}
String rawmessage = messages.getString("locked_error_preview");
Object[] args = {lock.getUsername(), hostname};
String message = MessageFormat.format(rawmessage, args);
log.info("Could not get lock on article. Locked by " + lock.getUsername() + " on " + hostname);
JOptionPane.showMessageDialog(this,
message,
messages.getString("locked_error"),
JOptionPane.WARNING_MESSAGE);
this.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
//Alt. version that keeps select and copy options, for locked view.
anArtis.disableAllEditors_butKeepOptionsRelevantToTextCopying();
anArtis.checkForLock();
}
else {
anArtis.startAutoSaver();
}
anArtis.setVisible(true);
} else { //not allowed to edit, must do some previewing instead. later.
}
}
void editAction_actionPerformed(ActionEvent e) {
if (articleList.hasSelection()) {
openArticleInArtis(articleList.getSelectedArticle());
}
}
void exitAction_actionPerformed(ActionEvent e) {
dispose();
}
void groupMenuItem_actionPerformed(ActionEvent e) {
GroupDialog groupDialog = new GroupDialog(this, articleList.getCurrentGrouper());
groupDialog.pack();
groupDialog.setVisible(true);
groupDialog.setVisible(false);
Grouper selectedGrouper = groupDialog.getSelectedGrouper();
Comparator selectedComparator = groupDialog.getSelectedComparator();
if (!groupDialog.wasCanceled())
articleList.regroup(selectedGrouper, selectedComparator);
validate();
articleList.repaint();
}
void prefsMenuItem_actionPerformed(ActionEvent e) {
PrefsDialog pd = new PrefsDialog(this, prefs);
pd.setVisible(true);
if (pd.okResult()) {
Properties changed = pd.getChangedPreferences();
Enumeration en = changed.keys();
while (en.hasMoreElements()) {
String key = en.nextElement().toString();
String value = changed.getProperty(key);
prefs.put(key, value);
try {
LoginContext.server.savePreference(PREFS_DOMAIN, key, value, LoginContext.sessionKey);
} catch (Exception ex) {
log.error("Unable to save pref: " + key + "=" + value, ex);
}
}
}
}
void quitMenuItem_actionPerformed(ActionEvent e) {
dispose();
}
void articleList_stateChanged(ChangeEvent e) {
boolean canEdit = false;
try {
canEdit = LoginContext.server.hasArticlePermission(LoginContext.server.getUserID(LoginContext.sessionKey), ArticlePermissions.EDIT_ARTICLE, articleList.getSelectedArticle().getId(), LoginContext.sessionKey);
} catch (RemoteException e1) {
log.error("Connection error", e1);
}
editAction.setEnabled(canEdit);
aboutAction.setEnabled(canEdit);
printArticleAction.setEnabled(canEdit);
changeArticleStatusMenu.setEnabled(canEdit);
// All users can publish
publishAction.setEnabled(true);
// All users can send email
sendMailTo.setEnabled(true);
// sjekker om brukeren har lov til å slette
try {
boolean canDelete = LoginContext.server.hasArticlePermission(LoginContext.server.getUserID(LoginContext.sessionKey), ArticlePermissions.LEGACY_DELETE_ARTICLE, articleList.getSelectedArticle().getId(), LoginContext.sessionKey);
deleteAction.setEnabled(canDelete);
}
catch (Exception ex) {
log.error("Error check delete privilege", ex);
}
}
void deleteAction_actionPerformed(ActionEvent e) {
Article art = articleList.getSelectedArticle();
boolean choice = displayDeleteWarning();
if (choice) {
try {
if (LoginContext.server.hasArticlePermission(LoginContext.server.getUserID(LoginContext.sessionKey), ArticlePermissions.LEGACY_DELETE_ARTICLE, art.getId(), LoginContext.sessionKey))
{
LoginContext.server.deleteArticle(art.getId(), LoginContext.sessionKey);
refreshArticles();
}
} catch (Exception jeppz) {
log.error("Error deleting article", jeppz);
}
}
}
void sendMailToJournalistAction_actionPerformed(ActionEvent e) {
setCursor(new Cursor(Cursor.WAIT_CURSOR));
Article art = articleList.getSelectedArticle();
String[] replaceWith = new String[8];
try {
Person u = LoginContext.server.getSessionUser(LoginContext.sessionKey);
replaceWith[0] = u.getName();
replaceWith[1] = u.getEmailAddress();
}
catch (java.rmi.RemoteException re) {
log.error("Could not get user data from server", re);
}
replaceWith[2] = art.getJournalist().getName();
replaceWith[3] = art.getJournalist().getEmailAddress();
replaceWith[4] = art.getName();
replaceWith[5] = art.getArticleStatus().getName();
replaceWith[6] = Integer.toString(art.getCurrentNumberOfCharacters());
replaceWith[7] = (art.getPublication() != null) ? art.getPublication().getName() : "Unknown";
String url;
try {
url = LoginContext.server.getWebXMLRoot(LoginContext.sessionKey);
url += "/templates/listermail.template";
}
catch (java.rmi.RemoteException re) {
log.error("Error getting webxmlroot", re);
return;
}
MailDialog dialog = new MailDialog(this, "", false);
dialog.loadTemplate(url, replaceWith);
dialog.setFromFieldEditable(false);
dialog.setToFieldEditable(true);
dialog.pack();
dialog.setVisible(true);
setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
}
void publishAction_actionPerformed(ActionEvent e) {
if (articleList.hasSelection()) {
//fetch a fresh article from the server. In case it has been edited since last refresh of lister
Article freshArticle = null;
try {
freshArticle = LoginContext.server.getArticleByID(articleList.getSelectedArticle().getId(), LoginContext.sessionKey);
}
catch (Exception ex) {
log.error("Could not get article from server!", ex);
}
PublishDialog pd = new PublishDialog(this, freshArticle);
pd.setLastPublishedToDir(lastPublishedToDir);
Point p = getLocation();
p.x += 30;
p.y += 30;
pd.setVisible(true);
}
}
void changeArticleStatus_actionPerformed(ActionEvent e, ArticleStatus status) {
Article art = articleList.getSelectedArticle();
if (Artis.isOpen(art)) {
JOptionPane.showMessageDialog(this,
messages.getString("about_error_long"),
messages.getString("about_error"),
JOptionPane.ERROR_MESSAGE);
return;
}
setCursor(new Cursor(Cursor.WAIT_CURSOR));
ArticleLock lock = null;
try {
lock = LoginContext.server.getArticleLock(art.getId(), false, LoginContext.sessionKey);
} catch (RemoteException re) {
log.error("Connection error", re);
}
boolean lockIsMine = lock.getSessionKey().equals(LoginContext.sessionKey);
// Is this lock owned by user?
boolean isSameUser = false;
try {
isSameUser = lock.getUsername().equals(LoginContext.server.getSessionUser(LoginContext.sessionKey).getUsername());
} catch (RemoteException re) {
log.error("Connection error", re);
}
if (!lockIsMine && isSameUser) { // The lock is owned by this user, but not this session. Grab lock?
String hostname;
try {
InetAddress address = InetAddress.getByName(lock.getHost());
hostname = address.getHostName();
} catch (UnknownHostException uhe) {
hostname = lock.getHost();
}
String rawmessage = messages.getString("hijack_lock_msg");
Object[] args = {hostname};
String message = MessageFormat.format(rawmessage, args);
int d = JOptionPane.showConfirmDialog(this,
message,
messages.getString("hijack_lock_caption"),
JOptionPane.YES_NO_OPTION,
JOptionPane.ERROR_MESSAGE);
if (d == JOptionPane.YES_OPTION) {
try {
lock = LoginContext.server.getArticleLock(art.getId(), true, LoginContext.sessionKey);
} catch (RemoteException rme) {
log.error("Connection error", rme);
}
lockIsMine = true;
}
if (d == JOptionPane.NO_OPTION) {
this.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
return;
}
}
if (lockIsMine) { // Everything in order. Change status.
try {
//It is crusial that we get a fresh copy of the article after we have aquired a write lock
art = LoginContext.server.getArticleByID(art.getId(), LoginContext.sessionKey);
} catch (Exception e1) {
log.error("Sorry could not get a fresh article", e1);
JOptionPane.showMessageDialog(this,
"Sorry Mac. Could not get articlelock",
messages.getString("locked_error"),
JOptionPane.ERROR_MESSAGE);
return;
}
art.setArticleStatus(status);
boolean saved = false;
while (!saved) {
try {
Article hack = (Article) art.clone();
LoginContext.server.saveArticle(hack, LoginContext.sessionKey);
saved = true;
} catch (Exception ee) {
log.error("Exception saving changed articlestatus", ee);
int d = JOptionPane.showConfirmDialog(this,
messages.getString("save_error_msg"),
messages.getString("save_error_caption"),
JOptionPane.YES_NO_OPTION,
JOptionPane.ERROR_MESSAGE);
if (d == JOptionPane.NO_OPTION) {
saved = true;
}
}
}
try {
LoginContext.server.releaseArticleLock(art.getId(), LoginContext.sessionKey);
} catch (Exception ex) {
log.error("Could not release articlelock", ex);
}
refreshArticles();
} else {
String hostname;
try {
InetAddress address = InetAddress.getByName(lock.getHost());
hostname = address.getHostName();
} catch (UnknownHostException uhe) {
hostname = lock.getHost();
}
String user = lock.getUsername();
try {
user = LoginContext.server.getUserByUsername(lock.getUsername(), LoginContext.sessionKey).getFullName();
} catch (NoAccessException nae) {
log.error("Could not get person holding lock", nae);
}
String rawmessage = messages.getString("locked_error_long");
Object[] args = {user, hostname};
String message = MessageFormat.format(rawmessage, args);
log.info("Could not get lock on article. Locked by {} on {}", lock.getUsername(), hostname);
JOptionPane.showMessageDialog(this,
message,
messages.getString("locked_error"),
JOptionPane.ERROR_MESSAGE);
}
this.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
}
void printArticleAction_actionPerformed(ActionEvent e) {
Article article;
try {
article = LoginContext.server.getArticleByID(articleList.getSelectedArticle().getId(), LoginContext.sessionKey);
} catch (RemoteException e1) {
log.error("Connection error", e1);
return;
}
if (!article.hasText()) {
JOptionPane.showMessageDialog(this, messages.getString("parse_err_edit_art"), messages.getString("parse_err"), JOptionPane.ERROR_MESSAGE);
return;
}
if (article.getDocument() == null) {
if (!article.parseText()) {
JOptionPane.showMessageDialog(this, messages.getString("parse_err_contact_adm"), messages.getString("parse_err"), JOptionPane.ERROR_MESSAGE);
return;
}
}
setCursor(new Cursor(Cursor.WAIT_CURSOR));
FOPPrintPublisher fpp = new FOPPrintPublisher();
Properties p = getPrintProperties();
if (p == null) {
setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
return;
}
fpp.setTransformerProperties(p);
try {
fpp.publish(article, null, PublishingMediaEnum.PDF);
} catch (Exception ex) {
log.error("Error during transformation.", ex);
JOptionPane.showMessageDialog(this, messages.getString("transform_error_general"), messages.getString("transform_error_captition"), JOptionPane.ERROR_MESSAGE);
}
setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
}
public Properties getPrintProperties() {
PrintDialog printDialog = new PrintDialog(this, ResourceBundle.getBundle("org.pegadi.artis.ArtisStrings"));
printDialog.pack();
printDialog.setVisible(true);
if (!printDialog.wasAccepted()) // Was cancel pressed?
return null;
return printDialog.getPrintProperties();
}
public void updateArticleList() {
articleList.revalidate();
articleList.repaint();
}
public void setLastPublishedToDir(String lastPublishedToDir) {
this.lastPublishedToDir = lastPublishedToDir;
}
protected void changeArticle(Article art) {
if (Artis.isOpen(art)) {
JOptionPane.showMessageDialog(this,
messages.getString("about_error_long"),
messages.getString("about_error"),
JOptionPane.ERROR_MESSAGE);
return;
}
this.setCursor(new Cursor(Cursor.WAIT_CURSOR));
ArticleLock lock = null;
try {
lock = LoginContext.server.getArticleLock(art.getId(), false, LoginContext.sessionKey);
} catch (RemoteException re) {
log.error("Connection error", re);
}
boolean lockIsMine = lock.getSessionKey().equals(LoginContext.sessionKey);
// Is this lock owned by user?
boolean isSameUser = false;
try {
isSameUser = lock.getUsername().equals(LoginContext.server.getSessionUser(LoginContext.sessionKey).getUsername());
} catch (RemoteException re) {
log.error("Connection error", re);
}
if (!lockIsMine && isSameUser) { // The lock is owned by this user, but not this session. Grab lock?
String hostname;
try {
InetAddress address = InetAddress.getByName(lock.getHost());
hostname = address.getHostName();
} catch (UnknownHostException uhe) {
hostname = lock.getHost();
}
String rawmessage = messages.getString("hijack_lock_msg");
Object[] args = {hostname};
String message = MessageFormat.format(rawmessage, args);
int d = JOptionPane.showConfirmDialog(this,
message,
messages.getString("hijack_lock_caption"),
JOptionPane.YES_NO_OPTION,
JOptionPane.ERROR_MESSAGE);
if (d == JOptionPane.YES_OPTION) {
try {
lock = LoginContext.server.getArticleLock(art.getId(), true, LoginContext.sessionKey);
} catch (RemoteException rme) {
log.error("Connection error", rme);
}
lockIsMine = true;
}
if (d == JOptionPane.NO_OPTION) {
this.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
return;
}
}
try {
//It is crusial that we get a fresh copy of the article after we have aquired a write lock
art = LoginContext.server.getArticleByID(art.getId(), LoginContext.sessionKey);
} catch (Exception e1) {
log.error("Sorry could not get a fresh article", e1);
JOptionPane.showMessageDialog(this,
"Sorry Mac. Could not get articlelock",
messages.getString("locked_error"),
JOptionPane.ERROR_MESSAGE);
return;
}
ArticleDialog artDialog = new ArticleDialog(this, art);
artDialog.pack();
artDialog.setLocation(this.getLocation().x + 50, this.getLocation().y + 50);
this.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
if (lockIsMine) { // Everything in order. Change article.
artDialog.setVisible(true);
setCursor(new Cursor(Cursor.WAIT_CURSOR));
if (artDialog.dialogResult()) {
boolean saved = false;
while (!saved) {
try {
Article hack = (Article) artDialog.getArticle().clone();
LoginContext.server.saveArticle(hack, LoginContext.sessionKey);
LoginContext.server.setCoJournalistsForArticle(hack.getId(), artDialog.getCoJournalists(), LoginContext.sessionKey);
saved = true;
} catch (Exception ee) {
log.error("Exception saving changed article", ee);
int d = JOptionPane.showConfirmDialog(this,
messages.getString("save_error_msg"),
messages.getString("save_error_caption"),
JOptionPane.YES_NO_OPTION,
JOptionPane.ERROR_MESSAGE);
if (d == JOptionPane.NO_OPTION) {
saved = true;
}
}
}
}
// Clean up, release articlelock.
try {
LoginContext.server.releaseArticleLock(art.getId(), LoginContext.sessionKey);
} catch (Exception ex) {
log.error("Could not release articlelock", ex);
}
refreshArticles();
} else { // Article locked by someone else. Changing not allowed.
String hostname;
try {
InetAddress address = InetAddress.getByName(lock.getHost());
hostname = address.getHostName();
} catch (UnknownHostException uhe) {
hostname = lock.getHost();
}
String user = lock.getUsername();
try {
user = LoginContext.server.getUserByUsername(lock.getUsername(), LoginContext.sessionKey).getFullName();
} catch (NoAccessException e) {
log.error("Could not get person holding lock", e);
}
String rawmessage = messages.getString("locked_error_preview");
Object[] args = {user, hostname};
String message = MessageFormat.format(rawmessage, args);
log.info("Could not get lock on article. Locked by {} on {}", lock.getUsername(), hostname);
JOptionPane.showMessageDialog(this,
message,
messages.getString("locked_error"),
JOptionPane.WARNING_MESSAGE);
artDialog.disableEditing();
artDialog.setVisible(true);
}
setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
}
public void closeAllArtis() {
Object[] col = Artis.openArtises.values().toArray();
for (Object aCol : col) {
Artis art = (Artis) aCol;
try {
LoginContext.server.releaseArticleLock(art.getArticle().getId(), LoginContext.sessionKey);
} catch (Exception e) {
log.error("Error releasing articlelock", e);
}
art.dispose();
}
}
void aboutAction_actionPerformed(ActionEvent e) {
changeArticle(articleList.getSelectedArticle());
}
protected void articleList_actionPerformed(ActionEvent e) {
Article art = articleList.getSelectedArticle();
if (e.getID() == 0) {
openArticleInArtis(art);
} else // "About" if ctrl is down
changeArticle(art);
}
/**
* Prints the current list.
*/
protected void printArticleList() {
try {
PrinterJob pj = PrinterJob.getPrinterJob();
if (!pj.printDialog()) {
log.info("Printing cancelled by user");
return;
}
TransformerFactory tFactory = TransformerFactory.newInstance();
SAXTransformerFactory factory = (SAXTransformerFactory) tFactory;
String url;
try {
url = LoginContext.server.getWebXMLRoot(LoginContext.sessionKey);
url += "/stylesheets/articlelist2fo.xsl";
}
catch (java.rmi.RemoteException re) {
log.error("Error getting webxmlroot", re);
JOptionPane.showMessageDialog(this, messages.getString("parse_err_contact_adm"), messages.getString("parse_err"), JOptionPane.ERROR_MESSAGE);
return;
}
TransformerHandler transformerHandler = factory.newTransformerHandler(new StreamSource(url));
FopFactory fopFactory = FopFactory.newInstance();
FOUserAgent foUserAgent = fopFactory.newFOUserAgent();
FOPPrintRenderer renderer = new FOPPrintRenderer(pj);
renderer.setUserAgent(foUserAgent);
renderer.setPreviewDialogDisplayed(false);
foUserAgent.setRendererOverride(renderer);
Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, foUserAgent);
transformerHandler.setResult(new SAXResult(fop.getDefaultHandler()));
articleList.generateArticleListAsXML(transformerHandler);
}
catch (Exception e) {
log.error("Exception during printing", e);
JOptionPane.showMessageDialog(this,
messages.getString("print_error"),
messages.getString("print_error_caption"),
JOptionPane.ERROR_MESSAGE);
}
}
private class ChangeArticleStatusAction extends AbstractAction {
private ArticleStatus status;
public ChangeArticleStatusAction(ArticleStatus status) {
super(status.getName());
this.status = status;
}
public void actionPerformed(ActionEvent e) {
changeArticleStatus_actionPerformed(e, status);
}
}
}