Thursday, November 27, 2014

File input control don't have to be ugly    

The caption is a bit of a lie, it has to be ugly, since native browser implementation is pretty ugly and there is no straight forward way to change it's L&F.

So what do you do when your have a nice bootstrap  L&F in the whole system?

This fiddle suggesting a nice solution that was inspired by this guy.

I've used it together with AngularJS file uploader directive and it looks and works pretty nice good together.

In general the solution is :

  1. To make the sure you file input tag is transparent 
  2. To increase it's z-index so it will be above
  3. To locate it on the same spot a nice looking control is located
  4. To make sure z-index of nice looking control is lower than the file input tag

Actually that all the story, if anyone familiar with better techniques to prettify file input tag, please leave a comment bellow.



Tuesday, August 5, 2014

AngularJS directive to wrap Chart.js charting library

Just forked a directive used to wrap Chart.js charting library.
I've made a single change to original code published by earlonrails, which already worked fine.
My directive sensitive to both changing the whole chart object or just data  attribute.
Here is the link for forked version. 

Wednesday, July 2, 2014

Create an extensible set of commands using: Spring,Annotations and simple interface

Lately I've found myself using the same technique more than once in order to create some easily extensible mechanism, using: Spring, Annotations and simple predefined interface

I think the best way to picture the usage would be an example:
Let's say you need some kind of email editor in your application which will allow your user to use predefined set of keywords that will be evaluated during the email sending.

For example: 
If the user wrote following text in email body :  Hi today is ${system.Date} and I'm ...
Then  the recipient will get following content  :  Hi today is 2/7/2014 and I'm ...

In case your task is a bit more complicated than that and you need more comprehensive set of keywords, that will be extended during the time or even you would like to allow 3rd party developers to extend it, following technique might be handy.

I'll skip the part when you find  ${prefix.keyword} pattern in the code and start from the point you have extracted the keyword already.
 

   
 //.......
    for(/*... do the iteration*/){
        // get your keyword from text
        String keywordValue =  getKeywordValue(foundKeyword);
        // replace your ${foundKeyword} with keywordValue
    } 

//......
    // call the Helper class to get the correct executor
    private String getKeywordValue(String key) {
        KeywordExecutor keywordExecutor = KeywordExecutorsHelper.getKeywordExecutor(key);
        if(keywordExecutor != null){
            return  keywordExecutor.execute(context);
        }
        // if we couldn't find suitable executor just return the keyword as is 
        return key;
    }

Now let's have a look on how KeywordExecutor implemented, for sake of our example let's assume we have 2 keywords to implement: system.Date and system.Time

 // the interface
 public interface KeywordExecutor {

    // you can pass any parameters if you need them for your business case
    String execute();
 }

 // annotation that will hold the required keyword 
 @Target(ElementType.TYPE)
 @Retention(RetentionPolicy.RUNTIME)
 public @interface Keyword {

    String value();
 }


 @Component // Spring Component annotation 
 @Keyword("system.Time") // here goes our annotation with the the keyword 
 public class TimeKeyword implements KeywordExecutor {


    // the implementation itself 
    @Override
    public String execute() {
        Date now = new Date();
        // using Spring SimpleDateFormat here 
        SimpleDateFormat format = new SimpleDateFormat("HH:mm:ss");
        return format.format(now);
    }
 }


// same as above with slight format change
 @Component
 @Keyword("system.Date")
 public class DateKeyword implements KeywordExecutor {


    @Override
    public String execute() {
        Date now = new Date();
        SimpleDateFormat format = new SimpleDateFormat("dd-MMM-yyyy");
        return format.format(now);
    }
 }

You can see that execute method can be as complex as we need and the rest of the code won't be affected.

The last thing that we need is our KeywordExecutorsHelper implementation:

 
 // in this sample I just reading all the classes every time getKeywordExecutor method called, you can optimize this by
 // saving the Map a static variable and lazy initializing it during the first getKeywordExecutor call 
 public class KeywordExecutorsHelper {
    public static KeywordExecutor getKeywordExecutor(String keyword) {

        // getting all the beans annotated with Keyword annotation 
        Map keywordExecutors = SpringUtils.getBeanWithAnnotation(Keyword.class);
        // the bean name used as a key in retrieved Map
        for (String beanName : keywordExecutors.keySet()) {
            // since all the beans implementing the same interface, I can safely cast each bean to KeywordExecutor 
            KeywordExecutor keywordExecutor = (KeywordExecutor) keywordExecutors.get(beanName);
            // getting the specific annotation instance from current bean using simple java reflection
            Keyword keywordAnnotation = keywordExecutor.getClass().getAnnotation(Keyword.class);

            // reading the value attribute and comparing with received keyword
            if (keyword.equalsIgnoreCase(keywordAnnotation.value())) {
                return keywordExecutor;
            }

        }
        // no implementation found for requested keyword
        return null;
    }

}

So, lets summarize what have we done and why you might need it:
  • What
    • Defined an interface that will help us to encapsulate bean implementation (execute in the case above)
    • Define an annotation that will help us to find all the annotated classes using Spring and will be used as a placeholder for required attributes  (Keyword in the case described above)
    • Define a Helper class that will retrieve all the possible implementations from Spring context and will  return a specific one by demand
    • Finally use the  Helper class to get the specific implementation 
  • Why
    • In case you need an extensible set of commands that can be summoned using keyword only this implementation can  be very handy
    • In case you want to outsource the implementation and will receive some kind of 3rd jar, you'll have to define only the interface and the annotation
Hope it was helpful.

Saturday, June 28, 2014

Stream a file using Spring MVC Controller

Did you ever need a way to stream a file directly to the browser as a result of calling a specific URI?

I did, more than once. Every time it requires some time to recall what is the correct way to do that.
This post will be a reminder for me and might become useful for anyone who reads this.

Why would I want to do that?

I needed that in following scenarios:

  1. I've just generated a pdf file and I'm required to return it to web based client, so the pdf file would be opened or downloaded automatically by the browser.
  2. There is a bunch of  image files located in some custom (preferably predefined) location that is not exposed  via direct URL, a.k.a it's not located in any subfolder under WEB-INF directory. This configuration is useful when I need to allow a customer put some custom icons without giving him an access to my web application resources or implementing file upload.
  3. In general: any time I need to return to web browser any downloadable type of file or file type that browsers are able to open.

How to do that?


Let's define a simple Spring MVC controller. In order access to application context I'll implement ApplicationContextAware interface.

@Controller
@RequestMapping("/customIcons")
public class CustomIconsController  implements ApplicationContextAware {
    private ApplicationContext applicationContext;
       
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

}

In this specific implementation I needed a way to enlist all the images under specific location. Once a caller UI gets them, it will have to show a dialog with all the available icons and will allow the user to pick one of the presented icons.


    // will contain all the found resources in order to return the stream as soon as the request arrives
    private Map foundResources = new HashMap<>(); 

    @RequestMapping("/all")
    @ResponseBody
    public Collection getAllCustomIcons() {

        Collection retVal = new ArrayList<>();
        Resource[] resources = null;

        try {
            // getting all the .png files from predefined location 
            resources= applicationContext.getResources("file:c:/customIconsPath/*.png");
        } catch (IOException e) {
            // any fallback solution can come here, for example: try to load images from your classpath instead 
            throw new ConfigurationException("No custom icons directory available");
        }

        extractFileNames(retVal, resources);

        return retVal;

    }
    private void extractFileNames(Collection retVal, Resource[] resources) {
        if (resources != null) {
            for (Resource resource : resources) {
                String finalName = resource.getFilename().replace(".png", "");// just removing the extention
                if (!"".equals(finalName)) {
                    retVal.add(finalName);
                    foundResources.put(resource.getFilename(), resource);
                }
            }
        }
    }

So far so good, I've got the list of all my .png files and now I want to show them in html using img tag Using AngularJS I would write something like this:

<img ng-repeat="customIconName in customIconNames"  ng-src="'customIcons/icon/' + customIconName"/>    

 You can use any other JS technique to get the resulting file name from the list returned by previous call.

 And that's the way method returning the requested image will look:


    @RequestMapping("/icon/{fileName}")
    // pay attention to second parameter, Spring MVC can pass HTTP response and request besides the path variable parameters
    public void getCustomIcon(@PathVariable("fileName") final String fileName, HttpServletResponse response) {

        try {
            // we've returned the filename without extension, so we put the extension back
            // alternatively we could save the Map key without the extension.    
            InputStream inputStream = foundResources.get(fileName + ".png").getInputStream();
            // the browser should know what kind of data are we streaming so setting a mime type is essential  
            response.setContentType("image/png");
            // copy the file input stream to response output stream (see the function bellow)
            writeStream(inputStream, response.getOutputStream());
            // flushing the response
            response.flushBuffer();

        } catch (FileNotFoundException e) {
            // just logging the errors
            logger.error(e);
        } catch (IOException e) {
            logger.error(e);
        }
   }

   public static void writeStream(InputStream inputStream, OutputStream outputStream) throws IOException {
        int buf_size = 8192;
        byte[] buf = new byte[buf_size];
        int len;
        while ((len = inputStream.read(buf, 0, buf_size)) != -1) {
            outputStream.write(buf, 0, len);
        }
    }

The getCustomIcon method, which is the whole reason for this post, is very simple  and requires to follow several steps:

  1. HttpServletResponse should be one of the parameters your void method receives
  2. Read the required file from the disk (in the example above it was already read in previous call)
  3. Copy  the input stream from of your file to response output stream (I've just used the fact that Resource can return an input stream right away)
  4. Call response.flushBuffer() to  complete the streaming
Hope it helps.

Wednesday, May 28, 2014

Saving encrypted password attribute in MongoDb using Spring

In my current project I'm using MongoDB with Spring .
It's the first time I'm using noSQL database and over all the experience is pretty good.

One of the reasons that required noSQL DB usage was the fact, that various entities can have unknown number of attributes. Furthermore that number can vary depending on the entity internal type.  

If I use an Endpoint entity as an example, it would look like this:

// BaseModel it's a parent class containing a single field
//  @Id
//  protected  String _id; 

@Document(collection = "endpoint")
public class Endpoint extends BaseModel {

    private String name;
    private String description;
    private String endpointType;
    private Collection attributes;

// getters and setters
}

The Attribute class looks like this:
public class Attribute extends BaseModel {
 
    private String parentObjectName;
    private AttributeType attributeType;
    private String name;
    private String displayName;
    private String fullName;
    private T value;
    private T defaultValue;
    // add getters and setters 
  }

and AttributeType is a simple enum:
public enum AttributeType {
    STRING,LONG,INTEGER,DATE,DATE_TIME,ENUM,PASSWORD,BOOLEAN,TEXT_AREA;
}

So everything is fine as long we don't have any security concerns. But an Attribute may contain a password information, in that case we would like to use some kind of bi-directional encryption (AES for instance) to encrypt the attribute value before it's being written to the DB and decrypt it right after it's read from the DB.
Since such attributes collections can be member of more than a single class, we need an infrastructural solution.

If we extend AbstractMongoEventListener class we'll achieve a listener that will be called on each one of the following occasions:

  • onBeforeConvert
  • onBeforeSave
  • onAfterSave
  • onAfterConvert  

for each entity that being saved or retrieved from the DB.

In our case we need to override 2 methods:

    @Override
    public void onBeforeConvert(Object source) {
        super.onBeforeConvert(source);
        passwordsPersistenceCare(source,true);
    }

//........
   @Override
    public void onAfterConvert(DBObject dbo, Object source) {
        super.onAfterConvert(dbo, source);
        passwordsPersistenceCare(source,false);
    }


To summarize:
Having some kind of general operation on certain  entity type, before it's written to MonogDb and\or after it's read from the DB, we can  extend AbstractMongoEventListener in order to gain a single location that will allow us to perform such an operation.
Another example that using the technique described above can be found here in Maciej Walkowiak blog

You can see the full code in the gist bellow: 
https://gist.github.com/IVedmak/7ec70d6744743a3c30eb

UPDATED:
See  gist with complete implementation of the listener that supports more complex data structures and UCs:
1)Attributes collection located in the objects that is deeper than the 1st level
2)The object with attributes collection is a part of the Map object
3)If any of the objects in memory instance used after the encryption and saving it, it's should be decrypted 1st
4)If the same object being referenced by more than one parent object it's should not be encrypted or decrypted twice 

Saturday, May 17, 2014

Linear gauge with gradient fill

In my searches for linear gauge control I didn't find any viable solution.
So I've created one based on D3 stacked bar graph.
See JSFiddle for implementation details

The final result will be something like this:


The Html will be pretty simple, only the container where we will put all the drawing

<div id="linearGaugeContainer"></div>

 I'm using SVG gradients definition in this sample

<!--define svg gradients to be used in java script. make sure the svg tag takes no room on your page=> width and height = 0px-->
<svg style="height: 0px; width: 0px;" xmlns="http://www.w3.org/2000/svg">
    <defs>
        <lineargradient id="NORMAL_COLOR" spreadmethod="pad" x1="0%" x2="0%" y1="0%" y2="100%">
            <stop offset="0%" stop-color="#C1DC99" stop-opacity="1">
            <stop offset="100%" stop-color="#669900" stop-opacity="1">
        </stop></stop></lineargradient>
        <lineargradient id="WARNING_COLOR" spreadmethod="pad" x1="0%" x2="0%" y1="0%" y2="100%">
            <stop offset="0%" stop-color="#84C6F6" stop-opacity="1">
            <stop offset="100%" stop-color="#6FA7CF" stop-opacity="1">
        </stop></stop></lineargradient>
        <lineargradient id="MINOR_COLOR" spreadmethod="pad" x1="0%" x2="0%" y1="0%" y2="100%">
            <stop offset="0%" stop-color="#FFE537" stop-opacity="1">
            <stop offset="100%" stop-color="#F9C328" stop-opacity="1">
        </stop></stop></lineargradient>
        <lineargradient id="MAJOR_COLOR" spreadmethod="pad" x1="0%" x2="0%" y1="0%" y2="100%">
            <stop offset="0%" stop-color="#FF9900" stop-opacity="1">
            <stop offset="100%" stop-color="#FF6700" stop-opacity="1">
        </stop></stop></lineargradient>
        <lineargradient id="CRITICAL_COLOR" spreadmethod="pad" x1="0%" x2="0%" y1="0%" y2="100%">
            <stop offset="0%" stop-color="#E70030" stop-opacity="1">
            <stop offset="100%" stop-color="#B30020" stop-opacity="1">
        </stop></stop></lineargradient>
    </defs>
</svg>

The javascript code is a bit long, just follow the comments within the code:

//Linear gauge
//The way to implement it would be: 
// - To take a stacked bar graph as a basis
// - Ignore all the graph related attributes 
//   (like: axis, ticks and so on)
// - Define a single set of data 
// - Swap the x and y axis values
var margins = {
    top: 12,
    left: 48,
    right: 24,
    bottom: 24
},
width = 700 - margins.left - margins.right
    height = 15,
    dataset = [{
        data: [{
            barId: '1', // we assign some random value, the most important to keep it same for all the entries 
            percent: 0.1, // percentage that we want a specific value to occupy as a part of the gauge: values betwee 0-1
            severity: 'NORMAL_COLOR'// color id that we'll used to reference gradient value
        }]
    }, {
        data: [{
            barId: '1',
            percent: 0.4,
            severity: 'WARNING_COLOR'
        }]
    }, {
        data: [{
            barId: '1',
            percent: 0.22,
            severity: 'MINOR_COLOR'
        }]
    }, {
        data: [{
            barId: '1',
            percent: 0.2,
            severity: 'MAJOR_COLOR'
        }]
    }, {
        data: [{
            barId: '1',
            percent: 0.08,
            severity: 'CRITICAL_COLOR'
        }]
    }],
    dataset = dataset.map(function (d) {
        return d.data.map(function (o, i) {
            // Structure it so that your numeric
            // axis (the stacked amount) is y
            return {
                y: o.percent,
                x: o.barId,
                severity:o.severity
            };
        });
    }),
    stack = d3.layout.stack();

stack(dataset);


var dataset = dataset.map(function (group) {
    return group.map(function (d) {
        // Invert the x and y values, and y0 becomes x0
        return {
            x: d.y,
            y: d.x,
            x0: d.y0,
            severity:d.severity
            
        };
    });
}),
    svg = d3.select('#linearGaugeContainer')
        .append('svg')
        .attr('width', width + margins.left + margins.right)
        .attr('height', height + margins.top + margins.bottom)
        .append('g')
        .attr('transform', 'translate(' + margins.left + ',' + margins.top + ')'),
    xMax = d3.max(dataset, function (group) {
        return d3.max(group, function (d) {
            return d.x + d.x0;
        });
    }),
    xScale = d3.scale.linear()
        .domain([0, xMax])
        .range([0, width]),
    yValue = dataset[0].map(function (d) {
        return d.y;
    }),
    yScale = d3.scale.ordinal()
        .domain(yValue)
        .rangeRoundBands([0, height], .1),
    // this color funciton referencing the linearGradient defind in the HTML part by id 
    color = function (index) {
        console.log(dataset[index][0])
        return "url(#" + dataset[index][0].severity + ")";
    },
    groups = svg.selectAll('g')
        .data(dataset)
        .enter()
        .append('g')
        .style('fill', function (d, i) {
        return color(i);
    });
    var rects = groups.selectAll('rect')
        .data(function (d) {
        return d;
    }).enter();
    rects.append('rect')
        .attr('x', function (d) {
        return xScale(d.x0);
    })
        .attr('y', function (d, i) {
        return yScale(d.y);
    })
        .attr('height', function (d) {
        return yScale.rangeBand();
    })
        .attr('width', function (d) {
        return xScale(d.x);
    });
// locate a label with percentage above each section of the gauge    
rects.append("text")
      .text(function(d,i) { return (d.x * 100) + '%' })
      .attr("x", function(d) { return xScale(d.x0); })
      .style("stroke", '#000000')

Wednesday, February 5, 2014

Google style gauge using D3.js

As a part of a dashboard I'm currently implementing I've popped into great job done by Tomer Doron
For my needs I've tweaked it a bit, see the following jFiddle link.