1
/*******************************************************************************
2
* Copyright (c) 2013 Google, Inc and others.
3
* All rights reserved. This program and the accompanying materials
4
* are made available under the terms of the Eclipse Public License v1.0
5
* which accompanies this distribution, and is available at
6
* http://www.eclipse.org/legal/epl-v10.html
9
* Sergey Prigogin (Google) - initial API and implementation
10
*******************************************************************************/
11
package org.eclipse.cdt.internal.ui.refactoring.includes;
13
import java.io.IOException;
14
import java.io.Reader;
15
import java.io.StringReader;
16
import java.io.StringWriter;
17
import java.util.ArrayList;
18
import java.util.Collections;
19
import java.util.List;
21
import org.eclipse.ui.IMemento;
22
import org.eclipse.ui.WorkbenchException;
23
import org.eclipse.ui.XMLMemento;
25
import org.eclipse.cdt.ui.CUIPlugin;
27
import org.eclipse.cdt.internal.corext.codemanipulation.IncludeInfo;
30
* A set of header file substitution rules.
32
public class HeaderSubstitutionMap {
33
private static final String TAG_HEADER_SUBSTITUTION_MAPS = "maps"; //$NON-NLS-1$
34
private static final String TAG_HEADER_SUBSTITUTION_MAP = "map"; //$NON-NLS-1$
35
private static final String TAG_NAME = "name"; //$NON-NLS-1$
36
private static final String TAG_CPP_ONLY = "cpp_only"; //$NON-NLS-1$
37
private static final String TAG_UNCONDITIONAL_SUBSTITUTION_MAP = "unconditional_substitution_map"; //$NON-NLS-1$
38
private static final String TAG_OPTIONAL_SUBSTITUTION_MAP = "optional_substitution_map"; //$NON-NLS-1$
41
private boolean cppOnly;
42
private final IncludeMap unconditionalSubstitutionMap;
43
private final IncludeMap optionalSubstitutionMap;
45
public HeaderSubstitutionMap(boolean cppOnly) {
46
this.cppOnly = cppOnly;
47
this.unconditionalSubstitutionMap = new IncludeMap(true);
48
this.optionalSubstitutionMap = new IncludeMap(false);
51
public HeaderSubstitutionMap(String name, boolean cppOnly,
52
IncludeMap unconditionalSubstitutionMap, IncludeMap optionalSubstitutionMap) {
54
this.cppOnly = cppOnly;
55
this.unconditionalSubstitutionMap = unconditionalSubstitutionMap;
56
this.optionalSubstitutionMap = optionalSubstitutionMap;
60
* Indicates that the header file {@code to} should be used instead of {@code from}.
62
* @param from The header file to be replaced.
63
* @param to The header file to be used instead.
64
* @param unconditionalSubstitution {@code true} if the header substitution is mandatory.
65
* Otherwise substitution only if the {@code to} header has to be included for other
68
protected void addMapping(IncludeInfo from, IncludeInfo to, boolean unconditionalSubstitution) {
69
IncludeMap map = unconditionalSubstitution ? unconditionalSubstitutionMap : optionalSubstitutionMap;
70
map.addMapping(from, to);
74
* Indicates that the header file {@code to} should be used instead of {@code from}.
76
* @param from The header file to be replaced. The header is represented by an include name
77
* optionally surrounded by double quotes or angle brackets. Angle brackets indicate
79
* @param to The header file to be used instead. The header is represented by an include name
80
* optionally surrounded by double quotes or angle brackets. Angle brackets indicate
82
* @param unconditionalSubstitution {@code true} if the header substitution is mandatory.
83
* Otherwise substitution only if the {@code to} header has to be included for other
86
public void addMapping(String from, String to, boolean unconditionalSubstitution) {
87
IncludeMap map = unconditionalSubstitution ? unconditionalSubstitutionMap : optionalSubstitutionMap;
88
map.addMapping(from, to);
91
public String getName() {
95
public void setName(String name) {
99
public boolean isCppOnly() {
103
public void setCppOnly(boolean cppOnly) {
104
this.cppOnly = cppOnly;
107
public void saveToMemento(IMemento memento) {
109
memento.putString(TAG_NAME, name);
110
memento.putBoolean(TAG_CPP_ONLY, cppOnly);
111
unconditionalSubstitutionMap.saveToMemento(memento.createChild(TAG_UNCONDITIONAL_SUBSTITUTION_MAP));
112
optionalSubstitutionMap.saveToMemento(memento.createChild(TAG_OPTIONAL_SUBSTITUTION_MAP));
115
public static HeaderSubstitutionMap fromMemento(IMemento memento) {
116
String name = memento.getString(TAG_NAME);
117
Boolean b = memento.getBoolean(TAG_CPP_ONLY);
118
boolean cppOnly = b != null && b.booleanValue();
119
IncludeMap unconditionalSubstitutionMap = IncludeMap.fromMemento(true, memento.getChild(TAG_UNCONDITIONAL_SUBSTITUTION_MAP));
120
IncludeMap optionalSubstitutionMap = IncludeMap.fromMemento(false, memento.getChild(TAG_OPTIONAL_SUBSTITUTION_MAP));
121
// Remove potential redundant substitutions from optionalSubstitutionMap.
122
for (IncludeInfo header : unconditionalSubstitutionMap.getMap().keySet()) {
123
optionalSubstitutionMap.removeMapping(header);
125
return new HeaderSubstitutionMap(name, cppOnly, unconditionalSubstitutionMap, optionalSubstitutionMap);
128
public static HeaderSubstitutionMap fromSerializedMemento(String str) {
129
return fromSerializedMemento(new StringReader(str));
132
public static HeaderSubstitutionMap fromSerializedMemento(Reader reader) {
135
memento = XMLMemento.createReadRoot(reader);
136
} catch (WorkbenchException e) {
139
return fromMemento(memento);
142
public static String serializeMaps(List<HeaderSubstitutionMap> maps) {
143
XMLMemento memento = XMLMemento.createWriteRoot(TAG_HEADER_SUBSTITUTION_MAPS);
144
for (HeaderSubstitutionMap element : maps) {
145
element.saveToMemento(memento.createChild(TAG_HEADER_SUBSTITUTION_MAP));
147
StringWriter writer = new StringWriter();
149
memento.save(writer);
150
} catch (IOException e) {
153
return writer.toString();
156
public static List<HeaderSubstitutionMap> deserializeMaps(String str) {
157
StringReader reader = new StringReader(str);
160
memento = XMLMemento.createReadRoot(reader);
161
} catch (WorkbenchException e) {
162
return Collections.emptyList();
165
List<HeaderSubstitutionMap> maps = new ArrayList<HeaderSubstitutionMap>();
166
for (IMemento element : memento.getChildren(TAG_HEADER_SUBSTITUTION_MAP)) {
167
maps.add(fromMemento(element));
172
public IncludeMap getUnconditionalSubstitutionMap() {
173
return unconditionalSubstitutionMap;
176
public IncludeMap getOptionalSubstitutionMap() {
177
return optionalSubstitutionMap;
b'\\ No newline at end of file'