Better Faster Lighter Java [Electronic resources] نسخه متنی

اینجــــا یک کتابخانه دیجیتالی است

با بیش از 100000 منبع الکترونیکی رایگان به زبان فارسی ، عربی و انگلیسی

Better Faster Lighter Java [Electronic resources] - نسخه متنی

Justin Gehtland; Bruce A. Tate

| نمايش فراداده ، افزودن یک نقد و بررسی
افزودن به کتابخانه شخصی
ارسال به دوستان
جستجو در متن کتاب
بیشتر
تنظیمات قلم

فونت

اندازه قلم

+ - پیش فرض

حالت نمایش

روز نیمروز شب
جستجو در لغت نامه
بیشتر
لیست موضوعات
توضیحات
افزودن یادداشت جدید








9.5 The Configuration Service


Let's start by looking at our configuration service,


since
it is used by all of the other services and interfaces. We need to
provide a generic interface for retrieving our configuration options,
separating the rest of the application from the details of how those
values are stored or retrieved. We are going to use property files
via java.util.Properties for the


initial
implementation.

Here is the class definition for ConfigBean:

package com.relevance.ss.config;
import java.util.Properties;
public class ConfigBean {
Properties props = new Properties( );
int maxlinks;
String[] allowedExtensions;
String skippedLinksFile;
public ConfigBean( )
{
try
{
props.load(getClass( ).getResourceAsStream(
"/com.relevance.ss.properties"));
maxlinks = Integer.parseInt(props.getProperty("maxlinks"));
allowedExtensions= props.getProperty("allowed.extensions").split(",");
skippedLinksFile = props.getProperty("skipped.links.file");
}
catch(Exception ex)
{
//log the errors and populate with reasonable defaults, if necessary
}
}
public String getSkippedLinksFile( )
{
return skippedLinksFile;
}
public int getMaxLinks( )
{
return maxlinks;
}
public String[] getAllowedExtensions( )
{
return allowedExtensions;
}
}

The class provides for the retrieval of three properties by name:
MaxLinks, AllowedExtensions,
and SkippedLinksFile. MaxLinks
determines the maximum size of the searchable domain,
AllowedExtensions is the file types the crawler
should attempt to index, and the SkippedLinksFile
is a logfile for keeping track of all the links skipped by a given
indexing event.

Originally, I thought about adding an additional method to allow for
future extension of the list of properties:

public String getPropertyByName(String propName)
{
return props.getProperty(propName);
}

However, adding this method would be confusing and redundant. If the
list of properties ever changes, we will have to make changes to the
source code for whatever services use the new property; we might as
well, then, also update ConfigBean at the same
time to expose the new property explicitly. For the sake of
simplicity, we'll leave this method out.

Getting the path to the index is not as simple as just reading the
path from a file. If we were talking about only a console-based
interface to the application, it would be okay. But since we are also
going to expose a web service, we have to protect against multiple
concurrent uses of the index. Specifically, we need to prevent a user
from performing a search on the index while the indexer is updating
it.

To ensure this, we implement a simple

kind of shadow copy.
The configuration file for the index path contains a root path
(index.fullpath) and a property for a special
extension to the index root path (index.next).
index.next has a value at all times of either 0
or 1. Any attempt to use the index for a search should use the
current value of index.fullpath +
index.next. Any attempt to create a new index
should use the alternate value of index.next,
write the new index there, and update the value in the property file
so future searches will use the new index.

Below is the implementation of IndexPathBean that
allows for these behaviors:

package com.relevance.ss.config;
import java.io.IOException;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.Properties;
public class IndexPathBean {
private final String propFilePath = "index.properties";
private String nextIndexPath;
private String curIndexPath;
private String nextIndex;
private Properties props;
private void getPaths( ) throws IOException
{
File f = new File(propFilePath);
if (!f.exists( )) {
throw new IOException("properties path " + propFilePath
+ " does not exist");
}
props = new Properties( );
props.load(new FileInputStream(propFilePath));
String indexRelativePath = props.getProperty("index.next");
if (indexRelativePath == null) {
throw new IllegalArgumentException("indexRelativePath not set in "
+ propFilePath);
}
nextIndex = Integer.toString(1 - Integer.parseInt(indexRelativePath));
curIndexPath = props.getProperty("index.fullpath") + indexRelativePath;
nextIndexPath = props.getProperty("index.fullpath") + nextIndex;
}
public String getFlippedIndexPath( ) throws IOException
{
getPaths( );
return nextIndexPath;
}
public String getIndexPath( ) throws IOException {
getPaths( );
return curIndexPath;
}
public void flipIndexPath( ) throws IOException
{
getPaths( );
props.setProperty("index.next", nextIndex);
props.store(new FileOutputStream(propFilePath), ");
}

The class exposes three public methods: getters for the current index
path and next index path, and a method that flips them. Any class
that needs to merely use the index can call getIndexPath(
)
to get the current version. Any class that needs to
modify the index can call getFlippedIndexPath( )
to get the version that isn't currently in use, and
after modifying it, can call flipIndexPath( ) to
reset the properties file to the new version. All three public
methods rely on a private utility method called getPaths(
)
, which reads the current values from the property file.

From a simplicity standpointand, to a certain extent,
transparency as wellwe should probably expose the index path
methods from ConfigBean, providing a single entry
point into the application's configuration settings
for the rest of the services. We'll leave the actual
functionality separated for ease of maintenance and replacement (in
case we have to modify the way the index path is stored over time).
To do that, we add the following lines of code to
ConfigBean:

IndexPathBean indexPathBean = new IndexPathBean( );
public String getCurIndexPath( )
{
String indexPath = ";
try
{
indexPath = indexPathBean.getIndexPath( );
}
catch(Exception ex)
{
}
return indexPath;
}
public String getNextIndexPath( )
{
String indexPath = ";
try
{
indexPath = indexPathBean.getFlippedIndexPath( );
}
catch(Exception ex)
{
}
return indexPath;
}
public void flipIndexPath( )
{
try
{
indexPathBean.flipIndexPath( );
}
catch(Exception ex)
{
}
}


9.5.1 Principles in Action


Keep it simple: use existing Properties tools, not XML

Choose the right tools: java.util.Properties

Do one thing, and do it well: separate configuration details into
separate service, keep simple properties and index path in separate
classes

Strive for transparency: one entry point for configuration settings,
even though there are two implementations

Allow for extension: expandable list of allowable link types



/ 111