package org.pegadi.disposal;
import org.pegadi.artis.Artis;
import org.pegadi.lister.ArticleDialog;
import org.pegadi.model.*;
import org.pegadi.server.NoAccessException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.rmi.RemoteException;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.ResourceBundle;
public class AddArticlesDialog extends JDialog {
DispPage page;
Disp disp;
JFrame owner;
Publication pub;
List<Article> articles = new ArrayList<Article>();
List<Article> containedArticles = new ArrayList<Article>();
PageTable table;
JComboBox relevantbox, containBox;
JButton addButton, removeButton;
ResourceBundle messages, editArticle;
Logger log = LoggerFactory.getLogger(getClass());
public AddArticlesDialog(DispPage page, Disp disp, PageTable table, Publication pub, JFrame owner) {
super(owner);
setModal(true);
this.page = page;
this.disp = disp;
this.table = table;
this.owner = owner;
this.pub = pub;
ImageIcon icon = new ImageIcon(getClass().getResource("/images/pegadi.gif"));
setIconImage(icon.getImage());
messages = ResourceBundle.getBundle("org.pegadi.publicationcontrol.PublicationControlStrings");
editArticle = ResourceBundle.getBundle("org.pegadi.lister.ListerStrings");
setTitle(messages.getString("addarticles_button"));
JPanel mainpanel = new JPanel(new GridBagLayout());
GridBagConstraints c;
try {
articles = LoginContext.server.getArticlesByDispID(disp.getId(), LoginContext.sessionKey);
} catch (NoAccessException e) {
log.error("error - no access to articles from DB", e);
}
relevantbox = new JComboBox(articles.toArray(new Article[articles.size()]));
if(page != null) {
try {
containedArticles = LoginContext.server.getArticlesByPageID(page.getId(), LoginContext.sessionKey);
} catch (NoAccessException e) {
log.error("error - no access to containedArticles", e);
}
containBox = new JComboBox(containedArticles.toArray(new Article[containedArticles.size()]));
}
relevantbox.setMaximumRowCount(30);
addButton = new JButton(messages.getString("add_button"));
removeButton = new JButton(messages.getString("remove_button"));
JPanel buttonPanel = new JPanel();
JButton closeBtn = new JButton(messages.getString("action_close"));
JButton newButton = new JButton(messages.getString("newarticle_button"));
JButton editButton = new JButton(messages.getString("article_edit"));
buttonPanel.add(newButton);
buttonPanel.add(editButton);
buttonPanel.add(closeBtn);
newButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
newArticle();
fillRelevantList();
}
});
editButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
editArticle();
}
});
closeBtn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
dispose();
}
});
addButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
addArticle();
}
});
removeButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
removeArticle();
}
});
JLabel label;
if(page != null) {
label = new JLabel(messages.getString("addarticles_button") + ": " + page.getPageNumber());
} else {
label = new JLabel(messages.getString("addarticles_button"));
}
JPanel optionsPanel = new JPanel(new GridBagLayout());
c = new GridBagConstraints();
c.insets = new Insets(10, 0, 0, 10);
c.anchor = GridBagConstraints.LINE_START;
c.fill = GridBagConstraints.HORIZONTAL;
c.weightx = 1;
optionsPanel.add(relevantbox, c);
c.gridy = 1;
if(page != null) {
optionsPanel.add(containBox, c);
}
c.gridx = 1;
c.gridy = 0;
c.weightx = 0;
if(page != null) {
optionsPanel.add(addButton, c);
c.gridy = 1;
optionsPanel.add(removeButton, c);
}
// To mainpanel
c = new GridBagConstraints();
c.anchor = GridBagConstraints.LINE_START;
c.insets = new Insets(20, 10, 5, 0);
mainpanel.add(label, c);
c.gridy = 1;
c.weightx = 1;
c.fill = GridBagConstraints.HORIZONTAL;
c.insets = new Insets(0, 20, 5, 10);
mainpanel.add(optionsPanel, c);
c.gridy = 2;
c.fill = GridBagConstraints.NONE;
c.anchor = GridBagConstraints.LINE_END;
c.insets = new Insets(10, 0, 10, 20);
mainpanel.add(buttonPanel, c);
add(mainpanel);
pack();
setLocationRelativeTo(owner);
setVisible(true);
}
private void fillRelevantList() {
}
public void addArticle() {
if(relevantbox.getSelectedIndex() == -1) return;
Article article = (Article) relevantbox.getSelectedItem();
for(Article oldArticle : page.getArticles()) {
if(oldArticle.getId() == article.getId()) return;
}
try {
LoginContext.server.addArticleToPage(page, article, LoginContext.sessionKey);
containBox.addItem(article);
page.getArticles().add(article);
table.refresh();
} catch (NoAccessException e) {
log.error("error - no access to addarticletopage", e);
}
}
public void removeArticle() {
if(containBox.getSelectedIndex() == -1) return;
Article article = (Article) containBox.getSelectedItem();
try {
LoginContext.server.removeArticleFromPAge(page, article, LoginContext.sessionKey);
containBox.removeItem(article);
table.refresh();
for(Article oldArticle : page.getArticles()) {
if(oldArticle.getId() == article.getId()) {
page.getArticles().remove(oldArticle);
return;
}
}
} catch (NoAccessException e) {
log.error("error - no access to removeArticleFromPage", e);
}
}
private void newArticle() {
Article newArt = new Article();
newArt.setPublication(pub);
ArticleDialog artDialog = new ArticleDialog(owner, newArt);
artDialog.pack();
artDialog.setLocationRelativeTo(this);
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) {
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;
}
}
}
relevantbox.addItem(article);
}
}
private void editArticle() {
if(relevantbox.getSelectedIndex() == -1) return;
Article art = (Article) relevantbox.getSelectedItem();
if (Artis.isOpen(art)) {
JOptionPane.showMessageDialog(this,
messages.getString("about_error_long"),
messages.getString("about_error"),
JOptionPane.ERROR_MESSAGE);
return;
}
ArticleLock lock = null;
try {
lock = LoginContext.server.getArticleLock(art.getId(), false, LoginContext.sessionKey);
} catch (RemoteException re) {
log.error("Error fetching lock", 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("RemoteException", 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("RemoteException", rme);
}
lockIsMine = true;
}
if (d == JOptionPane.NO_OPTION) {
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);
log.error("Error getting article", e1);
return;
}
ArticleDialog artDialog = new ArticleDialog(owner, art);
artDialog.pack();
artDialog.setLocation(this.getLocation().x + 50, this.getLocation().y + 50);
if (lockIsMine) { // Everything in order. Change article.
artDialog.setVisible(true);
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);
}
} 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 rawmessage = messages.getString("locked_error_preview");
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);
}
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);
}
}
}