Showing posts with label tip. Show all posts
Showing posts with label tip. Show all posts

Nov 16, 2016

Regex: Changing case in IntelliJ or Sublime Text

Regex is the ultimate swiss army knife. The kind you can use for years and still not exercise it all. That's how I felt years ago when I first stumbled on using it to solve capitalization problems. I needed a refresher on some of those techniques today and found myself sifting through a lot of incomplete answers online. Using one of them lead to disaster because it overlooked some important details. So I decided to do a quick write up on how to solve a couple real world uppercase and lowercase situations for the next time I need a refresher.

A Good Regex Editor

First, not all regex editors are created equal. You know you have a decent one when it supports upper and lower case conversion. This is one reason I chose Sublime years ago over other popular choices. Also, it was something I missed when I switched to Android Studio from Eclipse because this feature was missing until IntelliJ 15 (fixed in build 142.2822 but barely mentioned). Now that it's baked into Android Studio we no longer have to hop over to Sublime to do heavy lifting in Regex. Test your favorite editor or online regex tool for the techniques listed below and if it doesn't support them, maybe consider a switch.

Real World Example

String Constants into String Resources

We're working tech debt today and I was busy cleaning up an ugly file of String constants. I won't belabor why it existed for this client but only point out that my desire was to convert it into resources instead.

The goal was to convert this:

public static final String EXTERNAL_SHOP_URL = "http://buy.our.stuff.pretty/please";
public static final String EXTERNAL_PRIVACY_POLICY = "http://we.no.steal.you.info/promise";
public static final String EXTERNAL_TERMS_AND_CONDITIONS = "http://you.give.us.arm.and.leg/promptly";
public static final String EXTERNAL_HELP = "https://why.you.has.minor/problem?key=ABC123";

to this (dozens of times):

<string name="external_shop_url">http://buy.our.stuff.pretty/please</string>
<string name="external_privacy_policy">http://we.no.steal.you.info/promise</string>
<string name="external_terms_and_conditions">http://you.give.us.arm.and.leg/promptly</string>
<string name="external_help">https://why.you.has.minor/problem?key=ABC123</string>

The key to accomplishing this is the special \L and \E single character classes when replacing. Like the related \U \u and \l characters, these control the case of characters that come after. \L and \U will make everything that follows lowercase or uppercase, respectively. Similarly, \l and \u will make just the next character upper or lower case. Using that knowledge, press CMD+R to open find and replace and enter a regex similar to the following to pull out the capture groups and convert them to the desired case:

Find:

public static final String ([A-Z_0-9]+)\s*=\s*"([^"]+)";

Replace:

<string name="\L$1\E">$2</string>

Caution: Don't forget \E

When using \L and \U all subsequent characters are converted until the next \U or \L or \E is encountered. This is the detail that most online answers omit. It nearly caused a disaster while I converted URLs because public static final String EXTERNAL_HELP = "https://why.you.has.minor/problem?key=ABC123"; has a case-sensitive key on the end. Changing the case of the entire line also changes the URL keys and that can be very easy to overlook, introducing subtle bugs. Since I wanted the lowercase change to stop after the "name" attribute, I had to change the "replace" regex from:

<string name="\L$1">$2</string>
to:
<string name="\L$1\E">$2</string>
So don't forget \E when appropriate!

Real World Example

camelCaseVariables to/from CONSTANTS

As another quick example, when we want to change constants like VARIABLE_THAT_SHOULD_BE_CAMEL_CASE, it is easiest to do so in two steps. A fancy-pants regex like ([A-Z]+)(_[A-Z]+)* would group all the words together and be useful in a program, where you can iterate over them. Unfortunately, in the simplified world of find/replace, the final capture group ($2) is repeatedly replaced with the last match. So there's no easy way to do this in one step. Instead, use two:

  1. change the case
  2. find: [A-Z_]+\b replace: \L$0
  3. and then convert the underscores.
  4. find: _([a-z]) replace: \u$1

Note: using \b in step one helps avoid converting things like the first letter in "String" by only matching all caps that end with word boundaries. Also, because step 1 can be completed with the IDE shortcut CMD+SHIFT+U it is sometimes handy to use that, instead, and then skip to step 2 to replace the underscores.

To do this in reverse and create constants from variables

  1. convert the camel humps to underscores
  2. find: ([a-z])([A-Z]) replace: $1_\l$2
  3. and then convert to uppercase
  4. find: [a-z]+(_[a-z]+)+ replace: \U$0

Here we make step 2 a little more specific, requiring that the text we find must contain at least one word prefixed with an underscore, so that it only matches the underscored variables that we just created.

Summary (TL;DR)

Regex can be used to change the case of matched groups, which is powerful when done in bulk. Many tools now support this by default, including IntelliJ recently and that should be a factor when selecting an online regex tool. The key is to use \U \L \u \l and \E but most online posts forget to mention \E.

May 3, 2015

Android: Dynamically Coloring Images with Picasso

I'm working on an app where the server provides certain icon images but only in one color. Needing to tint these images, I checked whether the tinting from Lollipop was backward compatible. Nope. Not in AppCompat. That would be too easy! So I had to find another way.

Spoiler alert: Turns out I didn't technically need Picasso.

The Basic Idea: Use ColorFilters!

Fortunately, next Google pointed me to my friend Paul's awesome blog. He gave an excellent overview on Programmatically Coloring Drawables that's worth a quick read. After adapting his solution to my specific needs, I decided to post about my code so that the next time this comes up, I know exactly what to do:

Picasso.with(viewHolder.itemView.getContext())
 .load(iconUrl)
 .fit()
 .centerInside()
 .into(viewHolder.currentWeatherIcon);

int iconColor = viewHolder.itemView.getResources().getColor(R.color.weather_icon_color);
viewHolder.currentWeatherIcon.setColorFilter(
 new PorterDuffColorFilter(iconColor, PorterDuff.Mode.SRC_IN)
);

The core idea was to apply a ColorFilter to the ImageView but, in my case, since I already had an ImageView, I didn't have to go the route of using a Transformer. Instead, I can just apply the ColorFilter to my ImageView, directly. Also, I could leverage a PorterDuffColorFilter since I knew I always want to use Porter Duff Compositing here.

One Step Further: Leverage the ViewHolder!

Given the way a ColorFilter works, I figured this could also be set on the ViewHolder, itself, during construction. So my final, working solution was along the lines of this:

public static class ViewHolder extends RecyclerView.ViewHolder {
    /* [other view holder stuff here] */
    public ImageView currentWeatherIcon;

    public ViewHolder(View v) {
        super(v);
        /* [other view holder stuff here] */
        currentWeatherIcon = (ImageView) v.findViewById(R.id.current_weather_icon);
        currentWeatherIcon.setColorFilter(
                new PorterDuffColorFilter(v.getResources().getColor(
                    R.color.weather_icon_color), PorterDuff.Mode.SRC_IN)
        );
    }
}

// elsewhere in code...
Picasso.with(viewHolder.itemView.getContext())
        .load(iconUrl)
        .fit()
        .centerInside()
        .into(viewHolder.currentWeatherIcon);

Of course, if I needed different icon colors, based on the data, then I'd have to set the color filter inside of onBindViewHolder but in my case, the icon color is always the same so this worked well. Bonus: this solution ended up not even requiring Picasso. I know I'll be coming back to this post in 8-12 months, after I've forgotten half this stuff...

Good thing I wrote it down!

Mar 30, 2013

Using a Custom Prettify Theme with Blogger

This blog entry is using Google's Prettify, which was put in place following the setup outlined, below.


Out with the Old

I've been away from Blogger for some time. After returning, I've noticed a lot has changed. So I updated my template and made a bunch of changes, which promptly broke all the syntax highlighting I configured years ago!

Of course, I then looked into the old syntax highlighter I had. Although it has been moved to gitHub and has some fairly recent contributions, I still decided to go with something else. Partially because it's been around since 2004 and that's ancient in internet years--back in the time when dinosaurs were surfing the net--but mainly because I'm tired of seeing that same syntax highlighter everywhere.

In with the New

I quickly stumbled on this StackOverflow post, which had several solid responses. In my searches, I also found a site with a few "prettify themes" which are an improvement over the default. Combining all this together, here is some sample java code to show the final product:

Final Results (Java Sample)

    /**
     * Reads a file into a String. The current Thread's classloader will attempt
     * to load the given file as a resource and the result will be passed
     * through Apache Common's utility for creating a string from a File.
     * 
     * @param filePath The file to read.
     * @return The string to enjoy.
     * @throws IOException Thrown when the file cannot be found.
     * @see {@link FileUtils#readFileToString(File)}
     */
    public String readFileToString(final String filePath) throws IOException {
        File file = FileUtils.toFile(getClass().getResource(filePath));
        return FileUtils.readFileToString(file);
    }

How It Was Done

If I ever fundamentally change my Blogger theme, I may have to re-apply these settings. So I'm listing the steps to do so here, for future reference:

Step 1: Go to the "Template" section and choose the "Edit Html" button

Step 2: Cut / Paste the following lines of code under the <head> tag:

<!-- START: added to support syntax highlighting via prettify -->
    <link href='http://google-code-prettify.googlecode.com/svn/trunk/src/prettify.css' rel='stylesheet' type='text/css'/>
    <script src='http://google-code-prettify.googlecode.com/svn/trunk/src/prettify.js' type='text/javascript'/>
    <script type='text/javascript'>
        document.addEventListener('DOMContentLoaded',function() {
            prettyPrint();
        });
    </script>
<!-- END: added to support syntax highlighting via prettify -->
Step 3: Go to a site that has prettify themes and download the CSS theme that you want
Step 4: Back in Blogger's "Template" section, click the "Customize" link (to the left of the "Edit Html" link in the picture, above)
Step 5: Paste your CSS in the "Advanced > Add CSS" section


That's it! Once setup is complete, syntax highlighting can be used with code along these lines
<pre class="prettyprint java">
    public void someFunction() {

    }
</pre>

Mar 16, 2010

Eclipse - Run / Debug - The Fast Way

Ok. This was so awesome, I had to stop everything and blog about it, simply because every Eclipse user on earth should hear about this.

Problem

So, in Eclipse, I got fed up always clicking through a thousand menus to run my application. I'm using maven, so to run our project, I have to mouse over to our POM.xml, right click on it, mouse ALL THE WAY down to "Run As" (of course, I always forgetfully mouse over "Maven," instead), then mouse ALL THE WAY down to "Maven build," then I have 6-8 run configurations to choose from so I have to mouse ALL THE WAY over to the middle of the screen and pick one!

Clearly, I HATE MOUSING. So I hunted down a better way.

Now all I have to do is hit COMMAND + SHIFT + F11 (ctrl + F11 on windows) to run my last-used configuration. This command already works by default on plain Java files but when you start getting fancy with the run configurations . . . and Maven . . . and things . . . it doesn't function the same.

Solution

  1. Hit COMMAND + , to open preferences (without the stinkin' mouse!)
  2. Begin typing. Enter "Launching" in the filter box
  3. Open the Launching preferences
  4. In the bottom section, choose "Always launch the previously launched application"
  5. Click OK. Celebrate victory.

This used to be the default behavior in Eclipse. A while ago, it changed so that it now makes a best guess based on your active resource and editor. That works perfectly . . . until you start doing things more complex. Now the CMD+SHFT+F11 shortcut key runs your last run/debug choice! That alone, will save BOATLOADS of time. Some days, I click "Maven Build" no less than 1 billion times!

Feb 11, 2010

Mac OS X : Open Ports, Network Connections, PIDs

Yesterday, my MacBook Pro was acting VERY strangely. I was hacked! (or so I thought) I feared that some evildoer hacked my home network and ran amuck.

Quickly, I had to figure out what was happening on my network. I wanted to know what ports were open, what connections were live and which applications were using those connections. Finding Linux info was easy. Mac OS X info? Not so much!

After hunting dozens of Google pages, here's what I've come up with:

Check All Network Connections
Run the following shell command to display all network connections:
netstat -an | grep 'LIS\|WAIT\|Recv-Q'

This will show all ESTABLISHED, LISTEN and TIME_WAIT connections and also displays the header for convenience.
Show Processes On Network
The command above is good but it doesn't show you WHO is on those ports. The following allows us to see the PID and Name of each process using the network!
sudo lsof -Pnl +M -i

Note: the first flag is -PNL (the last character is not a one). The first time I ran the lsof command, I couldn't see the ports that were listening. This was my main concern (evildoers love listening on ports). The key is to run this command as root (via sudo). Also note, with the netstat call, you can use egrep 'LIS|WAIT'. Honestly, I haven't gotten around to learning what egrep does. All I know is you don't have to escape the | symbol with egrep.