org.pegadi.server.article.ArticleServerImpl.java Source code

Java tutorial

Introduction

Here is the source code for org.pegadi.server.article.ArticleServerImpl.java

Source

/**
 * 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.
 */
package org.pegadi.server.article;

import no.dusken.common.model.Person;
import org.pegadi.articlesearch.JournalistTerm;
import org.pegadi.articlesearch.PhotographerTerm;
import org.pegadi.articlesearch.StatusTerm;
import org.pegadi.model.Article;
import org.pegadi.server.*;
import org.pegadi.server.user.UserServer;
import org.pegadi.sqlsearch.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.jdbc.core.PreparedStatementCreator;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.jdbc.support.GeneratedKeyHolder;
import org.springframework.jdbc.support.KeyHolder;
import org.springframework.stereotype.Service;
import org.w3c.dom.*;

import javax.sql.DataSource;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import java.io.*;
import java.nio.charset.Charset;
import java.sql.*;
import java.text.MessageFormat;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.Date;

import static org.apache.commons.lang.StringUtils.isNotBlank;
import static org.pegadi.util.PersonUtils.getInitials;

/**
 * @author Jrgen Binningsb <jb@underdusken.no>
 * @author Marvin B. Lillehaug <lillehau@underdusken.no>
 */
@Service
public class ArticleServerImpl implements ArticleServer {

    private NamedParameterJdbcTemplate template;

    private ArticleRowMapper mapper = new ArticleRowMapper();

    /**
     * The location for backup XML files.
     */
    protected File backupLocation;

    /**
     * The location to articles in html
     */
    protected File articleLocation;

    /**
     * The location to xml files
     */
    protected File xmlLocation;

    /**
     * The URL to the articles saved in @see articleLocation
     */
    protected String webXml;

    /**
     * An instance of a UserServer - needed to create the users connected
     * to this article
     */
    private UserServer userServer;

    /**
     * An instance of a PublicationServerImpl. Needed to create the <code>Publication</code>s
     * connected to the articles.
     */
    private PublicationServer publicationServer;

    private ArticleTypeServer articleTypeServer;

    private ArticleStatusServer articleStatusServer;

    private SectionServer sectionServer;

    private final Logger log = LoggerFactory.getLogger(getClass());
    private String webBase;
    private String webPath;

    @Autowired
    private DataSourceBasedLimitResultsUtil limitResultsUtil;

    public ArticleServerImpl() {
    }

    public void setDataSource(DataSource dataSource) {
        template = new NamedParameterJdbcTemplate(dataSource);
    }

    public void setUserServer(UserServer userServer) {
        this.userServer = userServer;
    }

    public void setPublicationServer(PublicationServer publicationServer) {
        this.publicationServer = publicationServer;
    }

    public void setArticleTypeServer(ArticleTypeServer articleTypeServer) {
        this.articleTypeServer = articleTypeServer;
    }

    public void setSectionServer(SectionServer sectionServer) {
        this.sectionServer = sectionServer;
    }

    public void init() {

        log.debug("Backuplocation is: " + backupLocation);

        if (!backupLocation.exists() || !backupLocation.isDirectory())
            backupLocation.mkdirs();

        if (!xmlLocation.exists() || !xmlLocation.isDirectory())
            xmlLocation.mkdir();
        setWebXml(webBase + webPath + webXml);
    }

    public boolean canEdit(Person person, int artId) {
        // security-rules: the journalist can edit the article
        //                 the photographer can edit the article. FIXME: He or she should only
        //                     be allowed to view the article.
        //                 the editor-in-chiefs can edit the article
        //                 the proof-readers can edit the article
        //                 co-journalists can only edit the xml, not permissions

        Article article = getArticleByID(person, artId);
        try {
            if (userServer.isGod(person)) {
                return true;
            } else if (article.getPhotographer() != null
                    && person.getUsername().equals(article.getPhotographer().getUsername())) {
                return true;
            } else if (article.getJournalist() != null
                    && person.getUsername().equals(article.getJournalist().getUsername())) {
                return true;
            } else if (userServer.hasRole(19, person.getId())) { //proof-reader
                return true;
            } else {
                Map<String, Object> parameters = new HashMap<String, Object>();
                parameters.put("article", artId);
                parameters.put("journalist", person.getUsername());
                int count = template.queryForInt(
                        "SELECT count(*) FROM CoJournalists WHERE refArticle=:article AND refJournalist=:journalist",
                        parameters);
                return count > 0;
            }
        } catch (Exception e) {
            log.error("getArticleByID: error setting article security: ", e);
            return false;
        }
    }

    public boolean canDelete(Person person, int artID) {
        Article art;
        try {
            art = getArticleByID(person, artID);
        } catch (Exception ee) {
            log.error("canDelete: exception getting article", ee);
            return false;
        }

        boolean isOwner = art.getJournalist() != null && art.getJournalist().getUsername() != null
                && art.getJournalist().getUsername().equals(person.getUsername());
        return userServer.isGod(person) || isOwner;
    }

    public List<Article> getArticlesBySearchTerm(SearchTerm searchTerm) {
        SearchTerm privateTerm = new OrTerm(new NotTerm(new StatusTerm(7)));

        return searchWithPrivateArticleTerm(searchTerm, privateTerm);
    }

    public List<Article> getArticlesBySearchTerm(Person person, SearchTerm searchTerm) {

        // Ensure private articles are not shown
        SearchTerm privateTerm = new OrTerm(new NotTerm(new StatusTerm(7)),
                new OrTerm(new JournalistTerm(person), new PhotographerTerm(person)));

        return searchWithPrivateArticleTerm(searchTerm, privateTerm);
    }

    private List<Article> searchWithPrivateArticleTerm(SearchTerm searchTerm, SearchTerm privateTerm) {
        final AndTerm andTerm = new AndTerm(searchTerm, privateTerm);

        andTerm.addTerm(new SearchTerm() {
            public String whereClause() {
                return "(Article.refArticleType=0 OR Article.refArticleType=ArticleType.ID)";
            }

            public List<String> getTables() {
                return Arrays.asList("Article", "ArticleType");
            }

        });
        andTerm.addTerm(new SearchTerm() {
            public String whereClause() {
                return "(Article.refStatus=0 OR Article.refStatus=ArticleStatus.ID)";
            }

            public List<String> getTables() {
                return Arrays.asList("Article", "ArticleStatus");
            }

        });
        andTerm.addTerm(new SearchTerm() {
            public String whereClause() {
                return "(Article.refSection=0 OR Article.refSection=Section.ID)";
            }

            public List<String> getTables() {
                return Arrays.asList("Article", "Section");
            }

        });
        andTerm.addTerm(new SearchTerm() {
            public String whereClause() {
                return "(Article.refPublication=Publication.ID)";
            }

            public List<String> getTables() {
                return Arrays.asList("Article", "Publication");
            }

        });
        andTerm.setSelectDistinct(true);
        String query = andTerm.getQuery("Article.ID, Article.name, Article.refJournalist, "
                + "Article.refPhotographer, Article.description, Article.characterCount, "
                + "Article.wantedCharacters, Article.wantedPages, Article.lastSaved, Article.articlexml, "
                + "Article.refPublication, Article.refArticleType, " + "Article.refStatus, Article.refSection");

        log.debug("Query is: {}", query);

        return template.query(query, Collections.<String, Object>emptyMap(), mapper);
    }

    @Override
    public List<Article> getArticlesBySearchTerm(SearchTerm searchTerm, Integer count, Integer offset) {
        SearchTerm limitClauseToSearchTerm = limitResultsUtil.createLimitClauseToSearchTerm(searchTerm, count,
                offset);
        String queryString = limitClauseToSearchTerm.getQuery("Article.*");
        log.debug("Query is: {}", queryString);

        return template.query(queryString, Collections.<String, Object>emptyMap(), mapper);
    }

    /**
     * Deletes an article from the database
     *
     * @param articleID the <code>Article</code> object to be deleted
     * @return <code>true</code> if the delete was successful.
     */
    public boolean deleteArticle(int articleID) {

        Map<String, Integer> parameters = Collections.singletonMap("id", articleID);
        template.update("INSERT INTO DeletedArticle SELECT * from Article WHERE id = :id", parameters);
        log.info("Copied article {} to DeletedArticle", articleID);
        template.update("DELETE FROM Article WHERE ID=:id", parameters);
        template.update("DELETE FROM CoJournalists WHERE refarticle=:id", parameters);

        log.info("Deleted article " + articleID);

        return true;
    }

    /**
     * Saves a new or updates an existing article. If the articleID is 0, a new article is inserted into the database
     * and the new ID is returned. Else the article will be updated. This method will not save or modyify
     * the article text. The exception is when the article type changes.
     *
     * @param article The article to save.
     * @return New articleID if new article is created or 0 for successful save of existing article. Returnvalue less than 0
     *         means that something was wrong, and the article was not successfully saved.
     */
    public int saveArticle(final Article article) {
        if (article == null) { // huh - no article?
            log.error("error - can't save a non-exixting article...");
            return -1;
        } else {
            log.info("Saving article with ID=" + article.getId());

            final String journalist = article.getJournalist() != null ? article.getJournalist().getUsername()
                    : null;
            final String photographer = article.getPhotographer() != null ? article.getPhotographer().getUsername()
                    : null;
            final int publication = article.getPublication() != null ? article.getPublication().getId() : 0;
            final int articleType = article.getArticleType() != null ? article.getArticleType().getId() : 0;
            final String text = article.getText() != null ? article.getText() : "";
            final int department = article.getSection() != null ? article.getSection().getId() : 0;
            final int articlestatus = article.getArticleStatus() != null ? article.getArticleStatus().getId() : 1;
            if (article.getId() == 0) { // no ID means insert a new article

                KeyHolder keyHolder = new GeneratedKeyHolder();
                final String insert = "INSERT INTO Article (name, refJournalist, refPhotographer, refPublication, description, refArticleType, wantedCharacters, wantedPages,articlexml, refSection, refStatus, lastSaved) VALUES (?,?,?,?,?,?,?,?,?,?,?,?)";

                template.getJdbcOperations().update(new PreparedStatementCreator() {
                    public PreparedStatement createPreparedStatement(Connection connection) throws SQLException {
                        PreparedStatement ps = connection.prepareStatement(insert, new String[] { "ID" });
                        ps.setString(1, article.getName());
                        ps.setString(2, journalist);
                        ps.setString(3, photographer);
                        ps.setInt(4, publication);
                        ps.setString(5, article.getDescription());
                        ps.setInt(6, articleType);
                        ps.setInt(7, article.getWantedNumberOfCharacters());
                        ps.setFloat(8, article.getWantedNumberOfPages());
                        ps.setString(9, text);
                        ps.setInt(10, department);
                        ps.setInt(11, articlestatus);
                        ps.setTimestamp(12, new Timestamp((new Date()).getTime()));
                        return ps;
                    }
                }, keyHolder);
                int articleId = keyHolder.getKey().intValue();
                log.info("Saved a new article, and gave it ID={}", articleId);
                return articleId;
            } else {
                // Save existing article
                int articletypeOld = template.queryForInt("SELECT refArticleType FROM Article WHERE ID=:id",
                        Collections.singletonMap("id", article.getId()));

                if (article.getArticleType() != null) {
                    int AT = article.getArticleType().getId();
                    // Important to do this before the article text is set
                    if (AT != articletypeOld && article.hasText()) {
                        changeArticleType(article, AT);
                    }
                }
                doBackup(article.getId(), article.getText());

                Map<String, Object> parameters = new HashMap<String, Object>();
                parameters.put("name", article.getName());
                parameters.put("text", article.getText());
                parameters.put("department", department);
                parameters.put("journalist", journalist);
                parameters.put("photographer", photographer);
                parameters.put("publication", publication);
                parameters.put("description", article.getDescription());
                parameters.put("wantedNumbeOfCharacters", article.getWantedNumberOfCharacters());
                parameters.put("wantedNumberOfPages", article.getWantedNumberOfPages());
                parameters.put("articleType", articleType);
                parameters.put("articleStatus", articlestatus);
                parameters.put("lastSaved", new Timestamp((new Date()).getTime()));
                parameters.put("id", article.getId());
                template.update("UPDATE Article " + "SET name=:name, articlexml=:text, refSection=:department, "
                        + "refJournalist=:journalist, refPhotographer=:photographer, "
                        + "refPublication=:publication, description=:description, "
                        + "wantedCharacters=:wantedNumbeOfCharacters, wantedPages=:wantedNumberOfPages, "
                        + "refArticleType=:articleType, refStatus=:articleStatus, " + "lastSaved=:lastSaved "
                        + "WHERE ID=:id", parameters);
            }
        }

        return 0;
    }

    /**
     * Change the main tag name of an article. Used when the article type changes.
     *
     * @param art The article.
     * @param ID  The ID of the new article type.
     */
    protected void changeArticleType(Article art, int ID) {
        Map<String, Object> map = template.queryForMap("SELECT tagname FROM ArticleType WHERE ID=:id",
                Collections.singletonMap("id", ID));
        String tag = (String) map.get("tagname");

        Document doc = art.getDocument();
        if (doc == null) {
            art.parseText();
            doc = art.getDocument();
        }

        if (doc == null) {
            log.error("changeArticleType: Can't get document for article, article is NOT changed.");
            return;
        }

        Element root = doc.getDocumentElement();
        log.info("Root before: " + doc.getDocumentElement().toString());

        Element replace = doc.createElement(tag);

        NamedNodeMap att = root.getAttributes();

        for (int i = 0; i < att.getLength(); i++) {
            Node n = att.item(i);
            if (n instanceof Attr) {
                replace.setAttribute(((Attr) n).getName(), ((Attr) n).getValue());
            }
        }

        NodeList nl = root.getChildNodes();
        log.info("changeArticleType: Root node has {} children.", nl.getLength());
        for (int i = 0; i < nl.getLength(); i++) {
            Node clone = nl.item(i).cloneNode(true);
            log.info("Adding node {} to replace", (i + 1));
            replace.appendChild(clone);
        }

        log.info("Replacement node: {}", replace.toString());

        doc.replaceChild(replace, root);

        log.info("Root after: {}", doc.getDocumentElement().toString());

        if (!art.serialize()) {
            log.error("changeArticleType: Can't serialize the changed XML.");
        }
    }

    /**
     * Save the text of an open article.
     *
     * @param article The article.
     */
    public boolean saveArticleText(Article article) {
        boolean retval = false;

        doBackup(article.getId(), article.getText());

        try {
            Map<String, Object> parameters = new HashMap<String, Object>();
            parameters.put("text", article.getText());
            parameters.put("lastSaved", new Timestamp((new Date()).getTime()));
            parameters.put("currentNumberOfCharacters", article.getCurrentNumberOfCharacters());
            parameters.put("id", article.getId());
            template.update(
                    "UPDATE Article SET articlexml=:text, lastSaved=:lastSaved, characterCount=:currentNumberOfCharacters WHERE ID=:id",
                    parameters);
            log.info("saveArticleText: Article with ID {} saved.", article.getId());
            retval = true;
        } catch (DataAccessException e) {
            log.error("saveArticleText: SQL exception saving article text for art.ID {}", article.getId(), e);
        }
        return retval;
    }

    public Article getArticleByID(Person person, int ID) {
        log.info("getArticleByID: Getting Article with ID {} for user {}", ID, person.getUsername());

        String query = "SELECT * FROM Article WHERE ID=:id AND (refStatus!=7 OR refJournalist=:journalist)";
        Map<String, Object> parameters = new HashMap<String, Object>();
        parameters.put("id", ID);
        parameters.put("journalist", person.getUsername());
        try {
            return template.queryForObject(query, parameters, mapper);
        } catch (EmptyResultDataAccessException e) {
            return null;
        }
    }

    public Article getArticleByID(int ID) {
        log.info("getArticleByID: Getting Article with ID {}", ID);

        String query = "SELECT * FROM Article WHERE ID=:id AND (refStatus<>7)";
        try {
            return template.queryForObject(query, Collections.singletonMap("id", ID), mapper);
        } catch (EmptyResultDataAccessException e) {
            return null;
        }
    }

    public List<Article> getArticlesByPageID(int pageId) {
        try {
            return template.query(
                    "SELECT * FROM Article JOIN disppagearticles on disppagearticles.articleid = Article.id WHERE disppagearticles.pageid =:pageId",
                    Collections.singletonMap("pageId", pageId), mapper);
        } catch (EmptyResultDataAccessException e) {
            return null;
        }

    }

    public List<Article> getArticlesByDispID(int dispId) {
        try {
            return template.query(
                    "SELECT * FROM Article JOIN Publication on Article.refpublication=Publication.id join disp on disp.publicationid=Publication.id where disp.id=:id",
                    Collections.singletonMap("id", dispId), mapper);
        } catch (EmptyResultDataAccessException e) {
            return null;
        }
    }

    /**
     * Backup an article as XML
     *
     * @param articleID The ID of the article.
     * @param text      The text of the article.
     * @return <code>true</code> if all parts of the save operation
     *         was successful.
     */
    protected boolean doBackup(int articleID, String text) {
        // Dump the XML to file
        SimpleDateFormat df = new SimpleDateFormat("-yyyyy-MM-dd-HH-mm");
        String xmlFile = backupLocation + "/" + articleID + df.format(new Date()) + ".xml";

        FileOutputStream fos = null;
        OutputStreamWriter writer = null;
        try {
            fos = new FileOutputStream(xmlFile);
            writer = new OutputStreamWriter(fos, Charset.forName("utf-8"));
            writer.write(text);

        } catch (IOException e) {
            log.error("doBackup: Error writing XML file, aborting publish", e);
            log.info("saveArticleText: WARNING: backup failed for article {}!", articleID);
        } finally {
            try {
                if (writer != null)
                    writer.close();
                if (fos != null)
                    fos.close();
            } catch (IOException e) {
                log.error("Failed on stream close", e);
            }
        }
        log.info("doBackup: XML file saves as '{}'.", xmlFile);

        return true;
    }

    /**
     * Returns the template for the given article. This method will return
     * <code>null</code> if the template isn't found or an exception is thrown.
     * TODO: This method does not consider the encoding of the template XML.
     * The proper way to fix this is to parse as XML, and then serialize.
     *
     * @param articleID The ID of the article.
     * @return The template.
     */
    public String getTemplate(int articleID) {
        Map parameters = template.queryForMap(
                "SELECT Article.refJournalist, Article.refPhotographer, ArticleType.template FROM Article, ArticleType WHERE Article.ID=:id AND ArticleType.ID=Article.refArticleType",
                Collections.singletonMap("id", articleID));
        String templName = (String) parameters.get("template");
        String journalistID = (String) parameters.get("refJournalist");
        String photographerID = (String) parameters.get("refPhotographer");
        log.info("getTemplate: Retrieving template '{}/{}'.", xmlLocation, templName);

        String template;
        try {
            StringWriter temp = new StringWriter();
            TransformerFactory fac = TransformerFactory.newInstance();
            Transformer trans = fac.newTransformer();
            trans.transform(new StreamSource(new FileInputStream(xmlLocation + "/" + templName)),
                    new StreamResult(temp));

            template = temp.toString();
        } catch (Exception e) {
            log.error("getTemplate: Exception reading template file", e);
            return null;
        }

        // Format the template
        MessageFormat mf = new MessageFormat(template);
        Object[] args = new Object[10];
        log.debug("setting webxml to {}", webXml);
        args[0] = webXml;
        args[9] = articleID;

        // Set journalist info for template
        Person j = null;
        try {
            if (isNotBlank(journalistID)) {
                j = userServer.getUserByUsername(journalistID);
            }
        } catch (Exception e) {
            log.error("getTemplate: Error getting journalist info", e);
        }
        if (j != null) {
            args[1] = j.getUsername();
            args[2] = j.getName();
            args[3] = j.getEmailAddress();
            args[4] = getInitials(j);
        } else {
            args[1] = 0;
            args[2] = "";
            args[3] = "";
            args[4] = "";
        }

        // Set photographer info for template
        Person p = null;
        try {
            if (isNotBlank(photographerID)) {
                p = userServer.getUserByUsername(photographerID);
            }
        } catch (Exception e) {
            log.error("getTemplate: Error getting photographer info", e);
        }
        if (p != null) {
            args[5] = p.getUsername();
            args[6] = p.getName();
            args[7] = p.getEmailAddress();
            args[8] = getInitials(p);
        } else {
            args[5] = 0;
            args[6] = "";
            args[7] = "";
            args[8] = "";
        }

        try {
            return mf.format(args);
        } catch (Exception e) {
            log.error("getTemplate: Error formatting template", e);
            return null;
        }
    }

    public List<Person> getCoJournalistsForArticle(int articleID) {
        return template.query("SELECT refJournalist FROM CoJournalists WHERE refArticle=:article",
                Collections.singletonMap("article", articleID), new RowMapper<Person>() {
                    @Override
                    public Person mapRow(ResultSet rs, int rowNum) throws SQLException {
                        return userServer.getUserByUsername(rs.getString("refJournalist"));
                    }
                });
    }

    public void setCoJournalistsForArticle(int articleID, List<String> coJournalists) {
        template.update("DELETE FROM CoJournalists WHERE refArticle=:articleID",
                Collections.singletonMap("articleID", articleID));
        HashMap<String, Object> parameters = new HashMap<String, Object>();
        parameters.put("articleID", articleID);
        for (String id : coJournalists) {
            parameters.put("coJournalist", id);
            template.update("INSERT INTO CoJournalists VALUES(:articleID, :coJournalist)", parameters);
        }
    }

    public void setWebBase(String webBase) {
        this.webBase = webBase;
    }

    public void setWebPath(String webPath) {
        //  add / to path
        if (webPath.length() != 0) {
            webPath = webPath + "/";
        }
        this.webPath = webPath;
    }

    public File getArticleLocation() {
        return articleLocation;
    }

    public void setArticleLocation(File v) {
        this.articleLocation = v;
        log.info("Article location set to: " + v);
    }

    public File getBackupLocation() {
        return backupLocation;
    }

    public void setBackupLocation(File location) {
        this.backupLocation = location;

        log.info("Backup location set to " + backupLocation);
    }

    public File getXmlLocation() {
        return xmlLocation;
    }

    public void setXmlLocation(File v) {
        this.xmlLocation = v;
        log.info("XML location set to: " + v);
    }

    public String getWebXml() {
        return webXml;
    }

    public void setWebXml(String v) {
        this.webXml = v;
        log.info("Web XML set to: ", v);
    }

    public void setArticleStatusServer(ArticleStatusServer articleStatusServer) {
        this.articleStatusServer = articleStatusServer;
    }

    private class ArticleRowMapper implements RowMapper<Article> {

        public Article mapRow(ResultSet rs, int rowNum) throws SQLException {
            Article article = new Article(rs.getInt("ID"));
            article.setName(rs.getString("name"));
            String refJournalist = rs.getString("refJournalist");
            if (isNotBlank(refJournalist)) {
                article.setJournalist(userServer.getUserByUsername(refJournalist));
            }
            String refPhotographer = rs.getString("refPhotographer");
            if (isNotBlank(refPhotographer)) {
                article.setPhotographer(userServer.getUserByUsername(refPhotographer));
            }
            article.setDescription(rs.getString("description"));
            article.setCurrentNumberOfCharacters(rs.getInt("characterCount"));
            article.setWantedNumberOfCharacters(rs.getInt("wantedCharacters"));
            article.setWantedNumberOfPages(rs.getFloat("wantedPages"));
            article.setLastSaved(new Date(rs.getTimestamp("lastSaved").getTime()));
            article.setText(rs.getString("articlexml"));
            article.setPublication(publicationServer.getPublicationByID(rs.getInt("refPublication")));
            article.setArticleType(articleTypeServer.getArticleType(rs.getInt("refArticleType")));
            article.setArticleStatus(articleStatusServer.getArticleStatus(rs.getInt("refStatus")));
            article.setSection(sectionServer.getDepartment(rs.getInt("refSection")));
            return article;
        }
    }
}