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...

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
Ced
  • 15,847
  • 14
  • 87
  • 146

1 Answers1

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.

Community
  • 1
  • 1
olexd
  • 1,360
  • 3
  • 13
  • 26
  • 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 ? – Ced May 20 '15 at 23:58
  • Yes, property-files are designed to store possible configurations and Properties class is designed to operate with them. – olexd May 21 '15 at 08:15
  • I'm sorry but did you try your solution ? I doesn't seem to work with the .css file. – Ced May 21 '15 at 13:33
  • 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. – olexd May 21 '15 at 14:01
  • 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. – Ced May 21 '15 at 15:55