0

I made a jsf page with colorpickers where an administrator will supposedly be able to change the main theme of the site which consist of 4 colors. I prefixed my main colors in my css with numbers as such :

.element{
    background: /*1*/#333333;
}

So to get the colors I just go through all css files and find the color which is after that number (which goes from 1 to 4). It is working fine for getting those but when I'm trying to set the colors and refresh the page I just have no css at all. However when I clean the project the .css is back up with the original colors.

My code is a bit funky but here it is:

@ManagedBean
public class SiteColorsSettings {
    private String color1, color2, color3, color4;
    private final String CSS_FOLDER_PATH = "/resources/css";
    ServletContext ctx;
    String realPath;

    public SiteColorsSettings() {
        ctx = (ServletContext) FacesContext.getCurrentInstance()
                .getExternalContext().getContext();
        realPath = ctx.getRealPath("/");
        getColors();
    }

    public void getColors() {
        try {
            File cssFolder = new File(realPath + CSS_FOLDER_PATH);
            if (!cssFolder.exists()) {
                System.out.println("css folder not found");
            }
            File[] listOfFiles = cssFolder.listFiles();

            for (int i = 0; i < listOfFiles.length; i++) {
                if (listOfFiles[i].isFile()) {
                    String currentLine;
                    BufferedReader br = new BufferedReader(new FileReader(
                            listOfFiles[i]));

                    while ((currentLine = br.readLine()) != null) {
                        if (currentLine.contains("/*1*/")) {
                            this.color1 = currentLine.substring(currentLine
                                    .lastIndexOf("/*1*/") + 6);
                        }
                        if (currentLine.contains("/*2*/")) {
                            this.color2 = currentLine.substring(currentLine
                                    .lastIndexOf("/*2*/") + 6);
                        }
                        if (currentLine.contains("/*3*/")) {
                            this.color3 = currentLine.substring(currentLine
                                    .lastIndexOf("/*3*/") + 6);
                        }
                        if (currentLine.contains("/*4*/")) {
                            this.color4 = currentLine.substring(currentLine
                                    .lastIndexOf("/*4*/") + 6);
                        }
                    }
                }
            }

        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }

    public void setColors() {
        try {
            File cssFolder = new File(realPath + CSS_FOLDER_PATH);
            if (!cssFolder.exists()) {
                System.out.println("css folder not found");
            }
            File[] listOfFiles = cssFolder.listFiles();

            switchColors(listOfFiles);

        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }

    private void switchColors(File[] files) {
        for (int i = 0; i < files.length; i++) {
            try {
                if (files[i].isFile()) {
                    BufferedReader br = new BufferedReader(new FileReader(
                            files[i]));
                    String fileContent = "";
                    String currentLine;
                    while ((currentLine = br.readLine()) != null) {
                        fileContent += currentLine;
                    }
                    for (int j = 1; j <= 4; j++) {
                        if (fileContent.contains("/*" + j + "*/")) {
                            int endOfColorChar = fileContent
                                    .lastIndexOf("/*+j+*/") + 12;
                            String fColor = fileContent.substring(
                                    fileContent.lastIndexOf("/*+j+*/") + 6,
                                    endOfColorChar);
                            switch (j) {
                            case (1):
                                fileContent.replace("/*j*/" + fColor, "/*j*/"
                                        + this.color1);
                                break;
                            case (2):
                                fileContent.replace("/*j*/" + fColor, "/*j*/"
                                        + this.color2);
                                break;
                            case (3):
                                fileContent.replace("/*j*/" + fColor, "/*j*/"
                                        + this.color3);
                                break;
                            case (4):
                                fileContent.replace("/*j*/" + fColor, "/*j*/"
                                        + this.color4);
                                break;
                            }
                            FileWriter fw = new FileWriter(files[i]);
                            BufferedWriter bw = new BufferedWriter(fw);
                            bw.write(fileContent);

                        }
                    }
                }

            } catch (Exception e) {
                e.printStackTrace();
            }
        }

    }

So what's happening ? Am I changing the deployed files while the project stays untouched ? If so why there is no css on my page after the refresh ? I checked the string fileContent and the css is there...

1
  • Frameworks like Richfaces support this with dynamic skinning, maybe worth looking at? Commented May 19, 2015 at 13:56

1 Answer 1

2

I would not recommend changing file content in runtime. You could use a different approach to solve your problem.

  1. Use Expression Language in your .css, like:

    .element{
        background: ##{siteColorsSettings.color1};
    }
    

    Note that this only works if it's referenced via <h:outputStylesheet> and not via <link>.

  2. Add getters and setters to color values in your managed bean.

  3. Persist your color values in database or in configuration (for example, colors.properties) file with a content:

    color1=333333
    color2=777777
    ...
    

    and accessing/changing them using Properties class.

Sign up to request clarification or add additional context in comments.

5 Comments

Thanks for your reply. You say you wouldn't advice changing file content at runtime. However your reply seems to imply that I'll change the file content of a .properties at runtime. Or is it solved by the use of the Properties class ?
Yes, property-files are designed to store possible configurations and Properties class is designed to operate with them.
I'm sorry but did you try your solution ? I doesn't seem to work with the .css file.
I had the same problem as you and this worked for me. Which content of .element{} selector in css is returned in your case? BTW, I didn't post a full-working solution, I did post an approach which worked to me.
Ah it's good to know it can work and I'm not adventuring in a dead end. When I inspect the source code when on the browser the css reads :body{ background-color:##{colors.color1}; }. So the EL doesn't parse it. Did you add something to the css file so it get parsed ? I mapped it to my faces servlet without luck.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.