This Bugzilla instance is a read-only archive of historic NetBeans bug reports. To report a bug in NetBeans please follow the project's instructions for reporting issues.

View | Details | Raw Unified | Return to bug 228022
Collapse All | Expand All

(-)a/openide.io/apichanges.xml (+24 lines)
Lines 107-112 Link Here
107
    <!-- ACTUAL CHANGES BEGIN HERE: -->
107
    <!-- ACTUAL CHANGES BEGIN HERE: -->
108
108
109
<changes>
109
<changes>
110
    <change id="Folding">
111
      <api name="io"/>
112
      <summary>Adding API to have support for folding of lines</summary>
113
      <version major="1" minor="38"/>
114
      <date day="5" month="4" year="2013"/>
115
      <author login="jhavlin"/>
116
      <compatibility addition="yes" binary="compatible" semantic="compatible" />
117
      <description>
118
          <p>Adding class IOFolding for checking that folding is supported and
119
              for creating folds in output window, and class FoldHandle for
120
              finishing the folds and creation of nested folds.</p>
121
          <p> See
122
              <code>
123
                  <a href="@TOP@/org/openide/windows/IOFolding.html">
124
                      IOFolding</a>,
125
                  <a href="@TOP@/org/openide/windows/FoldHandle.html">
126
                      FoldHandle</a>.
127
              </code>
128
          </p>
129
      </description>
130
      <class package="org.openide.windows" name="IOFolding"/>
131
      <class package="org.openide.windows" name="FoldHandle"/>
132
      <issue number="228022" />
133
    </change>
110
    <change id="getIO-4-params">
134
    <change id="getIO-4-params">
111
      <api name="io"/>
135
      <api name="io"/>
112
      <summary>Added IOProvider.getIO variant that takes all 4 possible parameters.</summary>
136
      <summary>Added IOProvider.getIO variant that takes all 4 possible parameters.</summary>
(-)a/openide.io/manifest.mf (-1 / +1 lines)
Lines 1-6 Link Here
1
Manifest-Version: 1.0
1
Manifest-Version: 1.0
2
OpenIDE-Module: org.openide.io
2
OpenIDE-Module: org.openide.io
3
OpenIDE-Module-Specification-Version: 1.37
3
OpenIDE-Module-Specification-Version: 1.38
4
OpenIDE-Module-Localizing-Bundle: org/openide/io/Bundle.properties
4
OpenIDE-Module-Localizing-Bundle: org/openide/io/Bundle.properties
5
OpenIDE-Module-Recommends: org.openide.windows.IOProvider, org.openide.windows.IOContainer$Provider
5
OpenIDE-Module-Recommends: org.openide.windows.IOProvider, org.openide.windows.IOContainer$Provider
6
AutoUpdate-Essential-Module: true
6
AutoUpdate-Essential-Module: true
(-)a/openide.io/nbproject/project.xml (-1 / +10 lines)
Lines 46-52 Link Here
46
<project xmlns="http://www.netbeans.org/ns/project/1">
46
<project xmlns="http://www.netbeans.org/ns/project/1">
47
    <type>org.netbeans.modules.apisupport.project</type>
47
    <type>org.netbeans.modules.apisupport.project</type>
48
    <configuration>
48
    <configuration>
49
        <data xmlns="http://www.netbeans.org/ns/nb-module-project/2">
49
        <data xmlns="http://www.netbeans.org/ns/nb-module-project/3">
50
            <code-name-base>org.openide.io</code-name-base>
50
            <code-name-base>org.openide.io</code-name-base>
51
            <module-dependencies>
51
            <module-dependencies>
52
                <dependency>
52
                <dependency>
Lines 75-80 Link Here
75
                    </run-dependency>
75
                    </run-dependency>
76
                </dependency>
76
                </dependency>
77
            </module-dependencies>
77
            </module-dependencies>
78
            <test-dependencies>
79
                <test-type>
80
                    <name>unit</name>
81
                    <test-dependency>
82
                        <code-name-base>org.netbeans.libs.junit4</code-name-base>
83
                        <compile-dependency/>
84
                    </test-dependency>
85
                </test-type>
86
            </test-dependencies>
78
            <public-packages>
87
            <public-packages>
79
                <package>org.openide.windows</package>
88
                <package>org.openide.windows</package>
80
            </public-packages>
89
            </public-packages>
(-)a/openide.io/src/org/openide/windows/FoldHandle.java (+91 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2013 Oracle and/or its affiliates. All rights reserved.
5
 *
6
 * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
7
 * Other names may be trademarks of their respective owners.
8
 *
9
 * The contents of this file are subject to the terms of either the GNU
10
 * General Public License Version 2 only ("GPL") or the Common
11
 * Development and Distribution License("CDDL") (collectively, the
12
 * "License"). You may not use this file except in compliance with the
13
 * License. You can obtain a copy of the License at
14
 * http://www.netbeans.org/cddl-gplv2.html
15
 * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
16
 * specific language governing permissions and limitations under the
17
 * License.  When distributing the software, include this License Header
18
 * Notice in each file and include the License file at
19
 * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
20
 * particular file as subject to the "Classpath" exception as provided
21
 * by Oracle in the GPL Version 2 section of the License file that
22
 * accompanied this code. If applicable, add the following below the
23
 * License Header, with the fields enclosed by brackets [] replaced by
24
 * your own identifying information:
25
 * "Portions Copyrighted [year] [name of copyright owner]"
26
 *
27
 * If you wish your version of this file to be governed by only the CDDL
28
 * or only the GPL Version 2, indicate your decision by adding
29
 * "[Contributor] elects to include this software in this distribution
30
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
31
 * single choice of license, a recipient has the option to distribute
32
 * your version of this file under either the CDDL, the GPL Version 2 or
33
 * to extend the choice of license to its licensees as provided above.
34
 * However, if you add GPL Version 2 code and therefore, elected the GPL
35
 * Version 2 license, then the option applies only if the new code is
36
 * made subject to such option by the copyright holder.
37
 *
38
 * Contributor(s):
39
 *
40
 * Portions Copyrighted 2013 Sun Microsystems, Inc.
41
 */
42
43
package org.openide.windows;
44
45
import org.openide.windows.IOFolding.FoldHandleDefinition;
46
47
/**
48
 * An object that refers to a fold in output window. It can be used to finish
49
 * the fold, or to create nested folds.
50
 *
51
 * @author jhavlin
52
 * @since openide.io/1.38
53
 */
54
public final class FoldHandle {
55
56
    private final FoldHandleDefinition definition;
57
58
    FoldHandle(FoldHandleDefinition definition) {
59
        this.definition = definition;
60
    }
61
62
    /**
63
     * Finish the fold at the current last line in the output window.
64
     *
65
     * @throws IllegalStateException if parent fold has been already finished,
66
     * or if there is an unfinished child fold.
67
     */
68
    public void finish() {
69
        definition.finish();
70
    }
71
72
    /**
73
     * Start a nested fold at the current last line in output window.
74
     *
75
     * @param expanded True to expand the new fold, false to collapse it.
76
     * @return Handle for the newly created fold.
77
     * @throws IllegalStateException if the fold has been already finished.
78
     */
79
    public FoldHandle startFold(boolean expanded) {
80
        return new FoldHandle(definition.startFold(expanded));
81
    }
82
83
    /**
84
     * Set state of the fold.
85
     *
86
     * @param expanded True to expand the fold, false to collapse it.
87
     */
88
    public void setExpanded(boolean expanded) {
89
        definition.setExpanded(expanded);
90
    }
91
}
(-)a/openide.io/src/org/openide/windows/IOFolding.java (+183 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2013 Oracle and/or its affiliates. All rights reserved.
5
 *
6
 * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
7
 * Other names may be trademarks of their respective owners.
8
 *
9
 * The contents of this file are subject to the terms of either the GNU
10
 * General Public License Version 2 only ("GPL") or the Common
11
 * Development and Distribution License("CDDL") (collectively, the
12
 * "License"). You may not use this file except in compliance with the
13
 * License. You can obtain a copy of the License at
14
 * http://www.netbeans.org/cddl-gplv2.html
15
 * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
16
 * specific language governing permissions and limitations under the
17
 * License.  When distributing the software, include this License Header
18
 * Notice in each file and include the License file at
19
 * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
20
 * particular file as subject to the "Classpath" exception as provided
21
 * by Oracle in the GPL Version 2 section of the License file that
22
 * accompanied this code. If applicable, add the following below the
23
 * License Header, with the fields enclosed by brackets [] replaced by
24
 * your own identifying information:
25
 * "Portions Copyrighted [year] [name of copyright owner]"
26
 *
27
 * If you wish your version of this file to be governed by only the CDDL
28
 * or only the GPL Version 2, indicate your decision by adding
29
 * "[Contributor] elects to include this software in this distribution
30
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
31
 * single choice of license, a recipient has the option to distribute
32
 * your version of this file under either the CDDL, the GPL Version 2 or
33
 * to extend the choice of license to its licensees as provided above.
34
 * However, if you add GPL Version 2 code and therefore, elected the GPL
35
 * Version 2 license, then the option applies only if the new code is
36
 * made subject to such option by the copyright holder.
37
 *
38
 * Contributor(s):
39
 *
40
 * Portions Copyrighted 2013 Sun Microsystems, Inc.
41
 */
42
package org.openide.windows;
43
44
import org.netbeans.api.annotations.common.CheckReturnValue;
45
import org.netbeans.api.annotations.common.NonNull;
46
import org.openide.util.Lookup;
47
import org.openide.util.Lookup.Provider;
48
import org.openide.util.Parameters;
49
50
/**
51
 * Folding of group of lines in Output Window.
52
 * <p>
53
 * Client usage:
54
 * </p>
55
 * <pre>
56
 *  InputOutput io = ...;
57
 *  if (!IOFolding.isSupported(io)) {
58
 *    throw new Exception("Folding is not supported");
59
 *  }
60
 *  io.getOut().println("First Line - start of fold");
61
 *  FoldHandle fold = IOFolding.startFold(io, true);
62
 *  io.getOut().println("  Fold Content 1");
63
 *  io.getOut().println("  The first line of nested fold");
64
 *  FoldHandle nestedFold = fold.startFold(true);
65
 *  io.getOut().println("     Nested fold content 1");
66
 *  nestedFold.finish();
67
 *  io.getOut().println("  Fold Content 2");
68
 *  fold.finish();
69
 *  io.getOut().println("Text outside of the fold.");
70
 * </pre>
71
 * <p>
72
 * How to support {@link IOFolding} in own {@link IOProvider} implementation:
73
 * </p>
74
 * <ul>
75
 * <li> {@link InputOutput} provided by {@link IOProvider} has to implement
76
 * {@link Provider}</li>
77
 * <li> Extend {@link IOFolding} and implement its abstract methods</li>
78
 * <li> Extend {@link FoldHandleDefinition}</li>
79
 * <li> Place instance of {@link IOFolding} to {@link Lookup} provided by
80
 * {@link InputOutput}</li>
81
 * </ul>
82
 *
83
 * @author jhavlin
84
 * @since openide.io/1.38
85
 */
86
public abstract class IOFolding {
87
88
    /**
89
     * Check whether an {@link InputOutput} supports folding.
90
     *
91
     * @param io The InputOutput to check.
92
     * @return True if {@link #startFold(InputOutput, boolean)} can be used with
93
     * {@code io}, false otherwise.
94
     */
95
    public static boolean isSupported(@NonNull InputOutput io) {
96
        Parameters.notNull("parent", io);                               //NOI18N
97
        return findIOFolding(io) != null;
98
    }
99
100
    /**
101
     * Find folding support in an {@link InputOutput} object.
102
     *
103
     * @return IOFolding object if folding is supported by the {@code parent}
104
     * object, null otherwise.
105
     */
106
    private static IOFolding findIOFolding(InputOutput parent) {
107
        return (parent instanceof Lookup.Provider)
108
                ? ((Lookup.Provider) parent).getLookup().lookup(IOFolding.class)
109
                : null;
110
    }
111
112
    /**
113
     * Create a fold handle definition for the current last line in the output
114
     * window.
115
     *
116
     * @param expanded Initial state of the fold.
117
     * @return FoldHandleDefinition for the fold handle. Never null.
118
     *
119
     * @throws IllegalStateException if the last fold hasn't been finished yet.
120
     */
121
    @NonNull
122
    protected abstract FoldHandleDefinition startFold(boolean expanded);
123
124
    /**
125
     * Create a fold handle for the current last line in the output window.
126
     *
127
     * @param io InputOutput to create the fold in.
128
     * @param expanded Initial state of the fold.
129
     * @return The fold handle that can be used to finish the fold or to create
130
     * nested folds.
131
     * @throws IllegalStateException if the last fold hasn't been finished yet.
132
     * @throws UnsupportedOperationException if folding is not supported by the
133
     * InputOutput object.
134
     */
135
    @CheckReturnValue
136
    @NonNull
137
    public static FoldHandle startFold(
138
            @NonNull InputOutput io, boolean expanded) {
139
140
        Parameters.notNull("io", io);                                   //NOI18N
141
        IOFolding folding = findIOFolding(io);
142
        if (folding == null) {
143
            throw new UnsupportedOperationException(
144
                    "The InputOutput doesn't support folding");         //NOI18N
145
        } else {
146
            return new FoldHandle(folding.startFold(expanded));
147
        }
148
    }
149
150
    /**
151
     * An SPI for creating custom FoldHandle implementations.
152
     */
153
    protected static abstract class FoldHandleDefinition {
154
155
        /**
156
         * Finish the fold at the current last line. Ensure that nested folds
157
         * are finished correctly.
158
         *
159
         * @throws IllegalStateException if parent fold has been already
160
         * finished, or if there is an unfinished nested fold.
161
         */
162
        public abstract void finish();
163
164
        /**
165
         * Start a new fold at the current last line. Ensure that the parent
166
         * fold hasn't been finished yet.
167
         *
168
         * @param expanded If false, the fold will be collapsed by default,
169
         * otherwise it will be expanded.
170
         * @return FoldHandleDefinition of handle for the newly created fold.
171
         * @throws IllegalStateException if the fold has been already finished,
172
         * or if the last nested fold hasn't been finished yet.
173
         */
174
        public abstract FoldHandleDefinition startFold(boolean expanded);
175
176
        /**
177
         * Set state of the fold.
178
         *
179
         * @param expanded True to expand the fold, false to collapse it.
180
         */
181
        public abstract void setExpanded(boolean expanded);
182
    }
183
}
(-)a/openide.io/test/unit/src/org/openide/windows/IOFoldingTest.java (+243 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2013 Oracle and/or its affiliates. All rights reserved.
5
 *
6
 * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
7
 * Other names may be trademarks of their respective owners.
8
 *
9
 * The contents of this file are subject to the terms of either the GNU
10
 * General Public License Version 2 only ("GPL") or the Common
11
 * Development and Distribution License("CDDL") (collectively, the
12
 * "License"). You may not use this file except in compliance with the
13
 * License. You can obtain a copy of the License at
14
 * http://www.netbeans.org/cddl-gplv2.html
15
 * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
16
 * specific language governing permissions and limitations under the
17
 * License.  When distributing the software, include this License Header
18
 * Notice in each file and include the License file at
19
 * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
20
 * particular file as subject to the "Classpath" exception as provided
21
 * by Oracle in the GPL Version 2 section of the License file that
22
 * accompanied this code. If applicable, add the following below the
23
 * License Header, with the fields enclosed by brackets [] replaced by
24
 * your own identifying information:
25
 * "Portions Copyrighted [year] [name of copyright owner]"
26
 *
27
 * If you wish your version of this file to be governed by only the CDDL
28
 * or only the GPL Version 2, indicate your decision by adding
29
 * "[Contributor] elects to include this software in this distribution
30
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
31
 * single choice of license, a recipient has the option to distribute
32
 * your version of this file under either the CDDL, the GPL Version 2 or
33
 * to extend the choice of license to its licensees as provided above.
34
 * However, if you add GPL Version 2 code and therefore, elected the GPL
35
 * Version 2 license, then the option applies only if the new code is
36
 * made subject to such option by the copyright holder.
37
 *
38
 * Contributor(s):
39
 *
40
 * Portions Copyrighted 2013 Sun Microsystems, Inc.
41
 */
42
package org.openide.windows;
43
44
import java.io.Reader;
45
import static org.junit.Assert.*;
46
import org.junit.Test;
47
import org.openide.util.Lookup;
48
import org.openide.util.lookup.Lookups;
49
50
/**
51
 *
52
 * @author jhavlin
53
 */
54
public class IOFoldingTest {
55
56
    @Test
57
    public void testStartFold() {
58
        InputOutputWithFolding io = new InputOutputWithFolding();
59
        FoldHandle fold1 = IOFolding.startFold(io, true);
60
        assertEquals(1, io.currentLevel);
61
        FoldHandle fold2 = fold1.startFold(true);
62
        assertEquals(2, io.currentLevel);
63
        fold2.finish();
64
        assertEquals(1, io.currentLevel);
65
        fold1.finish();
66
        assertEquals(0, io.currentLevel);
67
    }
68
69
    @Test(expected = UnsupportedOperationException.class)
70
    public void testStartFoldedUnsupported() {
71
        FoldHandle f = IOFolding.startFold(new DummyInputOutput(), true);
72
    }
73
74
    @Test(expected = IllegalStateException.class)
75
    public void testStartFoldIllegal() {
76
        InputOutputWithFolding io = new InputOutputWithFolding();
77
        FoldHandle f1 = IOFolding.startFold(io, true);
78
        FoldHandle f2 = IOFolding.startFold(io, true);
79
    }
80
81
    @Test(expected = IllegalStateException.class)
82
    public void testFinishIllegal() {
83
        InputOutputWithFolding io = new InputOutputWithFolding();
84
        FoldHandle f1 = IOFolding.startFold(io, true);
85
        FoldHandle f2 = f1.startFold(true);
86
        f1.finish();
87
    }
88
89
    @Test
90
    public void testIsSupported() {
91
        assertTrue(IOFolding.isSupported(new InputOutputWithFolding()));
92
    }
93
94
    @Test
95
    public void testIsSupportedUnsupported() {
96
        assertFalse(IOFolding.isSupported(new DummyInputOutput()));
97
    }
98
99
    /**
100
     * Dummy InputOutput that supports folding.
101
     */
102
    private static class InputOutputWithFolding extends DummyInputOutput
103
            implements Lookup.Provider {
104
105
        private final Lookup lookup = Lookups.fixed(new DummyIOFolding());
106
107
        private DummyIOFolding.DummyFoldHandleDef currentFold = null;
108
        private int currentLevel = 0;
109
110
        @Override
111
        public Lookup getLookup() {
112
            return lookup;
113
        }
114
115
        private class DummyIOFolding extends IOFolding {
116
117
            @Override
118
            protected FoldHandleDefinition startFold(boolean expanded) {
119
                if (currentFold != null) {
120
                    throw new IllegalStateException("Last fold not finished");
121
                } else {
122
                    currentFold = new DummyFoldHandleDef(null);
123
                    currentLevel++;
124
                    return currentFold;
125
                }
126
            }
127
128
            private class DummyFoldHandleDef extends FoldHandleDefinition {
129
130
                private DummyFoldHandleDef nested = null;
131
                private final DummyFoldHandleDef parent;
132
133
                public DummyFoldHandleDef(DummyFoldHandleDef parent) {
134
                    this.parent = parent;
135
                }
136
137
                @Override
138
                public void finish() {
139
                    if (nested != null) {
140
                        throw new IllegalStateException("A nested fold exists.");
141
                    } else if (parent == null) {
142
                        currentFold = null;
143
                    } else {
144
                        parent.nested = null;
145
                    }
146
                    currentLevel--;
147
                }
148
149
                @Override
150
                public FoldHandleDefinition startFold(boolean expanded) {
151
                    if (nested != null) {
152
                        throw new IllegalStateException("Last fold not finished.");
153
                    } else {
154
                        nested = new DummyFoldHandleDef(this);
155
                        currentLevel++;
156
                        return nested;
157
                    }
158
                }
159
160
                @Override
161
                public void setExpanded(boolean expanded) {
162
                }
163
            }
164
        }
165
    }
166
167
    /**
168
     * Dummy implementation of InputOutput.
169
     */
170
    private static class DummyInputOutput implements InputOutput {
171
172
        @Override
173
        public OutputWriter getOut() {
174
            throw new UnsupportedOperationException("Not supported yet.");
175
        }
176
177
        @Override
178
        public Reader getIn() {
179
            throw new UnsupportedOperationException("Not supported yet.");
180
        }
181
182
        @Override
183
        public OutputWriter getErr() {
184
            throw new UnsupportedOperationException("Not supported yet.");
185
        }
186
187
        @Override
188
        public void closeInputOutput() {
189
            throw new UnsupportedOperationException("Not supported yet.");
190
        }
191
192
        @Override
193
        public boolean isClosed() {
194
            throw new UnsupportedOperationException("Not supported yet.");
195
        }
196
197
        @Override
198
        public void setOutputVisible(boolean value) {
199
            throw new UnsupportedOperationException("Not supported yet.");
200
        }
201
202
        @Override
203
        public void setErrVisible(boolean value) {
204
            throw new UnsupportedOperationException("Not supported yet.");
205
        }
206
207
        @Override
208
        public void setInputVisible(boolean value) {
209
            throw new UnsupportedOperationException("Not supported yet.");
210
        }
211
212
        @Override
213
        public void select() {
214
            throw new UnsupportedOperationException("Not supported yet.");
215
        }
216
217
        @Override
218
        public boolean isErrSeparated() {
219
            throw new UnsupportedOperationException("Not supported yet.");
220
        }
221
222
        @Override
223
        public void setErrSeparated(boolean value) {
224
            throw new UnsupportedOperationException("Not supported yet.");
225
        }
226
227
        @Override
228
        public boolean isFocusTaken() {
229
            throw new UnsupportedOperationException("Not supported yet.");
230
        }
231
232
        @Override
233
        public void setFocusTaken(boolean value) {
234
            throw new UnsupportedOperationException("Not supported yet.");
235
        }
236
237
        @Override
238
        @Deprecated
239
        public Reader flushReader() {
240
            throw new UnsupportedOperationException("Not supported yet.");
241
        }
242
    }
243
}

Return to bug 228022