Gridarta Editor
FilterConfigDecoder.java
Go to the documentation of this file.
1 /*
2  * Gridarta MMORPG map editor for Crossfire, Daimonin and similar games.
3  * Copyright (C) 2000-2015 The Gridarta Developers.
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License along
16  * with this program; if not, write to the Free Software Foundation, Inc.,
17  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18  */
19 
20 package net.sf.gridarta.model.filter;
21 
22 import org.jetbrains.annotations.NotNull;
23 import org.jetbrains.annotations.Nullable;
24 
29 public class FilterConfigDecoder {
30 
34  @NotNull
35  private final StringBuilder sb = new StringBuilder();
36 
41  @NotNull
43 
44  @Override
45  public void visit(@NotNull final NamedFilterConfig filterConfig) {
46  filterConfig.accept(resetToDefaultsVisitor);
47  filterConfig.getFilter().resetConfig(filterConfig);
48 
49  final boolean enabled = removePrefix("enabled");
50  filterConfig.setEnabled(enabled);
51  boolean first = !enabled;
52 
53  final boolean inverted;
54  if (first) {
55  inverted = removePrefix("inverted");
56  } else {
57  inverted = removePrefix(",inverted");
58  }
59  if (inverted) {
60  first = false;
61  }
62  filterConfig.setInverted(inverted);
63 
64  while (true) {
65  if (sb.length() == 0 || sb.charAt(0) == ')') {
66  break;
67  }
68  if (first) {
69  first = false;
70  } else {
71  if (!removePrefix(",")) {
72  break;
73  }
74  }
75  final String key = FilterCodecUtils.decodeString(sb);
76  final FilterConfig<?, ?> subFilterConfig = filterConfig.getEntries().get(key);
77  if (subFilterConfig == null) {
78  throw new NumberFormatException("filter has no key '" + key + "'");
79  }
80  if (!removePrefix("=")) {
81  throw new NumberFormatException("syntax error");
82  }
83  decodeInternal(subFilterConfig);
84  }
85  }
86 
87  @Override
88  public void visit(@NotNull final NamedGameObjectMatcherFilterConfig filterConfig) {
89  filterConfig.accept(resetToDefaultsVisitor);
90 
91  final boolean enabled = removePrefix("enabled");
92  filterConfig.setEnabled(enabled);
93  boolean first = !enabled;
94 
95  while (true) {
96  if (sb.length() == 0 || sb.charAt(0) == ')') {
97  break;
98  }
99  if (first) {
100  first = false;
101  } else {
102  if (!removePrefix(",")) {
103  throw new NumberFormatException("syntax error");
104  }
105  }
106  final String key = FilterCodecUtils.decodeString(sb);
107  if (!removePrefix("=")) {
108  throw new NumberFormatException("syntax error");
109  }
110  filterConfig.setProperty(key, FilterCodecUtils.decodeString(sb));
111  }
112  }
113 
114  };
115 
120  @NotNull
122 
123  @Override
124  public void visit(@NotNull final NamedFilterConfig filterConfig) {
125  filterConfig.setEnabled(false);
126  filterConfig.setInverted(false);
127  filterConfig.getFilter().resetConfig(filterConfig);
128  filterConfig.getEntries().values().forEach(entry -> entry.accept(resetToDefaultsVisitor));
129  }
130 
131  @Override
132  public void visit(@NotNull final NamedGameObjectMatcherFilterConfig filterConfig) {
133  filterConfig.setEnabled(false);
134  filterConfig.removeAllProperties();
135  }
136 
137  };
138 
143  @Nullable
145 
153  public boolean decode(@NotNull final String string, @NotNull final FilterConfig<?, ?> filterConfig) {
154  sb.setLength(0);
155  sb.append(string);
156  try {
157  decodeInternal(filterConfig);
158  } catch (final IndexOutOfBoundsException | NumberFormatException ignored) {
159  return false;
160  }
161  return sb.length() == 0;
162  }
163 
168  private void decodeInternal(@NotNull final FilterConfig<?, ?> filterConfig) {
169  final FilterConfig<?, ?> prevFilterConfig = this.filterConfig;
170  try {
171  if (!removePrefix("(")) {
172  filterConfig.accept(resetToDefaultsVisitor);
173  return;
174  }
175  this.filterConfig = filterConfig;
176  filterConfig.accept(visitor);
177  if (!removePrefix(")")) {
178  throw new NumberFormatException("syntax error");
179  }
180  } finally {
181  this.filterConfig = prevFilterConfig;
182  }
183  }
184 
190  private boolean removePrefix(@NotNull final String string) {
191  final int length = string.length();
192  if (length > sb.length() || !sb.substring(0, length).equals(string)) {
193  return false;
194  }
195 
196  sb.delete(0, length);
197  return true;
198  }
199 
200 }
final FilterConfigVisitor visitor
The FilterConfigVisitor for updating filterConfig from the string representation in sb...
final StringBuilder sb
The string being decoded.
FilterConfig<?, ?> filterConfig
The FilterConfig instance being updated.
boolean decode(@NotNull final String string, @NotNull final FilterConfig<?, ?> filterConfig)
Import the filter configuration settings.
Utility class for codec related functions.
boolean removePrefix(@NotNull final String string)
Tries to remove a prefix from sb.
void accept(@NotNull FilterConfigVisitor visitor)
Visits the appropriate.
static String decodeString(@NotNull final StringBuilder sb)
Decodes a string from a string builder.
Interface for visitors of filter configs.
void decodeInternal(@NotNull final FilterConfig<?, ?> filterConfig)
Updates a file configuration from sb.
Filter configuration of NamedGameObjectMatcherFilter instances.
Converts a string into a FilterConfig.
final FilterConfigVisitor resetToDefaultsVisitor
The FilterConfigVisitor which resets a filterConfig instance to default settings. ...