// 2012-06-28 johnpfeiffer requires validation-api, bval-core, bval-jsr303, commons-beanutils-core, commons-lang3
// TODO: Depends on NFSService? (when writing fstab mutually exclusively to be CIFS or Fstab)
// TODO: getPropertyValue( arraylist , String keyword , skipcharacter ) moved to utility class?
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Set;
import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.constraints.NotNull;
public class CIFSServiceDAO
{
@NotNull( message = "ERROR: CIFS Service cannot be null" )
private CIFSService cifsService = null;
protected static final String CIFSSERVERFILE = "/etc/cifsserver";
protected static final String CIFSCREDENTIALSFILE = "/etc/cifscredentials";
protected static final String FSTABFILE = "/etc/fstab";
protected static final String PARAMCIFSMOUNTPOINT = "/mnt/cifs";
protected static final String PARAMCIFSSTORAGEFOLDER = PARAMCIFSMOUNTPOINT + "/storage";
protected static final String PARAMCIFSFSTABLINECOMPLETION = "cifs uid=106,user,noexec,credentials=/etc/cifscredentials 0 0";
public static class Builder
{
@NotNull( message = "ERROR: Server data Contents cannot be null" )
private ArrayList <String> serverConfigurationFileContents = null;
@NotNull( message = "ERROR: Credentials data Contents cannot be null" )
private ArrayList <String> serverCredentialsFileContents;
@NotNull( message = "ERROR: CIFS service cannot be null" )
private CIFSService cifsService = null;
Builder() throws InstantiationException // load from files
{
this.serverConfigurationFileContents = initializeFromDataSource( CIFSSERVERFILE );
this.serverCredentialsFileContents = initializeFromDataSource( CIFSCREDENTIALSFILE );
if( this.serverConfigurationFileContents.size() != 1 )
{
throw new InstantiationException( "ERROR: CIFS Server Configuration file should have exactly one line: " + CIFSSERVERFILE );
}
if( this.serverCredentialsFileContents.size() != 2 )
{
throw new InstantiationException( "ERROR: CIFS Server Credentials file should have exactly two lines:" + CIFSCREDENTIALSFILE );
}
String cifsshare = getPropertyValue( CIFSService.PARAMCIFSSHARE + "=" , serverConfigurationFileContents );
String user = getPropertyValue( CIFSService.PARAMCIFSUSER + "=" , serverCredentialsFileContents );
String password = getPropertyValue( CIFSService.PARAMCIFSPASSWORD + "=" , serverCredentialsFileContents );
try
{
this.cifsService = new CIFSService.Builder().cifsshare( cifsshare ).user( user ).password( password ).build();
}catch( IllegalArgumentException e )
{
throw new InstantiationException( "ERROR: " + e.getMessage() );
}
}
public Builder cifs( CIFSService value )
{
this.cifsService = value;
return this;
}
public CIFSServiceDAO build()
{
CIFSServiceDAO cifsDAO = new CIFSServiceDAO( this );
CIFSServiceDAOValidator( cifsDAO );
return cifsDAO;
}
private static Validator validator = Validation.buildDefaultValidatorFactory().getValidator();
private void CIFSServiceDAOValidator( CIFSServiceDAO cifsDAO ) throws IllegalArgumentException , IllegalStateException
{
Set <ConstraintViolation <CIFSServiceDAO>> violations = validator.validate( cifsDAO );
if( !violations.isEmpty() )
{
for( ConstraintViolation <?> v : violations )
{
throw new IllegalArgumentException( v.getMessage() );
}
}
// ConstraintViolations ensure all of the values are non null
}
private ArrayList <String> initializeFromDataSource( String filename ) throws InstantiationException
{
ArrayList <String> datastore = new ArrayList <String>(); // prefer empty list over null
FileSystem fs = new FileSystem();
String fileLocation = null;
try
{
fileLocation = fs.convertFileSystemPath( filename );
if( fileLocation == null || fileLocation.isEmpty() )
{
throw new InstantiationException( "ERROR: could not access the data source " + filename );
}
datastore = fs.delimitedListFromFile( System.getProperty( "line.separator" ) , fileLocation );
}catch( IOException ioe )
{
throw new InstantiationException( ioe.getMessage() );
}
return datastore;
}
private String getPropertyValue( String keyword , ArrayList <String> dataList )
{
if( keyword == null )
{
throw new IllegalArgumentException( "ERROR: keyword cannot be null" );
}
if( dataList == null )
{
throw new IllegalArgumentException( "ERROR: dataList cannot be null" );
}
String value = "";
Iterator <String> it = dataList.iterator();
while( it.hasNext() )
{
String line = it.next();
line = line.trim();
if( line.contains( keyword ) && !line.startsWith( "#" ) ) // skips comments
{
int start = line.indexOf( keyword );
int finish = keyword.length();
value = line.substring( start + finish ); // assumes all info to the right of the IDENTIFIER is the property value
}
}
return value;
}
} // end inner class Builder
private CIFSServiceDAO( Builder builder )
{
this.cifsService = builder.cifsService;
}
protected CIFSService getCIFSService()
{
return this.cifsService;
}
protected String getHTMLForm()
{
if( this.cifsService == null )
{
throw new IllegalStateException( "ERROR: cannot build html form if cifsService is null" );
}
StringBuilder strb = new StringBuilder();
strb.append( this.cifsService.getHTMLForm() );
return strb.toString();
}
protected void writeToFile() throws IOException
{
writeServerFile();
writeCredentialsFile();
writeFstabFile();
}
private void writeServerFile() throws IOException
{
FileSystem fs = new FileSystem();
String newline = System.getProperty( "line.separator" );
StringBuilder content = new StringBuilder();
content.append( CIFSService.PARAMCIFSUSER + "=" + this.cifsService.getUser() + newline );
content.append( CIFSService.PARAMCIFSPASSWORD + "=" + this.cifsService.getPassword() + newline );
fs.writeStringToFile( content.toString() , CIFSCREDENTIALSFILE );
}
private void writeCredentialsFile() throws IOException
{
FileSystem fs = new FileSystem();
String newline = System.getProperty( "line.separator" );
StringBuilder content = new StringBuilder();
content.append( CIFSService.PARAMCIFSSHARE + "=" + cifsService.getCIFSShare() + newline );
fs.writeStringToFile( content.toString() , CIFSSERVERFILE );
}
private void writeFstabFile() throws IOException
{
String cifsShare = cifsService.getCIFSShare();
String newline = System.getProperty( "line.separator" );
String newCIFSsetting = cifsShare + " " + PARAMCIFSMOUNTPOINT + " " + PARAMCIFSFSTABLINECOMPLETION + newline;
FileSystem fs = new FileSystem();
ArrayList <String> fstabList = fs.delimitedListFromFile( newline , FSTABFILE );
StringBuffer content = new StringBuffer();
if( isReplaceExistingLine( fstabList ) )
{
for( String value : fstabList )
{
if( value.contains( PARAMCIFSMOUNTPOINT ) || value.contains( NFSService.PARAMNFSSTORAGEFOLDER ) )
{
if( !value.startsWith( "#" ) )
{
value = newCIFSsetting;
}
}
content.append( value );
}
}else
{
for( String value : fstabList )
{
content.append( value );
}
content.append( newCIFSsetting );
}
fs.writeStringToFile( content.toString() , FSTABFILE );
}
private boolean isReplaceExistingLine( ArrayList<String> fstabList )
{
boolean needsReplacementLine = false;
for( String value : fstabList )
{
if( value.contains( PARAMCIFSMOUNTPOINT ) || value.contains( NFSService.PARAMNFSSTORAGEFOLDER ) )
{
if( !value.startsWith( "#" ) )
{
needsReplacementLine = true;
}
}
}
return needsReplacementLine;
}
} // end class