File Source: IPBanList.java
/*
P/P * Method: org.apache.roller.weblogger.util.IPBanList$ModifiedFile__static_init
*/
1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. The ASF licenses this file to You
4 * under the Apache License, Version 2.0 (the "License"); you may not
5 * use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License. For additional information regarding
15 * copyright in this work, please see the NOTICE file in the top level
16 * directory of this distribution.
17 */
18
19 package org.apache.roller.weblogger.util;
20
21 import java.io.BufferedReader;
22 import java.io.FileReader;
23 import java.io.FileWriter;
24 import java.io.PrintWriter;
25 import java.util.HashSet;
26 import java.util.Set;
27 import org.apache.commons.logging.Log;
28 import org.apache.commons.logging.LogFactory;
29 import org.apache.roller.weblogger.config.WebloggerConfig;
30
31
32 /**
33 * Represents a list of banned ip addresses.
34 *
35 * This base implementation gets its list from a file on the filesystem. We
36 * are also aware of when the file changes via some outside source and we will
37 * automatically re-read the file and update the list when that happens.
38 */
39 public class IPBanList {
40
/*
P/P * Method: org.apache.roller.weblogger.util.IPBanList__static_init
*
* Presumptions:
* org.apache.commons.logging.LogFactory:getLog(...)@41 != null
*
* Postconditions:
* instance == &new IPBanList(IPBanList__static_init#1)
* (soft) log != null
* new HashSet(IPBanList#1) num objects == 1
* new IPBanList(IPBanList__static_init#1) num objects == 1
* new HashSet(loadBannedIps#1) num objects <= 1
* new IPBanList$ModifiedFile(IPBanList#2) num objects <= 1
* init'ed(new IPBanList$ModifiedFile(IPBanList#2).myLastModified)
* instance.bannedIps == One-of{&new HashSet(IPBanList#1), &new HashSet(loadBannedIps#1)}
* instance.bannedIps in Addr_Set{&new HashSet(IPBanList#1),&new HashSet(loadBannedIps#1)}
* init'ed(instance.bannedIpsFile)
*/
41 private static Log log = LogFactory.getLog(IPBanList.class);
42
43 // set of ips that are banned, use a set to ensure uniqueness
44 private Set bannedIps = new HashSet();
45
46 // file listing the ips that are banned
47 private ModifiedFile bannedIpsFile = null;
48
49 // reference to our singleton instance
50 private static IPBanList instance = null;
51
52
53 static {
54 instance = new IPBanList();
55 }
56
57
58 // private because we are a singleton
/*
P/P * Method: void org.apache.roller.weblogger.util.IPBanList()
*
* Preconditions:
* log != null
*
* Postconditions:
* this.bannedIps in Addr_Set{&new HashSet(IPBanList#1),&new HashSet(loadBannedIps#1)}
* init'ed(this.bannedIpsFile)
* new HashSet(IPBanList#1) num objects == 1
* new HashSet(loadBannedIps#1) num objects <= 1
* new IPBanList$ModifiedFile(IPBanList#2) num objects <= 1
* init'ed(new IPBanList$ModifiedFile(IPBanList#2).myLastModified)
*
* Test Vectors:
* org.apache.roller.weblogger.config.WebloggerConfig:getProperty(...)@64: Addr_Set{null}, Inverse{null}
* org.apache.roller.weblogger.util.IPBanList_ModifiedFile:canRead(...)@68: {0}, {1}
* org.apache.roller.weblogger.util.IPBanList_ModifiedFile:exists(...)@68: {0}, {1}
*/
59 private IPBanList() {
60
61 log.debug("INIT");
62
63 // load up set of denied ips
64 String banIpsFilePath = WebloggerConfig.getProperty("ipbanlist.file");
65 if(banIpsFilePath != null) {
66 ModifiedFile banIpsFile = new ModifiedFile(banIpsFilePath);
67
68 if(banIpsFile.exists() && banIpsFile.canRead()) {
69 this.bannedIpsFile = banIpsFile;
70 this.loadBannedIps();
71 }
72 }
73 }
74
75
76 // access to the singleton instance
77 public static IPBanList getInstance() {
/*
P/P * Method: IPBanList getInstance()
*
* Preconditions:
* init'ed(instance)
*
* Postconditions:
* return_value == instance
* init'ed(return_value)
*/
78 return instance;
79 }
80
81
82 public boolean isBanned(String ip) {
83
84 // update the banned ips list if needed
/*
P/P * Method: bool isBanned(String)
*
* Preconditions:
* init'ed(this.bannedIpsFile)
* (soft) log != null
* (soft) init'ed(this.bannedIps)
* (soft) init'ed(this.bannedIpsFile.myLastModified)
*
* Postconditions:
* init'ed(return_value)
* this.bannedIps == One-of{old this.bannedIps, &new HashSet(loadBannedIps#1)}
* (soft) init'ed(this.bannedIps)
* init'ed(this.bannedIpsFile.myLastModified)
* new HashSet(loadBannedIps#1) num objects <= 1
*
* Test Vectors:
* ip: Addr_Set{null}, Inverse{null}
*/
85 this.loadBannedIpsIfNeeded(false);
86
87 if(ip != null) {
+ 88 return this.bannedIps.contains(ip);
89 } else {
90 return false;
91 }
92 }
93
94
95 public void addBannedIp(String ip) {
96
/*
P/P * Method: void addBannedIp(String)
*
* Preconditions:
* (soft) log != null
* (soft) init'ed(this.bannedIps)
* (soft) init'ed(this.bannedIpsFile.myLastModified)
* (soft) init'ed(this.bannedIpsFile)
*
* Postconditions:
* this.bannedIps == One-of{old this.bannedIps, &new HashSet(loadBannedIps#1)}
* (soft) init'ed(this.bannedIps)
* (soft) init'ed(this.bannedIpsFile.myLastModified)
* new HashSet(loadBannedIps#1) num objects <= 1
*
* Test Vectors:
* ip: Inverse{null}, Addr_Set{null}
* this.bannedIpsFile: Addr_Set{null}, Inverse{null}
* java.util.Set:contains(...)@104: {1}, {0}
* org.apache.roller.weblogger.util.IPBanList_ModifiedFile:canWrite(...)@104: {0}, {1}
*/
97 if(ip == null) {
98 return;
99 }
100
101 // update the banned ips list if needed
102 this.loadBannedIpsIfNeeded(false);
103
+ 104 if(!this.bannedIps.contains(ip) &&
105 (bannedIpsFile != null && bannedIpsFile.canWrite())) {
106
107 try {
108 synchronized(this) {
109 // add to file
110 PrintWriter out = new PrintWriter(new FileWriter(this.bannedIpsFile, true));
111 out.println(ip);
112 out.close();
113 this.bannedIpsFile.clearChanged();
114
115 // add to Set
116 this.bannedIps.add(ip);
117 }
118
119 log.debug("ADDED "+ip);
120 } catch(Exception e) {
121 log.error("Error adding banned ip to file", e);
122 }
123 }
124 }
125
126
127 /**
128 * Check if the banned ips file has changed and needs to be reloaded.
129 */
130 private void loadBannedIpsIfNeeded(boolean forceLoad) {
131
/*
P/P * Method: void loadBannedIpsIfNeeded(bool)
*
* Preconditions:
* init'ed(this.bannedIpsFile)
* (soft) log != null
* (soft) init'ed(this.bannedIpsFile.myLastModified)
*
* Postconditions:
* this.bannedIps == One-of{old this.bannedIps, &new HashSet(loadBannedIps#1)}
* (soft) init'ed(this.bannedIpsFile.myLastModified)
* new HashSet(loadBannedIps#1) num objects <= 1
*
* Test Vectors:
* forceLoad: {0}, {1}
* this.bannedIpsFile: Addr_Set{null}, Inverse{null}
*/
132 if(bannedIpsFile != null &&
133 (bannedIpsFile.hasChanged() || forceLoad)) {
134
135 // need to reload
136 this.loadBannedIps();
137 }
138 }
139
140
141 /**
142 * Load the list of banned ips from a file. This clears the old list and
143 * loads exactly what is in the file.
144 */
145 private synchronized void loadBannedIps() {
146
/*
P/P * Method: void loadBannedIps()
*
* Preconditions:
* init'ed(this.bannedIpsFile)
* (soft) log != null
*
* Postconditions:
* this.bannedIps == One-of{old this.bannedIps, &new HashSet(loadBannedIps#1)}
* possibly_updated(this.bannedIpsFile.myLastModified)
* new HashSet(loadBannedIps#1) num objects <= 1
*
* Test Vectors:
* this.bannedIpsFile: Addr_Set{null}, Inverse{null}
* java.io.BufferedReader:readLine(...)@156: Addr_Set{null}, Inverse{null}
*/
147 if(bannedIpsFile != null) {
148
149 try {
150 HashSet newBannedIpList = new HashSet();
151
152 // TODO: optimize this
153 BufferedReader in = new BufferedReader(new FileReader(this.bannedIpsFile));
154
155 String ip = null;
156 while((ip = in.readLine()) != null) {
157 newBannedIpList.add(ip);
158 }
159
160 in.close();
161
162 // list updated, reset modified file
163 this.bannedIps = newBannedIpList;
164 this.bannedIpsFile.clearChanged();
165
166 log.info(this.bannedIps.size()+" banned ips loaded");
167 } catch(Exception ex) {
168 log.error("Error loading banned ips from file", ex);
169 }
170
171 }
172 }
173
174
175 // a simple extension to the File class which tracks if the file has
176 // changed since the last time we checked
177 private class ModifiedFile extends java.io.File {
178
179 private long myLastModified = 0;
180
/*
P/P * Method: void org.apache.roller.weblogger.util.IPBanList$ModifiedFile(IPBanList, String)
*
* Postconditions:
* init'ed(this.myLastModified)
*/
181 public ModifiedFile(String filePath) {
182 super(filePath);
183
184 this.myLastModified = lastModified();
185 }
186
187 public boolean hasChanged() {
/*
P/P * Method: bool hasChanged()
*
* Preconditions:
* init'ed(this.myLastModified)
*
* Postconditions:
* init'ed(return_value)
*/
188 if(lastModified() != myLastModified) {
189 return true;
190 } else {
191 return false;
192 }
193 }
194
195 public void clearChanged() {
/*
P/P * Method: void clearChanged()
*
* Postconditions:
* init'ed(this.myLastModified)
*/
196 myLastModified = lastModified();
197 }
198 }
199
200 }
SofCheck Inspector Build Version : 2.18479
| IPBanList.java |
2009-Jan-02 14:24:54 |
| IPBanList.class |
2009-Sep-04 03:12:32 |
| IPBanList$ModifiedFile.class |
2009-Sep-04 03:12:32 |