comparison src/nabble/model/NodeImpl.java @ 47:72765b66e2c3

remove mailing list code
author Franklin Schmidt <fschmidt@gmail.com>
date Fri, 18 Jun 2021 17:44:24 -0600
parents 7ecd1a4ef557
children
comparison
equal deleted inserted replaced
46:7ac7f55e16cf 47:72765b66e2c3
47 import java.util.WeakHashMap; 47 import java.util.WeakHashMap;
48 import java.util.concurrent.CopyOnWriteArrayList; 48 import java.util.concurrent.CopyOnWriteArrayList;
49 import java.util.concurrent.TimeUnit; 49 import java.util.concurrent.TimeUnit;
50 50
51 51
52 final class NodeImpl implements Node, Node.MailFromList { 52 final class NodeImpl implements Node {
53 private static final Logger logger = LoggerFactory.getLogger(NodeImpl.class); 53 private static final Logger logger = LoggerFactory.getLogger(NodeImpl.class);
54 54
55 private static final Message DELETED_MESSAGE = new Message("- deleted -", Message.Format.TEXT) { 55 private static final Message DELETED_MESSAGE = new Message("- deleted -", Message.Format.TEXT) {
56 public boolean isDeleted() { return true; } 56 public boolean isDeleted() { return true; }
57 public boolean isDeactivated() { return true; } 57 public boolean isDeactivated() { return true; }
64 private Date whenCreated; 64 private Date whenCreated;
65 private long ownerId; 65 private long ownerId;
66 private UserImpl owner; 66 private UserImpl owner;
67 private long parentId = 0L; 67 private long parentId = 0L;
68 private NodeImpl parent; 68 private NodeImpl parent;
69 private String messageID;
70 private Date whenUpdated; 69 private Date whenUpdated;
71 private Boolean isGuessedParent = false;
72 private Date whenSent;
73 private long lastNodeId; 70 private long lastNodeId;
74 private Date lastNodeDate; 71 private Date lastNodeDate;
75 private int nodeCount; 72 private int nodeCount;
76 private Kind kind; 73 private Kind kind;
77 private String type; 74 private String type;
93 Message.Format msgFmt = Message.Format.getMessageFormat( rs.getString("msg_fmt").charAt(0) ); 90 Message.Format msgFmt = Message.Format.getMessageFormat( rs.getString("msg_fmt").charAt(0) );
94 message = new MyMessage(msgFmt); 91 message = new MyMessage(msgFmt);
95 whenCreated = rs.getTimestamp("when_created"); 92 whenCreated = rs.getTimestamp("when_created");
96 ownerId = rs.getLong("owner_id"); 93 ownerId = rs.getLong("owner_id");
97 parentId = rs.getLong("parent_id"); 94 parentId = rs.getLong("parent_id");
98 messageID = rs.getString("message_id");
99 whenUpdated = rs.getTimestamp("when_updated"); 95 whenUpdated = rs.getTimestamp("when_updated");
100 isGuessedParent = rs.getBoolean("guessed_parent");
101 if (rs.wasNull()) isGuessedParent = null;
102 whenSent = rs.getTimestamp("when_sent");
103 lastNodeId = rs.getLong("last_node_id"); 96 lastNodeId = rs.getLong("last_node_id");
104 lastNodeDate = rs.getTimestamp("last_node_date"); 97 lastNodeDate = rs.getTimestamp("last_node_date");
105 nodeCount = rs.getInt("node_count"); 98 nodeCount = rs.getInt("node_count");
106 kind = rs.getBoolean("is_app") ? Kind.APP : Kind.POST; 99 kind = rs.getBoolean("is_app") ? Kind.APP : Kind.POST;
107 type = rs.getString("type"); 100 type = rs.getString("type");
270 263
271 private static final long TEN_MINUTES = 10 * 60 * 1000; 264 private static final long TEN_MINUTES = 10 * 60 * 1000;
272 265
273 private void setWhenUpdated() { 266 private void setWhenUpdated() {
274 long timeDiff = new Date().getTime() - getWhenCreated().getTime(); 267 long timeDiff = new Date().getTime() - getWhenCreated().getTime();
275 boolean acceptChanges = timeDiff > TEN_MINUTES || !getChildren().isEmpty() || isMailToList(); 268 boolean acceptChanges = timeDiff > TEN_MINUTES || !getChildren().isEmpty();
276 if (acceptChanges) { 269 if (acceptChanges) {
277 setWhenUpdated( new Date() ); 270 setWhenUpdated( new Date() );
278 } 271 }
279 } 272 }
280 273
368 } finally { 361 } finally {
369 db().endTransaction(); 362 db().endTransaction();
370 } 363 }
371 return; 364 return;
372 } 365 }
373 MailingListImpl mailingList = getMailingListImpl();
374 if (mailingList != null) {
375 mailingList.unsubscribe();
376 }
377 if( getChildCount() == 0 ) { 366 if( getChildCount() == 0 ) {
378 deleteRecursively(); 367 deleteRecursively();
379 } else { 368 } else {
380 setMessage(DELETED_MESSAGE.getRaw(),DELETED_MESSAGE.getFormat()); 369 setMessage(DELETED_MESSAGE.getRaw(),DELETED_MESSAGE.getFormat());
381 clearPending();
382 update(); 370 update();
383 } 371 }
384 } 372 }
385 373
386 private boolean isDeletedMessage() { 374 private boolean isDeletedMessage() {
470 if( isDoneByPoster ) { 458 if( isDoneByPoster ) {
471 UserImpl owner = getOwnerImpl(); 459 UserImpl owner = getOwnerImpl();
472 if (owner != null) 460 if (owner != null)
473 owner.updateNewPostLimit(); 461 owner.updateNewPostLimit();
474 } 462 }
475 if( isMailToList() && isDoneByPoster )
476 throw new RuntimeException("no more pending");
477 String message = (String)record.fields().remove("message"); 463 String message = (String)record.fields().remove("message");
478 record.insert(); 464 record.insert();
479 insertMessage(message); 465 insertMessage(message);
480 setLastNodeId( getId() ); 466 setLastNodeId( getId() );
481 setLastNodeDate( whenCreated ); 467 setLastNodeDate( whenCreated );
1161 postInsertListeners.add(listener); 1147 postInsertListeners.add(listener);
1162 } 1148 }
1163 1149
1164 static void addPostUpdateListener(final Listener<? super NodeImpl> listener) { 1150 static void addPostUpdateListener(final Listener<? super NodeImpl> listener) {
1165 postUpdateListeners.add(listener); 1151 postUpdateListeners.add(listener);
1166 Listener<MailingListImpl> mlListener = new Listener<MailingListImpl>() {
1167 public void event(MailingListImpl ml) {
1168 listener.event(ml.getForumImpl());
1169 }
1170 };
1171 MailingListImpl.postInsertListeners.add(mlListener);
1172 MailingListImpl.postUpdateListeners.add(mlListener);
1173 MailingListImpl.postDeleteListeners.add(mlListener);
1174 } 1152 }
1175 1153
1176 static void addPostDeleteListener(final Listener<? super NodeImpl> listener) { 1154 static void addPostDeleteListener(final Listener<? super NodeImpl> listener) {
1177 postDeleteListeners.add(listener); 1155 postDeleteListeners.add(listener);
1178 } 1156 }
1773 if( !record.fields().isEmpty() ) 1751 if( !record.fields().isEmpty() )
1774 record.update(); 1752 record.update();
1775 } 1753 }
1776 1754
1777 1755
1778
1779 // mailing list related
1780
1781 static final String messageIDEnding;
1782 static {
1783 try {
1784 messageIDEnding = ".post@" + Init.get("mailDomain",InetAddress.getLocalHost().getHostName());
1785 } catch(UnknownHostException e) {
1786 logger.error("",e);
1787 System.exit(-1);
1788 throw new RuntimeException(); // for compiler
1789 }
1790 }
1791
1792 public String getMessageID() {
1793 return messageID;
1794 }
1795
1796 public MailFromList getParentMailFromList() {
1797 Node node = getParent();
1798 return (node == null) ? null : node.getMailFromList();
1799 }
1800
1801 public String getOrGenerateMessageID() {
1802 if (messageID == null) {
1803 String id = "" + System.currentTimeMillis() + "-" + getId() + messageIDEnding;
1804 setMessageID(id);
1805 if( isInDb() )
1806 this.record.update();
1807 }
1808 return messageID;
1809 }
1810
1811 void setMessageID(String messageID) {
1812 this.messageID = messageID;
1813 record.fields().put("message_id",messageID);
1814 }
1815
1816 void setGuessedParent(NodeImpl newParent)
1817 throws ModelException
1818 {
1819 setGuessedParent(true);
1820 changeParentImpl(newParent);
1821 }
1822
1823 boolean isGuessedParent() {
1824 return (isGuessedParent != null) && isGuessedParent;
1825 }
1826
1827 boolean isNotGuessedParent() {
1828 return (isGuessedParent != null) && !isGuessedParent;
1829 }
1830
1831 public boolean hasGuessedParent() {
1832 return isGuessedParent();
1833 }
1834
1835 Boolean rawGuessedParent() {
1836 return isGuessedParent;
1837 }
1838
1839 /**
1840 * Set 'guessed_parent' flag of the post.
1841 *
1842 * @param guessed flag value
1843 */
1844 void setGuessedParent(Boolean guessed) {
1845 this.isGuessedParent = guessed;
1846 record.fields().put("guessed_parent", DbNull.fix(this.isGuessedParent) );
1847 }
1848
1849 void setGuessedParent(String parentID) {
1850 setGuessedParent(Boolean.TRUE);
1851 setRawParentMessageId(parentID);
1852 }
1853
1854 // only returns MailingList if not isUIHidden
1855 public MailingList getAssociatedMailingList() {
1856 return getAssociatedMailingListImpl();
1857 }
1858
1859 MailingListImpl getAssociatedMailingListImpl() {
1860 for( NodeImpl node=this; node!=null; node=node.getParentImpl() ) {
1861 if( node.getKind()==Kind.APP ) {
1862 MailingListImpl ml = node.getMailingListImpl();
1863 if( ml != null )
1864 return ml;
1865 }
1866 }
1867 return null;
1868 }
1869
1870 boolean isFromMailingList() {
1871 return message.getFormat() == Message.Format.MAILING_LIST;
1872 }
1873
1874 void clearPending() {
1875 whenSent = null;
1876 record.fields().put("when_sent", DbNull.TIMESTAMP);
1877 if( !db().isInTransaction() ) {
1878 record.update();
1879 DbUtils.uncache(getOwnerImpl());
1880 }
1881 }
1882
1883 private boolean isMailToList() {
1884 return getKind() == Kind.POST && getAssociatedMailingListImpl() != null && !isFromMailingList();
1885 }
1886
1887 public MailToList getMailToList() {
1888 if( !isMailToList() )
1889 return null;
1890 return new MailToList() {
1891
1892 public Node getNode() {
1893 return NodeImpl.this;
1894 }
1895
1896 public boolean isPending() {
1897 return whenSent != null;
1898 }
1899
1900 public void clearPending() {
1901 NodeImpl.this.clearPending();
1902 }
1903
1904 public Date getWhenSent() {
1905 return whenSent;
1906 }
1907
1908 public String getOrGenerateMessageID() {
1909 return NodeImpl.this.getOrGenerateMessageID();
1910 }
1911
1912 };
1913 }
1914
1915
1916 public MailFromList getMailFromList() {
1917 // MailFromList is used to work with all messages from mailing lists, both local and external
1918 return (getKind() == Kind.POST && getAssociatedMailingListImpl() != null) ? this : null;
1919 }
1920
1921 public MailingList newMailingList(ListServer listServer,String listAddress,String url) throws ModelException {
1922 if( getKind() != Kind.APP )
1923 throw new UnsupportedOperationException();
1924 if( !ModelHome.insideImportProcedure.get() )
1925 DailyNumber.forumsStarted.dec();
1926 setMailingList(new MailingListImpl(this, listServer, listAddress, url));
1927 DbUtils.uncache(this);
1928 return mailingList;
1929 }
1930
1931 private void setRawParentMessageId(String parentMessageId) {
1932 record.fields().put("parent_message_id", DbNull.fix(parentMessageId));
1933 }
1934
1935 static NodeImpl[] getFromParentID(String parentID, MailingListImpl mailingList) {
1936 try {
1937 SiteKey siteKey = mailingList.siteKey;
1938 Connection con = siteKey.getDb().getConnection();
1939 PreparedStatement stmt = con.prepareStatement(
1940 "select *"
1941 +" from node"
1942 +" where lower(parent_message_id)=?"
1943 );
1944 stmt.setString(1,parentID.toLowerCase());
1945 ResultSet rs = stmt.executeQuery();
1946 try {
1947 List<NodeImpl> list = new ArrayList<NodeImpl>();
1948 while( rs.next() ) {
1949 NodeImpl post = getNode(siteKey,rs);
1950 if (mailingList.equals(post.getAssociatedMailingListImpl()))
1951 list.add( post );
1952 }
1953 return list.toArray(new NodeImpl[0]);
1954 } finally {
1955 rs.close();
1956 stmt.close();
1957 con.close();
1958 }
1959 } catch(SQLException e) {
1960 throw new RuntimeException(e);
1961 }
1962 }
1963
1964 NodeImpl getNodeImplFromMessageID(String messageID) {
1965 if( messageID == null )
1966 return null;
1967 try {
1968 Connection con = db().getConnection();
1969 PreparedStatement stmt = con.prepareStatement(
1970 "select * from node"
1971 +" where lower(message_id)=? and message_id is not null"
1972 );
1973 stmt.setString(1,messageID.toLowerCase());
1974 ResultSet rs = stmt.executeQuery();
1975 try {
1976 while (rs.next()) {
1977 NodeImpl post = getNode(rs);
1978 if( post.getAncestors().contains(this) )
1979 return post;
1980 }
1981 return null;
1982 } finally {
1983 rs.close();
1984 stmt.close();
1985 con.close();
1986 }
1987 } catch(SQLException e) {
1988 throw new RuntimeException(e);
1989 }
1990 }
1991
1992
1993
1994
1995
1996 private MailingListImpl mailingList;
1997 private boolean mailingListSet = false;
1998
1999 private void setMailingList(MailingListImpl mailingList) {
2000 this.mailingList = mailingList;
2001 mailingListSet = true;
2002 }
2003
2004 MailingListImpl getMailingListImpl() {
2005 if( getKind() != Kind.APP )
2006 return null;
2007 if (!mailingListSet || (mailingList != null && DbUtils.isStale(mailingList))) {
2008 setMailingList(MailingListImpl.getMailingListForForum(this));
2009 }
2010 return mailingList;
2011 }
2012
2013 public MailingList getMailingList() {
2014 return getMailingListImpl();
2015 }
2016
2017 public void deleteMailingList() {
2018 MailingList mailingList = getMailingList();
2019 if (mailingList != null) {
2020 mailingList.delete();
2021 this.mailingList = null;
2022 this.mailingListSet = false;
2023 DbUtils.uncache(this);
2024 }
2025 }
2026
2027
2028
2029
2030 // export/import 1756 // export/import
2031 1757
2032 NodeImpl(SiteImpl site,NodeData data) 1758 NodeImpl(SiteImpl site,NodeData data)
2033 throws ModelException 1759 throws ModelException
2034 { 1760 {
2049 if( data.whenUpdated != null ) 1775 if( data.whenUpdated != null )
2050 setWhenUpdated( data.whenUpdated ); 1776 setWhenUpdated( data.whenUpdated );
2051 setType( data.type ); 1777 setType( data.type );
2052 if( data.pin != null ) 1778 if( data.pin != null )
2053 record.fields().put( "pin", data.pin ); 1779 record.fields().put( "pin", data.pin );
2054 if( data.messageID != null )
2055 setMessageID( data.messageID );
2056 setGuessedParent( data.isGuessedParent );
2057 insert(false); 1780 insert(false);
2058
2059 if( data.mlAddress != null ) {
2060 ListServer listServer = ListServer.getServer( data.mlServer );
2061 MailingList mailingList = newMailingList( listServer, data.mlAddress, data.mlUrl );
2062 mailingList.setPlainTextOnly( data.mlPlainTextOnly );
2063 mailingList.setIgnoreNoArchive( data.mlIgnoreNoArchive );
2064 mailingList.setListName( data.mlListName );
2065 mailingList.update();
2066 update();
2067 }
2068 1781
2069 for( URL url : data.fileUrls ) { 1782 for( URL url : data.fileUrls ) {
2070 try { 1783 try {
2071 FileUpload.uploadFile( new FileUpload.UrlFileItem(url), this ); 1784 FileUpload.uploadFile( new FileUpload.UrlFileItem(url), this );
2072 } catch(ModelException e) {} 1785 } catch(ModelException e) {}
2102 data.message = getMessage().getRaw(); 1815 data.message = getMessage().getRaw();
2103 data.msgFmt = getMessage().getFormat().getCode(); 1816 data.msgFmt = getMessage().getFormat().getCode();
2104 data.whenCreated = whenCreated; 1817 data.whenCreated = whenCreated;
2105 data.whenUpdated = whenUpdated; 1818 data.whenUpdated = whenUpdated;
2106 data.type = type; 1819 data.type = type;
2107 data.messageID = messageID;
2108 data.isGuessedParent = isGuessedParent;
2109
2110 MailingListImpl mailingList = getMailingListImpl();
2111 if( mailingList != null ) {
2112 data.mlAddress = mailingList.getListAddress();
2113 data.mlUrl = mailingList.getUrl();
2114 if( data.mlUrl==null )
2115 data.mlUrl = "http://localhost";
2116 data.mlPlainTextOnly = mailingList.plainTextOnly();
2117 data.mlIgnoreNoArchive = mailingList.ignoreNoArchive();
2118 data.mlServer = mailingList.getListServer().getType();
2119 data.mlListName = mailingList.getListName();
2120 }
2121 1820
2122 List<URL> urls = new ArrayList<URL>(); 1821 List<URL> urls = new ArrayList<URL>();
2123 Message.Format fmt = message.getFormat(); 1822 Message.Format fmt = message.getFormat();
2124 if( !(fmt instanceof MailMessageFormat) ) { 1823 if( !(fmt instanceof MailMessageFormat) ) {
2125 Html list = message.parse(); 1824 Html list = message.parse();