73fab1a6c81d4ca9476c8a1b6cc2277b9b0215cd
[mdsal.git] / binding2 / mdsal-binding2-generator-util / src / main / java / org / opendaylight / mdsal / binding / javav2 / generator / util / YangSnippetCleaner.java
1 /*
2  * Copyright (c) 2017 Cisco Systems, Inc. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.mdsal.binding.javav2.generator.util;
9
10 import com.google.common.annotations.Beta;
11 import java.util.regex.Pattern;
12 import javax.annotation.RegEx;
13 import org.apache.commons.lang3.StringUtils;
14
15 /**
16  * Util class for cleaning yang models of excess whitespaces
17  *
18  */
19 @Beta
20 public final class YangSnippetCleaner {
21
22     private static final String[] RESERVED_LINES = { "yang-version", "namespace" };
23
24     @RegEx
25     private static final String NEW_LINE_REGEX = "\\r?\\n";
26     private static final Pattern NEW_LINE_PATTERN = Pattern.compile(NEW_LINE_REGEX);
27
28     @RegEx
29     private static final String WS_REGEX = "\\s+";
30     private static final Pattern WS_PATTERN = Pattern.compile(WS_REGEX);
31
32     private static final String START_BODY = "{";
33     private static final String END_BODY = "}";
34     private static final String KEY_PART = "key \"";
35     private static final String UNIQUE_PART = "unique \"";
36     private static final String SPECIAL_END_LINE = "\";";
37
38     private static final char NEW_LINE = '\n';
39     private static final char SPACE = ' ';
40
41     private static final int INDENT = 4;
42
43     private YangSnippetCleaner() {
44         throw new UnsupportedOperationException("Util class");
45     }
46
47     /**
48      * Cleaning yang model of excess whitespaces, adding indentations
49      *
50      * @param unformedYang
51      *            - unformed yang model
52      * @return cleaned yang model
53      */
54     public static String clean(final String unformedYang) {
55         int indentCount = 0;
56         final StringBuilder sb = new StringBuilder();
57         final String[] splitter = unformedYang.split(NEW_LINE_PATTERN.pattern());
58
59         for (int i = 0; i < splitter.length; i++) {
60             if (!StringUtils.isBlank(splitter[i])) {
61                 String line = cleanLine(splitter[i]);
62                 if(line.equals(START_BODY)) {
63                     indentCount = mergeWithPrevious(sb, indentCount);
64                     continue;
65                 }
66                 if ((line.contains(KEY_PART) || line.contains(UNIQUE_PART)) && line.endsWith(SPECIAL_END_LINE)) {
67                     line = new StringBuilder(line.substring(0, line.indexOf(SPECIAL_END_LINE) - 1))
68                             .append(SPECIAL_END_LINE).toString();
69                 }
70                 indentCount = lineIndent(sb, indentCount, line);
71                 sb.append(line).append(NEW_LINE);
72                 if (!StringUtils.startsWithAny(line, RESERVED_LINES) && indentCount == 1 && i != 0) {
73                         sb.append(NEW_LINE);
74                 }
75             }
76         }
77         if (sb.toString().isEmpty()) {
78             return sb.toString();
79         }
80         if (sb.charAt(sb.length() - 4) == NEW_LINE && sb.charAt(sb.length() - 3) == NEW_LINE) {
81             sb.deleteCharAt(sb.length() - 3);
82         }
83         removeRemainingWhitespace(sb);
84         sb.append(NEW_LINE);
85
86         return sb.toString();
87     }
88
89     private static int mergeWithPrevious(final StringBuilder sb, final int indentCount) {
90         int newIndentCount = indentCount;
91         removeRemainingWhitespace(sb);
92         sb.append(SPACE);
93         sb.append(START_BODY);
94         sb.append(NEW_LINE);
95         return ++newIndentCount;
96     }
97
98     private static void removeRemainingWhitespace(final StringBuilder sb) {
99         while (StringUtils.isWhitespace(String.valueOf(sb.charAt(sb.length() - 1)))) {
100             sb.deleteCharAt(sb.length() - 1);
101         }
102     }
103
104     private static String cleanLine(final String split) {
105         final StringBuilder sb = new StringBuilder();
106         final String[] s = split.split(WS_PATTERN.pattern());
107         for (int i = 0; i < s.length; i++) {
108             if (!StringUtils.isBlank(s[i])) {
109                 sb.append(s[i]);
110                 if (i != (s.length - 1)) {
111                     sb.append(SPACE);
112                 }
113             }
114         }
115         return sb.toString();
116     }
117
118     private static int lineIndent(final StringBuilder sb, final int indentCount, final String line) {
119         int newIndentCount = indentCount;
120         if (line.contains(END_BODY) && !line.contains(START_BODY)) {
121             newIndentCount--;
122         }
123         for (int i = 0; i < (newIndentCount * INDENT); i++) {
124             sb.append(SPACE);
125         }
126
127         if (line.contains(START_BODY) && !line.contains(END_BODY)) {
128             newIndentCount++;
129         }
130
131         return newIndentCount;
132     }
133 }