├── README.md ├── components └── org.wso2.carbon.uiserver │ └── src │ ├── test │ ├── resources │ │ ├── apps │ │ │ ├── full-app │ │ │ │ ├── public │ │ │ │ │ ├── js │ │ │ │ │ │ └── bundle.js │ │ │ │ │ └── css │ │ │ │ │ │ └── styles.css │ │ │ │ ├── themes │ │ │ │ │ └── light │ │ │ │ │ │ └── css │ │ │ │ │ │ └── styles.css │ │ │ │ ├── extensions │ │ │ │ │ └── widgets │ │ │ │ │ │ └── line-chart │ │ │ │ │ │ ├── css │ │ │ │ │ │ └── styles.css │ │ │ │ │ │ └── widget.json │ │ │ │ ├── i18n │ │ │ │ │ ├── en.json │ │ │ │ │ └── some-other-file.txt │ │ │ │ ├── configuration.yaml │ │ │ │ └── pages │ │ │ │ │ └── index.hbs │ │ │ ├── empty-app │ │ │ │ └── readme.txt │ │ │ └── minimal-app │ │ │ │ └── pages │ │ │ │ └── index.html │ │ └── testng.xml │ └── java │ │ └── org │ │ └── wso2 │ │ └── carbon │ │ └── uiserver │ │ ├── api │ │ ├── ServerConfigurationTest.java │ │ ├── http │ │ │ └── HttpResponseTest.java │ │ ├── ConfigurationTest.java │ │ ├── ThemeTest.java │ │ ├── ExtensionTest.java │ │ ├── util │ │ │ ├── MultilocationalTest.java │ │ │ └── OverridableTest.java │ │ └── I18nResourceTest.java │ │ └── internal │ │ ├── impl │ │ └── HtmlPageTest.java │ │ ├── io │ │ └── util │ │ │ ├── MimeMapperTest.java │ │ │ └── PathUtilsTest.java │ │ ├── deployment │ │ ├── AppCreatorTest.java │ │ ├── listener │ │ │ └── CarbonUiServerTest.java │ │ ├── msf4j │ │ │ └── MicroserviceRegistrationTest.java │ │ ├── parser │ │ │ └── YamlFileParserTest.java │ │ └── AppRegistryTest.java │ │ └── http │ │ ├── PageRequestDispatcherTest.java │ │ ├── HttpTransportTest.java │ │ └── RequestDispatcherTest.java │ └── main │ ├── resources │ └── default-favicon.png │ └── java │ └── org │ └── wso2 │ └── carbon │ └── uiserver │ ├── spi │ ├── Server.java │ └── RestApiProvider.java │ ├── internal │ ├── reference │ │ ├── PageReference.java │ │ ├── ThemeReference.java │ │ ├── I18nResourceReference.java │ │ ├── ExtensionReference.java │ │ ├── FileReference.java │ │ └── AppReference.java │ ├── deployment │ │ ├── AppDeploymentEventListener.java │ │ ├── listener │ │ │ └── CarbonUiServer.java │ │ ├── msf4j │ │ │ ├── WebappMicroservice.java │ │ │ └── MicroserviceRegistration.java │ │ ├── parser │ │ │ ├── ConfigurationYaml.java │ │ │ └── YamlFileParser.java │ │ └── AppRegistry.java │ ├── io │ │ ├── util │ │ │ ├── PathUtils.java │ │ │ └── MimeMapper.java │ │ └── reference │ │ │ ├── ArtifactThemeReference.java │ │ │ ├── ArtifactExtensionReference.java │ │ │ ├── ArtifactPageReference.java │ │ │ ├── ArtifactFileReference.java │ │ │ └── ArtifactI18nResourceReference.java │ ├── impl │ │ ├── HtmlPage.java │ │ ├── OverriddenTheme.java │ │ ├── OverriddenExtension.java │ │ ├── HbsPage.java │ │ └── OverriddenApp.java │ ├── exception │ │ ├── BadRequestException.java │ │ ├── ResourceNotFoundException.java │ │ ├── ConfigurationException.java │ │ ├── AppCreationException.java │ │ ├── FileOperationException.java │ │ └── AppDeploymentEventListenerException.java │ └── http │ │ ├── PageRequestDispatcher.java │ │ ├── util │ │ └── IpAddressUtils.java │ │ └── RequestDispatcher.java │ └── api │ ├── util │ ├── Multilocational.java │ └── Overridable.java │ ├── exception │ ├── PageNotFoundException.java │ ├── PageRedirectException.java │ ├── UiServerException.java │ ├── RenderingException.java │ ├── UiServerRuntimeException.java │ └── HttpErrorException.java │ ├── Page.java │ ├── Theme.java │ ├── ServerConfiguration.java │ ├── Extension.java │ ├── Configuration.java │ └── I18nResource.java ├── tests ├── distribution │ ├── carbon-home │ │ ├── wso2 │ │ │ └── default │ │ │ │ └── deployment │ │ │ │ └── web-ui-apps │ │ │ │ └── test │ │ │ │ ├── public │ │ │ │ ├── css │ │ │ │ │ └── styles.css │ │ │ │ └── js │ │ │ │ │ └── bundle.js │ │ │ │ ├── themes │ │ │ │ ├── dark │ │ │ │ │ └── css │ │ │ │ │ │ └── styles.css │ │ │ │ └── light │ │ │ │ │ └── css │ │ │ │ │ └── styles.css │ │ │ │ ├── extensions │ │ │ │ └── widgets │ │ │ │ │ └── line-chart │ │ │ │ │ ├── widget.json │ │ │ │ │ └── css │ │ │ │ │ └── styles.css │ │ │ │ ├── i18n │ │ │ │ └── en.json │ │ │ │ ├── configuration.yaml │ │ │ │ └── pages │ │ │ │ └── index.hbs │ │ ├── deployment │ │ │ └── web-ui-apps │ │ │ │ └── test │ │ │ │ ├── extensions │ │ │ │ └── widgets │ │ │ │ │ └── bar-chart │ │ │ │ │ ├── css │ │ │ │ │ └── styles.css │ │ │ │ │ └── widget.json │ │ │ │ └── pages │ │ │ │ └── index.hbs │ │ ├── resources │ │ │ └── security │ │ │ │ └── wso2carbon.jks │ │ └── conf │ │ │ └── default │ │ │ └── deployment.yaml │ ├── carbon.product │ └── src │ │ └── assembly │ │ └── bin.xml └── pom.xml ├── features └── org.wso2.carbon.uiserver.feature │ └── src │ └── main │ └── resources │ └── p2.inf ├── issue_template.md ├── pull_request_template.md └── .gitignore /README.md: -------------------------------------------------------------------------------- 1 | # carbon-ui-server -------------------------------------------------------------------------------- /components/org.wso2.carbon.uiserver/src/test/resources/apps/full-app/public/js/bundle.js: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /components/org.wso2.carbon.uiserver/src/test/resources/apps/full-app/public/css/styles.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/distribution/carbon-home/wso2/default/deployment/web-ui-apps/test/public/css/styles.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/distribution/carbon-home/wso2/default/deployment/web-ui-apps/test/public/js/bundle.js: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /components/org.wso2.carbon.uiserver/src/test/resources/apps/full-app/themes/light/css/styles.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/distribution/carbon-home/wso2/default/deployment/web-ui-apps/test/themes/dark/css/styles.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/distribution/carbon-home/deployment/web-ui-apps/test/extensions/widgets/bar-chart/css/styles.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/distribution/carbon-home/deployment/web-ui-apps/test/extensions/widgets/bar-chart/widget.json: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/distribution/carbon-home/wso2/default/deployment/web-ui-apps/test/themes/light/css/styles.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /components/org.wso2.carbon.uiserver/src/test/resources/apps/empty-app/readme.txt: -------------------------------------------------------------------------------- 1 | This web app is empty! 2 | -------------------------------------------------------------------------------- /components/org.wso2.carbon.uiserver/src/test/resources/apps/full-app/extensions/widgets/line-chart/css/styles.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/distribution/carbon-home/wso2/default/deployment/web-ui-apps/test/extensions/widgets/line-chart/widget.json: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /components/org.wso2.carbon.uiserver/src/test/resources/apps/full-app/extensions/widgets/line-chart/widget.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /tests/distribution/carbon-home/wso2/default/deployment/web-ui-apps/test/extensions/widgets/line-chart/css/styles.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /components/org.wso2.carbon.uiserver/src/test/resources/apps/full-app/i18n/en.json: -------------------------------------------------------------------------------- 1 | { 2 | "welcome": "Hello!" 3 | } 4 | -------------------------------------------------------------------------------- /components/org.wso2.carbon.uiserver/src/test/resources/apps/full-app/i18n/some-other-file.txt: -------------------------------------------------------------------------------- 1 | This will be ignored. 2 | -------------------------------------------------------------------------------- /tests/distribution/carbon-home/wso2/default/deployment/web-ui-apps/test/i18n/en.json: -------------------------------------------------------------------------------- 1 | { 2 | "welcome": "Hello!" 3 | } 4 | -------------------------------------------------------------------------------- /tests/distribution/carbon-home/resources/security/wso2carbon.jks: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/this/carbon-ui-server/master/tests/distribution/carbon-home/resources/security/wso2carbon.jks -------------------------------------------------------------------------------- /components/org.wso2.carbon.uiserver/src/main/resources/default-favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/this/carbon-ui-server/master/components/org.wso2.carbon.uiserver/src/main/resources/default-favicon.png -------------------------------------------------------------------------------- /features/org.wso2.carbon.uiserver.feature/src/main/resources/p2.inf: -------------------------------------------------------------------------------- 1 | metaRequirements.0.namespace = org.eclipse.equinox.p2.iu 2 | metaRequirements.0.name = org.wso2.carbon.extensions.touchpoint 3 | metaRequirements.0.optional=true 4 | instructions.configure = \ 5 | org.eclipse.equinox.p2.touchpoint.natives.mkdir(path:${installFolder}/../../deployment/);\ 6 | org.eclipse.equinox.p2.touchpoint.natives.mkdir(path:${installFolder}/../../deployment/web-ui-apps/);\ 7 | org.wso2.carbon.extensions.touchpoint.mkdir(path:${installFolder}/../{runtime}/deployment/);\ 8 | org.wso2.carbon.extensions.touchpoint.mkdir(path:${installFolder}/../{runtime}/deployment/web-ui-apps/); 9 | -------------------------------------------------------------------------------- /issue_template.md: -------------------------------------------------------------------------------- 1 | **Description:** 2 | 3 | 4 | **Suggested Labels:** 5 | 6 | 7 | **Suggested Assignees:** 8 | 9 | 10 | **Affected Product Version:** 11 | 12 | **OS, DB, other environment details and versions:** 13 | 14 | **Steps to reproduce:** 15 | 16 | 17 | **Related Issues:** 18 | -------------------------------------------------------------------------------- /components/org.wso2.carbon.uiserver/src/test/resources/apps/full-app/configuration.yaml: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | # 4 | # WSO2 Inc. licenses this file to you under the Apache License, 5 | # Version 2.0 (the "License"); you may not use this file except 6 | # in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | # 18 | 19 | responseHeaders: 20 | resources: 21 | "Content-Security-Policy": "default-src 'none'; script-src 'self' ssl.google-analytics.com;" 22 | pages: 23 | "X-Frame-Options": "DENY" 24 | -------------------------------------------------------------------------------- /components/org.wso2.carbon.uiserver/src/test/resources/apps/minimal-app/pages/index.html: -------------------------------------------------------------------------------- 1 | 18 | 19 | 20 | 21 | Web App for Unit Tests 22 | 23 | 24 |

This web app has only a HTML file.

25 | 26 | 27 | -------------------------------------------------------------------------------- /components/org.wso2.carbon.uiserver/src/test/resources/testng.xml: -------------------------------------------------------------------------------- 1 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /tests/distribution/carbon-home/wso2/default/deployment/web-ui-apps/test/configuration.yaml: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | # 4 | # WSO2 Inc. licenses this file to you under the Apache License, 5 | # Version 2.0 (the "License"); you may not use this file except 6 | # in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | # 18 | 19 | # HTTP response headers. 20 | responseHeaders: 21 | # HTTP response headers for static resources. 22 | resources: 23 | "Content-Security-Policy": "default-src 'none'; script-src 'self' ssl.google-analytics.com;" 24 | # HTTP response headers for pages. 25 | pages: 26 | "X-Frame-Options": "DENY" 27 | -------------------------------------------------------------------------------- /components/org.wso2.carbon.uiserver/src/test/java/org/wso2/carbon/uiserver/api/ServerConfigurationTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * WSO2 Inc. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | package org.wso2.carbon.uiserver.api; 20 | 21 | import org.testng.Assert; 22 | import org.testng.annotations.Test; 23 | 24 | /** 25 | * Test cases for {@link ServerConfiguration} class. 26 | * 27 | * @since 0.12.6 28 | */ 29 | public class ServerConfigurationTest { 30 | 31 | @Test 32 | public void testGetContextPaths() { 33 | ServerConfiguration serverConfiguration = new ServerConfiguration(); 34 | Assert.assertFalse(serverConfiguration.getConfigurationForApp("foo").isPresent()); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /components/org.wso2.carbon.uiserver/src/test/java/org/wso2/carbon/uiserver/internal/impl/HtmlPageTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * WSO2 Inc. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | package org.wso2.carbon.uiserver.internal.impl; 20 | 21 | import org.testng.Assert; 22 | import org.testng.annotations.Test; 23 | import org.wso2.carbon.uiserver.api.UriPatten; 24 | 25 | /** 26 | * Test cases for {@link HtmlPage} class. 27 | * 28 | * @since 0.12.5 29 | */ 30 | public class HtmlPageTest { 31 | 32 | @Test 33 | public void testRender() { 34 | String pageContent = "

some html

"; 35 | HtmlPage page = new HtmlPage(new UriPatten("/"), pageContent); 36 | Assert.assertEquals(page.render(null, null), pageContent); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /components/org.wso2.carbon.uiserver/src/test/java/org/wso2/carbon/uiserver/internal/io/util/MimeMapperTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * WSO2 Inc. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | package org.wso2.carbon.uiserver.internal.io.util; 20 | 21 | import org.testng.Assert; 22 | import org.testng.annotations.Test; 23 | 24 | /** 25 | * Test cases for {@link MimeMapper} class. 26 | * 27 | * @since 0.12.5 28 | */ 29 | public class MimeMapperTest { 30 | 31 | @Test 32 | public void testGetMimeType() { 33 | Assert.assertTrue(MimeMapper.getMimeType("jpeg").isPresent()); 34 | Assert.assertEquals(MimeMapper.getMimeType("jpeg").orElse(null), "image/jpeg"); 35 | Assert.assertFalse(MimeMapper.getMimeType("foo").isPresent()); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /components/org.wso2.carbon.uiserver/src/main/java/org/wso2/carbon/uiserver/spi/Server.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * WSO2 Inc. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | package org.wso2.carbon.uiserver.spi; 20 | 21 | import org.wso2.carbon.uiserver.api.App; 22 | 23 | import java.util.Optional; 24 | 25 | /** 26 | * Represents Carbon UI server. 27 | * 28 | * @since 0.8.0 29 | */ 30 | public interface Server { 31 | 32 | /** 33 | * Returns fully deployed web app with the specified name. 34 | * 35 | * @param appName name of the app 36 | * @return app with the specified name; {@link Optional#empty() empty} if there is no app with the given name or app 37 | * is not deployed yet 38 | */ 39 | Optional getApp(String appName); 40 | } 41 | -------------------------------------------------------------------------------- /tests/distribution/carbon-home/deployment/web-ui-apps/test/pages/index.hbs: -------------------------------------------------------------------------------- 1 | 18 | 19 | 20 | 21 | TEST 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 |

custom index.hbs served successfully!

33 | 34 | 35 | -------------------------------------------------------------------------------- /tests/distribution/carbon-home/wso2/default/deployment/web-ui-apps/test/pages/index.hbs: -------------------------------------------------------------------------------- 1 | 18 | 19 | 20 | 21 | TEST 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 |

index.hbs served successfully!

33 | 34 | 35 | -------------------------------------------------------------------------------- /components/org.wso2.carbon.uiserver/src/test/resources/apps/full-app/pages/index.hbs: -------------------------------------------------------------------------------- 1 | 18 | 19 | 20 | 21 | Web App for Unit Tests 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 |

index.hbs served successfully!

33 | 34 | 35 | -------------------------------------------------------------------------------- /tests/distribution/carbon.product: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /components/org.wso2.carbon.uiserver/src/main/java/org/wso2/carbon/uiserver/internal/reference/PageReference.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * WSO2 Inc. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | package org.wso2.carbon.uiserver.internal.reference; 20 | 21 | import org.wso2.carbon.uiserver.internal.exception.FileOperationException; 22 | 23 | /** 24 | * A reference to a page in a web app. 25 | * 26 | * @since 0.8.0 27 | */ 28 | public interface PageReference { 29 | 30 | /** 31 | * Returns the path pattern of the page represented by this reference. 32 | * 33 | * @return path pattern of the page 34 | * @throws FileOperationException if cannot get the path pattern 35 | */ 36 | String getPathPattern() throws FileOperationException; 37 | 38 | /** 39 | * Returns a reference to the HTMl if of the page represented by this reference. 40 | * 41 | * @return reference to the HTML file of the page 42 | */ 43 | FileReference getHtmlFile(); 44 | } 45 | -------------------------------------------------------------------------------- /components/org.wso2.carbon.uiserver/src/main/java/org/wso2/carbon/uiserver/internal/reference/ThemeReference.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * WSO2 Inc. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | package org.wso2.carbon.uiserver.internal.reference; 20 | 21 | import org.wso2.carbon.uiserver.internal.exception.FileOperationException; 22 | 23 | /** 24 | * A reference to a theme in a web app artifact. 25 | * 26 | * @since 0.8.0 27 | */ 28 | public interface ThemeReference { 29 | 30 | /** 31 | * Returns the name of the theme represented by this reference. 32 | * 33 | * @return name of the theme 34 | * @throws FileOperationException if cannot read theme name 35 | */ 36 | String getName() throws FileOperationException; 37 | 38 | /** 39 | * Returns the absolute path to the theme represented by this reference. 40 | * 41 | * @return absolute path to the theme 42 | * @throws FileOperationException if cannot obtain the path 43 | */ 44 | String getPath() throws FileOperationException; 45 | } 46 | -------------------------------------------------------------------------------- /tests/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 19 | 20 | 21 | 4.0.0 22 | 23 | org.wso2.carbon.uiserver.tests 24 | tests-parent 25 | pom 26 | 27 | WSO2 Carbon UI Server - Tests 28 | WSO2 Carbon UI Server tests 29 | http://wso2.org 30 | 31 | 32 | org.wso2.carbon.uiserver 33 | uis-parent 34 | 0.19.3-SNAPSHOT 35 | ../pom.xml 36 | 37 | 38 | 39 | distribution 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /components/org.wso2.carbon.uiserver/src/test/java/org/wso2/carbon/uiserver/api/http/HttpResponseTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * WSO2 Inc. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | package org.wso2.carbon.uiserver.api.http; 20 | 21 | import org.testng.Assert; 22 | import org.testng.annotations.Test; 23 | 24 | /** 25 | * Test cases for {@link HttpResponse} class. 26 | * 27 | * @since 0.13.0 28 | */ 29 | public class HttpResponseTest { 30 | 31 | @Test 32 | public void test() { 33 | HttpResponse response = new HttpResponse(HttpResponse.STATUS_OK, "some-content", 34 | HttpResponse.CONTENT_TYPE_TEXT_PLAIN); 35 | 36 | Assert.assertEquals(response.getStatus(), HttpResponse.STATUS_OK); 37 | Assert.assertEquals(response.getContent(), "some-content"); 38 | Assert.assertEquals(response.getContentType(), HttpResponse.CONTENT_TYPE_TEXT_PLAIN); 39 | Assert.assertTrue(response.getHeaders().isEmpty()); 40 | Assert.assertTrue(response.getCookies().isEmpty()); 41 | Assert.assertNotNull(response.toString()); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /components/org.wso2.carbon.uiserver/src/main/java/org/wso2/carbon/uiserver/spi/RestApiProvider.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * WSO2 Inc. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | package org.wso2.carbon.uiserver.spi; 20 | 21 | import org.wso2.carbon.uiserver.api.App; 22 | import org.wso2.msf4j.Microservice; 23 | 24 | import java.util.Map; 25 | 26 | /** 27 | * Provider that supplies microservices that should be deployed as REST APIs for a specified web app. 28 | * 29 | * @since 0.15.0 30 | */ 31 | public interface RestApiProvider { 32 | 33 | /** 34 | * Returns the name of the app that this provider supplies REST APIs. 35 | * 36 | * @return name of the app 37 | */ 38 | String getAppName(); 39 | 40 | /** 41 | * Returns microservices that needs to be deployed as REST APIs. 42 | *

43 | * Key of the returning map is considered as the path (without the app context path) of the REST API. 44 | * 45 | * @param app app that returning microservices belong to 46 | * @return microservices to be deploy 47 | */ 48 | Map getMicroservices(App app); 49 | } 50 | -------------------------------------------------------------------------------- /components/org.wso2.carbon.uiserver/src/main/java/org/wso2/carbon/uiserver/internal/reference/I18nResourceReference.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * WSO2 Inc. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | package org.wso2.carbon.uiserver.internal.reference; 20 | 21 | import org.wso2.carbon.uiserver.internal.exception.FileOperationException; 22 | 23 | import java.util.Locale; 24 | import java.util.Map; 25 | 26 | /** 27 | * A reference to an i18n resource in a web app artifact. 28 | * 29 | * @since 0.8.0 30 | */ 31 | public interface I18nResourceReference { 32 | 33 | /** 34 | * Returns the locale of the i18n resource represented by this reference. 35 | * 36 | * @return locale of the i18n resource 37 | * @throws FileOperationException if cannot read the locale 38 | */ 39 | Locale getLocale() throws FileOperationException; 40 | 41 | /** 42 | * Returns the messages of the i18n resource represented by this reference. 43 | * 44 | * @return messages of the i18n resource 45 | * @throws FileOperationException if cannot read the messages 46 | */ 47 | Map getMessages() throws FileOperationException; 48 | } 49 | -------------------------------------------------------------------------------- /components/org.wso2.carbon.uiserver/src/main/java/org/wso2/carbon/uiserver/internal/deployment/AppDeploymentEventListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * WSO2 Inc. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | package org.wso2.carbon.uiserver.internal.deployment; 20 | 21 | import org.wso2.carbon.uiserver.api.App; 22 | import org.wso2.carbon.uiserver.internal.exception.AppDeploymentEventListenerException; 23 | 24 | /** 25 | * A listener that observes web app deployments. 26 | * 27 | * @since 0.8.3 28 | */ 29 | public interface AppDeploymentEventListener { 30 | 31 | /** 32 | * Invoked when an app is deployed. 33 | * 34 | * @param app the deployed app 35 | * @throws AppDeploymentEventListenerException if an error occurred when calling 36 | */ 37 | void appDeploymentEvent(App app) throws AppDeploymentEventListenerException; 38 | 39 | /** 40 | * Invoked when an app is undeployed. 41 | * 42 | * @param appName name of the undeploying app. 43 | * @throws AppDeploymentEventListenerException if an error occurred when calling 44 | */ 45 | void appUndeploymentEvent(String appName) throws AppDeploymentEventListenerException; 46 | } 47 | -------------------------------------------------------------------------------- /components/org.wso2.carbon.uiserver/src/main/java/org/wso2/carbon/uiserver/internal/io/util/PathUtils.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * WSO2 Inc. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | package org.wso2.carbon.uiserver.internal.io.util; 20 | 21 | import org.apache.commons.io.FilenameUtils; 22 | 23 | import java.nio.file.Path; 24 | 25 | /** 26 | * Utility methods for {@link Path}s. 27 | * 28 | * @since 0.8.0 29 | */ 30 | public class PathUtils { 31 | 32 | private PathUtils() { 33 | } 34 | 35 | /** 36 | * Returns the file name of the given path. 37 | * 38 | * @param path file/directory path 39 | * @return file name (never {@code null}) 40 | */ 41 | public static String getName(Path path) { 42 | Path fileName = path.getFileName(); 43 | return (fileName == null) ? "" : fileName.toString(); 44 | } 45 | 46 | /** 47 | * Returns the file extension of the given path. 48 | * 49 | * @param filePath file path 50 | * @return file extension (never {@code null}) 51 | */ 52 | public static String getExtension(Path filePath) { 53 | return FilenameUtils.getExtension(filePath.getFileName().toString()); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /components/org.wso2.carbon.uiserver/src/main/java/org/wso2/carbon/uiserver/internal/impl/HtmlPage.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * WSO2 Inc. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | package org.wso2.carbon.uiserver.internal.impl; 20 | 21 | import org.wso2.carbon.uiserver.api.Configuration; 22 | import org.wso2.carbon.uiserver.api.Page; 23 | import org.wso2.carbon.uiserver.api.UriPatten; 24 | import org.wso2.carbon.uiserver.api.exception.RenderingException; 25 | import org.wso2.carbon.uiserver.api.http.HttpRequest; 26 | 27 | /** 28 | * Page based on a HTML file. 29 | * 30 | * @since 0.10.3 31 | */ 32 | public class HtmlPage extends Page { 33 | 34 | private final String content; 35 | 36 | /** 37 | * Creates a new page that renders given HTML content 38 | * 39 | * @param uriPatten URI pattern of the page 40 | * @param content HTML content of the page 41 | */ 42 | public HtmlPage(UriPatten uriPatten, String content) { 43 | super(uriPatten); 44 | this.content = content; 45 | } 46 | 47 | @Override 48 | public String render(HttpRequest request, Configuration configuration) throws RenderingException { 49 | return content; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /components/org.wso2.carbon.uiserver/src/test/java/org/wso2/carbon/uiserver/internal/io/util/PathUtilsTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * WSO2 Inc. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | package org.wso2.carbon.uiserver.internal.io.util; 20 | 21 | import org.testng.Assert; 22 | import org.testng.annotations.Test; 23 | 24 | import java.nio.file.Path; 25 | import java.nio.file.Paths; 26 | 27 | import static org.mockito.Mockito.mock; 28 | import static org.mockito.Mockito.when; 29 | 30 | /** 31 | * Test cases for {@link PathUtils} class. 32 | * 33 | * @since 0.12.5 34 | */ 35 | public class PathUtilsTest { 36 | 37 | @Test 38 | public void testGetNameReturnsEmptyString() { 39 | Path filePath = mock(Path.class); 40 | when(filePath.getFileName()).thenReturn(null); 41 | Assert.assertEquals(PathUtils.getName(filePath), ""); 42 | } 43 | 44 | @Test 45 | public void testGetName() { 46 | Path filePath = Paths.get("test/some-file.txt"); 47 | Assert.assertEquals(PathUtils.getName(filePath), "some-file.txt"); 48 | } 49 | 50 | @Test 51 | public void testGetExtension() { 52 | Path filePath = Paths.get("test/some-file.txt"); 53 | Assert.assertEquals(PathUtils.getExtension(filePath), "txt"); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /components/org.wso2.carbon.uiserver/src/main/java/org/wso2/carbon/uiserver/api/util/Multilocational.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * WSO2 Inc. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | package org.wso2.carbon.uiserver.api.util; 20 | 21 | import java.util.List; 22 | 23 | /** 24 | * Represents an entity that can be present in more than one location. 25 | * 26 | * @since 0.12.0 27 | */ 28 | public interface Multilocational { 29 | 30 | /** 31 | * Returns paths that the entity represented this object is present. First path of the returning list has the 32 | * highest priority and the last path has the least priority. 33 | * 34 | * @return paths that the entity represented this object is present 35 | */ 36 | List getPaths(); 37 | 38 | /** 39 | * Returns the path with the highest priority. 40 | * 41 | * @return highest priority path 42 | */ 43 | default String getHighestPriorityPath() { 44 | return getPaths().get(0); 45 | } 46 | 47 | /** 48 | * Returns the path with the least priority. 49 | * 50 | * @return least priority path 51 | */ 52 | default String getLeastPriorityPath() { 53 | List paths = getPaths(); 54 | return paths.get(paths.size() - 1); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /components/org.wso2.carbon.uiserver/src/main/java/org/wso2/carbon/uiserver/internal/impl/OverriddenTheme.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * WSO2 Inc. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | package org.wso2.carbon.uiserver.internal.impl; 20 | 21 | import com.google.common.collect.ImmutableList; 22 | import org.wso2.carbon.uiserver.api.Theme; 23 | 24 | import java.util.Optional; 25 | 26 | /** 27 | * Represents an overridden theme. 28 | * 29 | * @since 0.12.0 30 | */ 31 | public class OverriddenTheme extends Theme { 32 | 33 | private final Theme base; 34 | private final Theme override; 35 | 36 | /** 37 | * Creates a new overridden theme. 38 | * 39 | * @param base base theme 40 | * @param override theme that overrides the {@code base} theme 41 | */ 42 | public OverriddenTheme(Theme base, Theme override) { 43 | super(override.getName(), 44 | ImmutableList.builder().addAll(override.getPaths()).addAll(base.getPaths()).build()); 45 | this.base = base; 46 | this.override = override; 47 | } 48 | 49 | @Override 50 | public Theme getBase() { 51 | return base; 52 | } 53 | 54 | @Override 55 | public Optional getOverride() { 56 | return Optional.of(override); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /components/org.wso2.carbon.uiserver/src/main/java/org/wso2/carbon/uiserver/api/exception/PageNotFoundException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * WSO2 Inc. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | package org.wso2.carbon.uiserver.api.exception; 20 | 21 | import org.wso2.carbon.uiserver.api.http.HttpResponse; 22 | 23 | /** 24 | * Indicates a page not found error. 25 | * 26 | * @since 0.8.0 27 | */ 28 | public class PageNotFoundException extends HttpErrorException { 29 | 30 | /** 31 | * Constructs a new exception with {@code null} as its detail message. 32 | */ 33 | public PageNotFoundException() { 34 | super(HttpResponse.STATUS_NOT_FOUND); 35 | } 36 | 37 | /** 38 | * Constructs a new exception with the specified detail message. 39 | * 40 | * @param message detail message 41 | */ 42 | public PageNotFoundException(String message) { 43 | super(HttpResponse.STATUS_NOT_FOUND, message); 44 | } 45 | 46 | /** 47 | * Constructs a new exception with the specified detail message and cause. 48 | * 49 | * @param message details message 50 | * @param cause the cause of the exception 51 | */ 52 | public PageNotFoundException(String message, Throwable cause) { 53 | super(HttpResponse.STATUS_NOT_FOUND, message, cause); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /components/org.wso2.carbon.uiserver/src/main/java/org/wso2/carbon/uiserver/internal/reference/ExtensionReference.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * WSO2 Inc. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | package org.wso2.carbon.uiserver.internal.reference; 20 | 21 | import org.wso2.carbon.uiserver.internal.exception.FileOperationException; 22 | 23 | /** 24 | * A reference to an extension in a web app. 25 | * 26 | * @since 0.8.0 27 | */ 28 | public interface ExtensionReference { 29 | 30 | /** 31 | * Returns the name of the extension represented by this reference. 32 | * 33 | * @return name of the extension 34 | * @throws FileOperationException if cannot read extension name 35 | */ 36 | String getName() throws FileOperationException; 37 | 38 | /** 39 | * Returns the type of the extension represented by this reference. 40 | * 41 | * @return type of the extension 42 | * @throws FileOperationException if cannot read extension type 43 | */ 44 | String getType() throws FileOperationException; 45 | 46 | /** 47 | * Returns the absolute path to the extension represented by this reference. 48 | * 49 | * @return absolute path to the extension 50 | * @throws FileOperationException if cannot obtain the path 51 | */ 52 | String getPath() throws FileOperationException; 53 | } 54 | -------------------------------------------------------------------------------- /components/org.wso2.carbon.uiserver/src/main/java/org/wso2/carbon/uiserver/internal/io/reference/ArtifactThemeReference.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * WSO2 Inc. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | package org.wso2.carbon.uiserver.internal.io.reference; 20 | 21 | import org.wso2.carbon.uiserver.internal.exception.FileOperationException; 22 | import org.wso2.carbon.uiserver.internal.io.util.PathUtils; 23 | import org.wso2.carbon.uiserver.internal.reference.ThemeReference; 24 | 25 | import java.nio.file.Path; 26 | 27 | /** 28 | * A reference to a theme in a directory inside a web app artifact. 29 | * 30 | * @since 0.8.0 31 | */ 32 | public class ArtifactThemeReference implements ThemeReference { 33 | 34 | private final Path themeDirectory; 35 | 36 | /** 37 | * Creates a reference to the theme which resides in the specified directory. 38 | * 39 | * @param themeDirectory directory that contains the theme 40 | */ 41 | public ArtifactThemeReference(Path themeDirectory) { 42 | this.themeDirectory = themeDirectory; 43 | } 44 | 45 | @Override 46 | public String getName() throws FileOperationException { 47 | return PathUtils.getName(themeDirectory); 48 | } 49 | 50 | @Override 51 | public String getPath() throws FileOperationException { 52 | return themeDirectory.toString(); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /components/org.wso2.carbon.uiserver/src/main/java/org/wso2/carbon/uiserver/internal/impl/OverriddenExtension.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * WSO2 Inc. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | package org.wso2.carbon.uiserver.internal.impl; 20 | 21 | import com.google.common.collect.ImmutableList; 22 | import org.wso2.carbon.uiserver.api.Extension; 23 | 24 | import java.util.Optional; 25 | 26 | /** 27 | * Represents an overridden extension. 28 | * 29 | * @since 0.12.0 30 | */ 31 | public class OverriddenExtension extends Extension { 32 | 33 | private final Extension base; 34 | private final Extension override; 35 | 36 | /** 37 | * Creates a new overridden extension. 38 | * 39 | * @param base base extension 40 | * @param override extension that overrides the {@code base} extension 41 | */ 42 | public OverriddenExtension(Extension base, Extension override) { 43 | super(override.getName(), override.getType(), 44 | ImmutableList.builder().addAll(override.getPaths()).addAll(base.getPaths()).build()); 45 | this.base = base; 46 | this.override = override; 47 | } 48 | 49 | @Override 50 | public Extension getBase() { 51 | return base; 52 | } 53 | 54 | @Override 55 | public Optional getOverride() { 56 | return Optional.of(override); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /components/org.wso2.carbon.uiserver/src/test/java/org/wso2/carbon/uiserver/internal/deployment/AppCreatorTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * WSO2 Inc. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | package org.wso2.carbon.uiserver.internal.deployment; 20 | 21 | import org.testng.Assert; 22 | import org.testng.annotations.DataProvider; 23 | import org.testng.annotations.Test; 24 | import org.wso2.carbon.uiserver.api.App; 25 | import org.wso2.carbon.uiserver.internal.io.reference.ArtifactAppReference; 26 | import org.wso2.carbon.uiserver.internal.reference.AppReference; 27 | 28 | import java.nio.file.Paths; 29 | 30 | /** 31 | * Test cases for {@link AppCreator} class. 32 | * 33 | * @since 0.12.5 34 | */ 35 | public class AppCreatorTest { 36 | 37 | @DataProvider 38 | public Object[][] appReferences() { 39 | return new Object[][]{ 40 | {new ArtifactAppReference(Paths.get("src/test/resources/apps/full-app/"))}, 41 | {new ArtifactAppReference(Paths.get("src/test/resources/apps/minimal-app/"))}, 42 | {new ArtifactAppReference(Paths.get("src/test/resources/apps/empty-app/"))} 43 | }; 44 | } 45 | 46 | @Test(dataProvider = "appReferences") 47 | public void testCreateApp(AppReference appReference) { 48 | App app = AppCreator.createApp(appReference, "/test"); 49 | Assert.assertNotNull(app); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /components/org.wso2.carbon.uiserver/src/main/java/org/wso2/carbon/uiserver/internal/exception/BadRequestException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * WSO2 Inc. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | package org.wso2.carbon.uiserver.internal.exception; 20 | 21 | import org.wso2.carbon.uiserver.api.exception.HttpErrorException; 22 | import org.wso2.carbon.uiserver.api.http.HttpResponse; 23 | 24 | /** 25 | * Indicates a bad/invalid HTTP request. 26 | * 27 | * @since 0.13.4 28 | */ 29 | public class BadRequestException extends HttpErrorException { 30 | 31 | /** 32 | * Constructs a new exception with {@code null} as its detail message. 33 | */ 34 | public BadRequestException() { 35 | super(HttpResponse.STATUS_BAD_REQUEST); 36 | } 37 | 38 | /** 39 | * Constructs a new exception with the specified detail message. 40 | * 41 | * @param message detail message 42 | */ 43 | public BadRequestException(String message) { 44 | super(HttpResponse.STATUS_BAD_REQUEST, message); 45 | } 46 | 47 | /** 48 | * Constructs a new exception with the specified detail message and cause. 49 | * 50 | * @param message details message 51 | * @param cause the cause of the exception 52 | */ 53 | public BadRequestException(String message, Throwable cause) { 54 | super(HttpResponse.STATUS_BAD_REQUEST, message, cause); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /components/org.wso2.carbon.uiserver/src/main/java/org/wso2/carbon/uiserver/internal/exception/ResourceNotFoundException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * WSO2 Inc. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | package org.wso2.carbon.uiserver.internal.exception; 20 | 21 | import org.wso2.carbon.uiserver.api.exception.HttpErrorException; 22 | import org.wso2.carbon.uiserver.api.http.HttpResponse; 23 | 24 | /** 25 | * Indicates a resource not found error. 26 | * 27 | * @since 0.8.0 28 | */ 29 | public class ResourceNotFoundException extends HttpErrorException { 30 | 31 | /** 32 | * Constructs a new exception with {@code null} as its detail message. 33 | */ 34 | public ResourceNotFoundException() { 35 | super(HttpResponse.STATUS_NOT_FOUND); 36 | } 37 | 38 | /** 39 | * Constructs a new exception with the specified detail message. 40 | * 41 | * @param message detail message 42 | */ 43 | public ResourceNotFoundException(String message) { 44 | super(HttpResponse.STATUS_NOT_FOUND, message); 45 | } 46 | 47 | /** 48 | * Constructs a new exception with the specified detail message and cause. 49 | * 50 | * @param message details message 51 | * @param cause the cause of the exception 52 | */ 53 | public ResourceNotFoundException(String message, Throwable cause) { 54 | super(HttpResponse.STATUS_NOT_FOUND, message, cause); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /components/org.wso2.carbon.uiserver/src/main/java/org/wso2/carbon/uiserver/internal/deployment/listener/CarbonUiServer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * WSO2 Inc. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | package org.wso2.carbon.uiserver.internal.deployment.listener; 20 | 21 | import org.wso2.carbon.uiserver.api.App; 22 | import org.wso2.carbon.uiserver.internal.deployment.AppDeploymentEventListener; 23 | import org.wso2.carbon.uiserver.spi.Server; 24 | 25 | import java.util.Optional; 26 | import java.util.concurrent.ConcurrentHashMap; 27 | import java.util.concurrent.ConcurrentMap; 28 | 29 | /** 30 | * Carbon UI server service component. 31 | * 32 | * @since 0.8.0 33 | */ 34 | public class CarbonUiServer implements Server, AppDeploymentEventListener { 35 | 36 | /** 37 | * Contains deployed apps. Here key is the app name and value is the deployed app. 38 | */ 39 | private final ConcurrentMap deployedApps = new ConcurrentHashMap<>(); 40 | 41 | @Override 42 | public Optional getApp(String appName) { 43 | return Optional.ofNullable(deployedApps.get(appName)); 44 | } 45 | 46 | @Override 47 | public void appDeploymentEvent(App app) { 48 | deployedApps.put(app.getName(), app); 49 | } 50 | 51 | @Override 52 | public void appUndeploymentEvent(String appName) { 53 | deployedApps.remove(appName); 54 | } 55 | 56 | public void close() { 57 | deployedApps.clear(); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /components/org.wso2.carbon.uiserver/src/main/java/org/wso2/carbon/uiserver/api/exception/PageRedirectException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * WSO2 Inc. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | package org.wso2.carbon.uiserver.api.exception; 20 | 21 | import org.wso2.carbon.uiserver.api.http.HttpResponse; 22 | 23 | /** 24 | * Indicates a page redirection. 25 | * 26 | * @since 0.8.0 27 | */ 28 | public class PageRedirectException extends HttpErrorException { 29 | 30 | private final String redirectUrl; 31 | 32 | /** 33 | * Constructs a new exception with the specified redirect URL. 34 | * 35 | * @param redirectUrl redirection URI or URL 36 | */ 37 | public PageRedirectException(String redirectUrl) { 38 | super(HttpResponse.STATUS_FOUND, "Redirecting to '" + redirectUrl + "'."); 39 | this.redirectUrl = redirectUrl; 40 | } 41 | 42 | /** 43 | * Constructs a new exception with the specified redirect URL. 44 | * 45 | * @param redirectUrl redirection URI or URL 46 | * @param cause the cause of the exception 47 | */ 48 | public PageRedirectException(String redirectUrl, Throwable cause) { 49 | super(HttpResponse.STATUS_FOUND, "Redirecting to '" + redirectUrl + "'.", cause); 50 | this.redirectUrl = redirectUrl; 51 | } 52 | 53 | /** 54 | * Returns the redirection URL of this exception. 55 | * 56 | * @return the redirection URL 57 | */ 58 | public String getRedirectUrl() { 59 | return redirectUrl; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /components/org.wso2.carbon.uiserver/src/main/java/org/wso2/carbon/uiserver/internal/io/reference/ArtifactExtensionReference.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * WSO2 Inc. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | package org.wso2.carbon.uiserver.internal.io.reference; 20 | 21 | import org.wso2.carbon.uiserver.internal.exception.FileOperationException; 22 | import org.wso2.carbon.uiserver.internal.io.util.PathUtils; 23 | import org.wso2.carbon.uiserver.internal.reference.ExtensionReference; 24 | 25 | import java.nio.file.Path; 26 | 27 | /** 28 | * A reference to an extension in a directory inside a web app artifact. 29 | * 30 | * @since 0.8.0 31 | */ 32 | public class ArtifactExtensionReference implements ExtensionReference { 33 | 34 | private final Path extensionDirectory; 35 | 36 | /** 37 | * Creates a reference to the extension which resides in the specified directory. 38 | * 39 | * @param extensionDirectory directory that contains the extension 40 | */ 41 | public ArtifactExtensionReference(Path extensionDirectory) { 42 | this.extensionDirectory = extensionDirectory; 43 | } 44 | 45 | @Override 46 | public String getName() throws FileOperationException { 47 | return PathUtils.getName(extensionDirectory); 48 | } 49 | 50 | @Override 51 | public String getType() throws FileOperationException { 52 | return PathUtils.getName(extensionDirectory.getParent()); 53 | } 54 | 55 | @Override 56 | public String getPath() throws FileOperationException { 57 | return extensionDirectory.toString(); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /components/org.wso2.carbon.uiserver/src/main/java/org/wso2/carbon/uiserver/internal/reference/FileReference.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * WSO2 Inc. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | package org.wso2.carbon.uiserver.internal.reference; 20 | 21 | import org.wso2.carbon.uiserver.internal.exception.FileOperationException; 22 | 23 | /** 24 | * A reference to a file in a web app. 25 | * 26 | * @since 0.8.0 27 | */ 28 | public interface FileReference { 29 | 30 | /** 31 | * Returns the name of the file represented by this reference. 32 | * 33 | * @return name of the file 34 | * @throws FileOperationException if cannot read file name 35 | */ 36 | String getName() throws FileOperationException; 37 | 38 | /** 39 | * Returns the extension of the file represented by this reference. 40 | * 41 | * @return extension of the file 42 | * @throws FileOperationException if cannot read file extension 43 | */ 44 | String getExtension() throws FileOperationException; 45 | 46 | /** 47 | * Returns the content of the file represented by this reference. 48 | * 49 | * @return content of the file 50 | * @throws FileOperationException if cannot read file content 51 | */ 52 | String getContent() throws FileOperationException; 53 | 54 | /** 55 | * Returns the absolute path to the file represented by this reference. 56 | * 57 | * @return absolute path to the file 58 | * @throws FileOperationException if cannot obtain the path 59 | */ 60 | String getFilePath() throws FileOperationException; 61 | } 62 | -------------------------------------------------------------------------------- /components/org.wso2.carbon.uiserver/src/test/java/org/wso2/carbon/uiserver/internal/deployment/listener/CarbonUiServerTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * WSO2 Inc. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | package org.wso2.carbon.uiserver.internal.deployment.listener; 20 | 21 | import org.testng.Assert; 22 | import org.testng.annotations.Test; 23 | import org.wso2.carbon.uiserver.api.App; 24 | 25 | import static org.mockito.Mockito.mock; 26 | import static org.mockito.Mockito.when; 27 | 28 | /** 29 | * Test cases for {@link CarbonUiServer} class. 30 | * 31 | * @since 0.15.0 32 | */ 33 | public class CarbonUiServerTest { 34 | 35 | @Test 36 | public void testGetApp() { 37 | CarbonUiServer carbonUiServer = new CarbonUiServer(); 38 | 39 | carbonUiServer.appDeploymentEvent(createApp("foo")); 40 | Assert.assertTrue(carbonUiServer.getApp("foo").isPresent()); 41 | 42 | Assert.assertFalse(carbonUiServer.getApp("bar").isPresent()); 43 | carbonUiServer.appDeploymentEvent(createApp("bar")); 44 | Assert.assertTrue(carbonUiServer.getApp("bar").isPresent()); 45 | 46 | carbonUiServer.appUndeploymentEvent("foo"); 47 | Assert.assertFalse(carbonUiServer.getApp("foo").isPresent()); 48 | Assert.assertTrue(carbonUiServer.getApp("bar").isPresent()); 49 | 50 | carbonUiServer.close(); 51 | Assert.assertFalse(carbonUiServer.getApp("foo").isPresent()); 52 | Assert.assertFalse(carbonUiServer.getApp("bar").isPresent()); 53 | } 54 | 55 | private static App createApp(String appName) { 56 | App app = mock(App.class); 57 | when(app.getName()).thenReturn(appName); 58 | return app; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /components/org.wso2.carbon.uiserver/src/test/java/org/wso2/carbon/uiserver/api/ConfigurationTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * WSO2 Inc. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | package org.wso2.carbon.uiserver.api; 20 | 21 | import org.testng.Assert; 22 | import org.testng.annotations.Test; 23 | 24 | import java.util.Map; 25 | 26 | import static org.wso2.carbon.uiserver.api.http.HttpResponse.HEADER_CACHE_CONTROL; 27 | import static org.wso2.carbon.uiserver.api.http.HttpResponse.HEADER_EXPIRES; 28 | import static org.wso2.carbon.uiserver.api.http.HttpResponse.HEADER_PRAGMA; 29 | 30 | import static java.util.Collections.singletonMap; 31 | 32 | /** 33 | * Test cases for {@link Configuration} class. 34 | * 35 | * @since 0.12.5 36 | */ 37 | public class ConfigurationTest { 38 | 39 | @Test 40 | public void testGetResponseHeaders() { 41 | Map pages = singletonMap(HEADER_EXPIRES, "100"); 42 | Map staticResources = singletonMap(HEADER_CACHE_CONTROL, "public,max-age=100"); 43 | Configuration configuration = new Configuration(new Configuration.HttpResponseHeaders(pages, staticResources)); 44 | 45 | Assert.assertEquals(configuration.getResponseHeaders().forPages().get(HEADER_PRAGMA), 46 | Configuration.DEFAULT_CONFIGURATION.getResponseHeaders().forPages().get(HEADER_PRAGMA)); 47 | Assert.assertEquals(configuration.getResponseHeaders().forPages().get(HEADER_EXPIRES), 48 | pages.get(HEADER_EXPIRES)); 49 | Assert.assertEquals(configuration.getResponseHeaders().forStaticResources().get(HEADER_CACHE_CONTROL), 50 | staticResources.get(HEADER_CACHE_CONTROL)); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /tests/distribution/carbon-home/conf/default/deployment.yaml: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the \"License\"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an \"AS IS\" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | # Carbon Configuration Parameters 16 | wso2.carbon: 17 | # value to uniquely identify a server 18 | id: carbon-kernel 19 | # server name 20 | name: WSO2 Carbon Kernel 21 | # ports used by this server 22 | ports: 23 | # port offset 24 | offset: 0 25 | 26 | wso2.securevault: 27 | secretRepository: 28 | type: org.wso2.carbon.secvault.repository.DefaultSecretRepository 29 | parameters: 30 | privateKeyAlias: wso2carbon 31 | keystoreLocation: ${sys:carbon.home}/resources/security/securevault.jks 32 | secretPropertiesFile: ${sys:carbon.home}/conf/${sys:wso2.runtime}/secrets.properties 33 | masterKeyReader: 34 | type: org.wso2.carbon.secvault.reader.DefaultMasterKeyReader 35 | parameters: 36 | masterKeyReaderFile: ${sys:carbon.home}/conf/${sys:wso2.runtime}/master-keys.yaml 37 | 38 | wso2.transport.http: 39 | transportProperties: 40 | - name: "server.bootstrap.socket.timeout" 41 | value: 60 42 | - name: "client.bootstrap.socket.timeout" 43 | value: 60 44 | - name: "latency.metrics.enabled" 45 | value: true 46 | 47 | listenerConfigurations: 48 | - id: "default-http" 49 | host: "0.0.0.0" 50 | port: 9090 51 | 52 | - id: "for-test-app" 53 | host: "0.0.0.0" 54 | port: 9443 55 | scheme: https 56 | keyStoreFile: "${carbon.home}/resources/security/wso2carbon.jks" 57 | keyStorePassword: wso2carbon 58 | certPass: wso2carbon 59 | 60 | senderConfigurations: 61 | - id: "default-http-sender" 62 | 63 | wso2.carbon-ui-server: 64 | apps: 65 | "test": 66 | contextPath: "/sample" 67 | transportId: "for-test-app" 68 | -------------------------------------------------------------------------------- /components/org.wso2.carbon.uiserver/src/main/java/org/wso2/carbon/uiserver/internal/io/reference/ArtifactPageReference.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * WSO2 Inc. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | package org.wso2.carbon.uiserver.internal.io.reference; 20 | 21 | import org.apache.commons.io.FilenameUtils; 22 | import org.wso2.carbon.uiserver.internal.exception.FileOperationException; 23 | import org.wso2.carbon.uiserver.internal.reference.FileReference; 24 | import org.wso2.carbon.uiserver.internal.reference.PageReference; 25 | 26 | import java.nio.file.Path; 27 | 28 | /** 29 | * A reference to a page inside a web app artifact. 30 | * 31 | * @since 0.8.0 32 | */ 33 | public class ArtifactPageReference implements PageReference { 34 | 35 | private final Path pageFile; 36 | private final ArtifactAppReference appReference; 37 | 38 | /** 39 | * Creates a reference to the page specified by the path. 40 | * 41 | * @param pageFile path to the page 42 | * @param appReference reference to the belonging app 43 | */ 44 | public ArtifactPageReference(Path pageFile, ArtifactAppReference appReference) { 45 | this.pageFile = pageFile; 46 | this.appReference = appReference; 47 | } 48 | 49 | @Override 50 | public String getPathPattern() throws FileOperationException { 51 | StringBuilder sb = new StringBuilder(); 52 | Path pagesDirectory = appReference.getPagesDirectory().relativize(pageFile); 53 | for (Path path : pagesDirectory) { 54 | sb.append('/').append(FilenameUtils.removeExtension(path.toString())); 55 | } 56 | return sb.toString(); 57 | } 58 | 59 | @Override 60 | public FileReference getHtmlFile() { 61 | return new ArtifactFileReference(pageFile); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /components/org.wso2.carbon.uiserver/src/main/java/org/wso2/carbon/uiserver/api/exception/UiServerException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * WSO2 Inc. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | package org.wso2.carbon.uiserver.api.exception; 20 | 21 | /** 22 | * Indicates a generic exception occurred in Carbon UI Server. 23 | * 24 | * @since 0.8.0 25 | */ 26 | public class UiServerException extends Exception { 27 | 28 | /** 29 | * Constructs a new exception with {@code null} as its detail message. The cause is not initialized, and may 30 | * subsequently be initialized by a call to {@link #initCause(Throwable)}. 31 | */ 32 | public UiServerException() { 33 | } 34 | 35 | /** 36 | * Constructs a new exception with the specified detail message. The cause is not initialized, and may 37 | * subsequently be initialized by a call to {@link #initCause}. 38 | * 39 | * @param message the detail message of the exception 40 | */ 41 | public UiServerException(String message) { 42 | super(message); 43 | } 44 | 45 | /** 46 | * Constructs a new exception with the specified cause and a detail message of {@code (cause==null ? null : 47 | * cause.toString())} which typically contains the class and detail message of the {@code cause}. 48 | * 49 | * @param cause the cause of the exception 50 | */ 51 | public UiServerException(Throwable cause) { 52 | super(cause); 53 | } 54 | 55 | /** 56 | * Constructs a new exception with the specified detail message and cause. 57 | * 58 | * @param message the detail message of the exception 59 | * @param cause the cause of the exception 60 | */ 61 | public UiServerException(String message, Throwable cause) { 62 | super(message, cause); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /components/org.wso2.carbon.uiserver/src/main/java/org/wso2/carbon/uiserver/api/exception/RenderingException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * WSO2 Inc. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | package org.wso2.carbon.uiserver.api.exception; 20 | 21 | /** 22 | * Indicates an error occurred when rendering a page. 23 | * 24 | * @since 0.8.0 25 | */ 26 | public class RenderingException extends UiServerRuntimeException { 27 | 28 | /** 29 | * Constructs a new exception with {@code null} as its detail message. The cause is not initialized, and may 30 | * subsequently be initialized by a call to {@link #initCause(Throwable)}. 31 | */ 32 | public RenderingException() { 33 | } 34 | 35 | /** 36 | * Constructs a new exception with the specified detail message. The cause is not initialized, and may subsequently 37 | * be initialized by a call to {@link #initCause}. 38 | * 39 | * @param message the detail message of the exception 40 | */ 41 | public RenderingException(String message) { 42 | super(message); 43 | } 44 | 45 | /** 46 | * Constructs a new exception with the specified cause and a detail message of {@code (cause==null ? null : 47 | * cause.toString())} which typically contains the class and detail message of the {@code cause}. 48 | * 49 | * @param cause the cause of the exception 50 | */ 51 | public RenderingException(Throwable cause) { 52 | super(cause); 53 | } 54 | 55 | /** 56 | * Constructs a new exception with the specified detail message and cause. 57 | * 58 | * @param message the detail message of the exception 59 | * @param cause the cause of the exception 60 | */ 61 | public RenderingException(String message, Throwable cause) { 62 | super(message, cause); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /tests/distribution/src/assembly/bin.xml: -------------------------------------------------------------------------------- 1 | 18 | 19 | 20 | carbon-ui-server 21 | 22 | true 23 | wso2-cuis-${project.version} 24 | 25 | 26 | zip 27 | 28 | 29 | 30 | 31 | target/wso2carbon-kernel-${carbon.kernel.version} 32 | . 33 | 644 34 | 35 | **/*.lock 36 | **/.data 37 | **/.settings 38 | libcairo-swt.so 39 | eclipse 40 | **/*.sh 41 | **/native/* 42 | 43 | 44 | 45 | 46 | target/wso2carbon-kernel-${carbon.kernel.version} 47 | . 48 | 49 | **/*.sh 50 | **/native/* 51 | 52 | 755 53 | 54 | 55 | 56 | carbon-home 57 | . 58 | 59 | **/*.ipr 60 | **/*.iwr 61 | **/*.eclipse 62 | 63 | 644 64 | 65 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /components/org.wso2.carbon.uiserver/src/main/java/org/wso2/carbon/uiserver/api/exception/UiServerRuntimeException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * WSO2 Inc. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | package org.wso2.carbon.uiserver.api.exception; 20 | 21 | /** 22 | * Indicates a generic runtime exception occurred in Carbon UI Server. 23 | * 24 | * @since 0.8.0 25 | */ 26 | public class UiServerRuntimeException extends RuntimeException { 27 | 28 | /** 29 | * Constructs a new exception with {@code null} as its detail message. The cause is not initialized, and may 30 | * subsequently be initialized by a call to {@link #initCause(Throwable)}. 31 | */ 32 | public UiServerRuntimeException() { 33 | } 34 | 35 | /** 36 | * Constructs a new exception with the specified detail message. The cause is not initialized, and may 37 | * subsequently be initialized by a call to {@link #initCause}. 38 | * 39 | * @param message the detail message of the exception 40 | */ 41 | public UiServerRuntimeException(String message) { 42 | super(message); 43 | } 44 | 45 | /** 46 | * Constructs a new exception with the specified cause and a detail message of {@code (cause==null ? null : 47 | * cause.toString())} which typically contains the class and detail message of the {@code cause}. 48 | * 49 | * @param cause the cause of the exception 50 | */ 51 | public UiServerRuntimeException(Throwable cause) { 52 | super(cause); 53 | } 54 | 55 | /** 56 | * Constructs a new exception with the specified detail message and cause. 57 | * 58 | * @param message the detail message of the exception 59 | * @param cause the cause of the exception 60 | */ 61 | public UiServerRuntimeException(String message, Throwable cause) { 62 | super(message, cause); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /components/org.wso2.carbon.uiserver/src/test/java/org/wso2/carbon/uiserver/internal/deployment/msf4j/MicroserviceRegistrationTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * WSO2 Inc. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | package org.wso2.carbon.uiserver.internal.deployment.msf4j; 20 | 21 | import org.osgi.framework.ServiceRegistration; 22 | import org.testng.Assert; 23 | import org.testng.annotations.Test; 24 | import org.wso2.carbon.uiserver.internal.http.HttpTransport; 25 | 26 | import static org.mockito.Mockito.mock; 27 | import static org.mockito.Mockito.verify; 28 | 29 | /** 30 | * Test cases for {@link MicroserviceRegistration} class. 31 | * 32 | * @since 0.15.0 33 | */ 34 | public class MicroserviceRegistrationTest { 35 | 36 | @Test 37 | @SuppressWarnings("unchecked") 38 | public void testGetRegisteredHttpTransport() { 39 | HttpTransport httpTransport = createHttpTransport(); 40 | ServiceRegistration serviceRegistration = mock(ServiceRegistration.class); 41 | MicroserviceRegistration microserviceRegistration = new MicroserviceRegistration(httpTransport, 42 | serviceRegistration); 43 | 44 | Assert.assertEquals(microserviceRegistration.getRegisteredHttpTransport(), httpTransport); 45 | } 46 | 47 | @Test 48 | @SuppressWarnings("unchecked") 49 | public void testUnregister() { 50 | HttpTransport httpTransport = createHttpTransport(); 51 | ServiceRegistration serviceRegistration = mock(ServiceRegistration.class); 52 | new MicroserviceRegistration(httpTransport, serviceRegistration).unregister(); 53 | 54 | verify(serviceRegistration).unregister(); 55 | } 56 | 57 | private static HttpTransport createHttpTransport() { 58 | return new HttpTransport("foo", "bar", "http", "localhost", 9292); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /components/org.wso2.carbon.uiserver/src/main/java/org/wso2/carbon/uiserver/internal/exception/ConfigurationException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * WSO2 Inc. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | package org.wso2.carbon.uiserver.internal.exception; 20 | 21 | /** 22 | * Indicates an error happens when reading or parsing or loading or processing configuration. 23 | * 24 | * @since 0.12.1 25 | */ 26 | public class ConfigurationException extends AppCreationException { 27 | 28 | /** 29 | * Constructs a new exception with {@code null} as its detail message. The cause is not initialized, and may 30 | * subsequently be initialized by a call to {@link #initCause(Throwable)}. 31 | */ 32 | public ConfigurationException() { 33 | } 34 | 35 | /** 36 | * Constructs a new exception with the specified detail message. The cause is not initialized, and may subsequently 37 | * be initialized by a call to {@link #initCause}. 38 | * 39 | * @param message the detail message of the exception 40 | */ 41 | public ConfigurationException(String message) { 42 | super(message); 43 | } 44 | 45 | /** 46 | * Constructs a new exception with the specified cause and a detail message of {@code (cause==null ? null : 47 | * cause.toString())} which typically contains the class and detail message of the {@code cause}. 48 | * 49 | * @param cause the cause of the exception 50 | */ 51 | public ConfigurationException(Throwable cause) { 52 | super(cause); 53 | } 54 | 55 | /** 56 | * Constructs a new exception with the specified detail message and cause. 57 | * 58 | * @param message the detail message of the exception 59 | * @param cause the cause of the exception 60 | */ 61 | public ConfigurationException(String message, Throwable cause) { 62 | super(message, cause); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /components/org.wso2.carbon.uiserver/src/main/java/org/wso2/carbon/uiserver/internal/io/reference/ArtifactFileReference.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * WSO2 Inc. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | package org.wso2.carbon.uiserver.internal.io.reference; 20 | 21 | import org.wso2.carbon.uiserver.internal.exception.FileOperationException; 22 | import org.wso2.carbon.uiserver.internal.io.util.PathUtils; 23 | import org.wso2.carbon.uiserver.internal.reference.FileReference; 24 | 25 | import java.io.IOException; 26 | import java.nio.charset.StandardCharsets; 27 | import java.nio.file.Files; 28 | import java.nio.file.Path; 29 | 30 | /** 31 | * A reference to a file inside a web app artifact.. 32 | * 33 | * @since 0.8.0 34 | */ 35 | public class ArtifactFileReference implements FileReference { 36 | 37 | private final Path filePath; 38 | 39 | /** 40 | * Creates a reference to the file specified by the path. 41 | * 42 | * @param filePath path to the file 43 | */ 44 | public ArtifactFileReference(Path filePath) { 45 | this.filePath = filePath; 46 | } 47 | 48 | @Override 49 | public String getName() throws FileOperationException { 50 | return PathUtils.getName(filePath); 51 | } 52 | 53 | @Override 54 | public String getExtension() throws FileOperationException { 55 | return PathUtils.getExtension(filePath); 56 | } 57 | 58 | @Override 59 | public String getContent() throws FileOperationException { 60 | try { 61 | return new String(Files.readAllBytes(filePath), StandardCharsets.UTF_8); 62 | } catch (IOException e) { 63 | throw new FileOperationException("Cannot read content of file '" + filePath + "'.", e); 64 | } 65 | } 66 | 67 | @Override 68 | public String getFilePath() throws FileOperationException { 69 | return filePath.toString(); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /components/org.wso2.carbon.uiserver/src/main/java/org/wso2/carbon/uiserver/api/exception/HttpErrorException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * WSO2 Inc. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | package org.wso2.carbon.uiserver.api.exception; 20 | 21 | /** 22 | * Indicates a HTTP error. 23 | * 24 | * @since 0.8.0 25 | */ 26 | public class HttpErrorException extends UiServerRuntimeException { 27 | 28 | private final int httpStatusCode; 29 | 30 | /** 31 | * Constructs a new exception with the specified HTTP status code and {@code null} as its detail message. 32 | * 33 | * @param httpStatusCode HTTP error status code 34 | */ 35 | public HttpErrorException(int httpStatusCode) { 36 | this.httpStatusCode = httpStatusCode; 37 | } 38 | 39 | /** 40 | * Constructs a new exception with the specified HTTP status code and detail message. 41 | * 42 | * @param httpStatusCode HTTP error status code 43 | * @param message detail message 44 | */ 45 | public HttpErrorException(int httpStatusCode, String message) { 46 | super(message); 47 | this.httpStatusCode = httpStatusCode; 48 | } 49 | 50 | /** 51 | * Constructs a new exception with the specified HTTP status code, detail message, and cause. 52 | * 53 | * @param httpStatusCode HTTP error status code 54 | * @param message detail message 55 | * @param cause the cause of the exception 56 | */ 57 | public HttpErrorException(int httpStatusCode, String message, Throwable cause) { 58 | super(message, cause); 59 | this.httpStatusCode = httpStatusCode; 60 | } 61 | 62 | /** 63 | * Returns the HTTP status error code of this HTTP exception. 64 | * 65 | * @return HTTP status code of the HTTP exception 66 | */ 67 | public int getHttpStatusCode() { 68 | return this.httpStatusCode; 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /components/org.wso2.carbon.uiserver/src/test/java/org/wso2/carbon/uiserver/api/ThemeTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * WSO2 Inc. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | package org.wso2.carbon.uiserver.api; 20 | 21 | import org.testng.Assert; 22 | import org.testng.annotations.DataProvider; 23 | import org.testng.annotations.Test; 24 | 25 | import static java.util.Arrays.asList; 26 | import static java.util.Collections.emptyList; 27 | import static java.util.Collections.singletonList; 28 | 29 | /** 30 | * Test cases for {@link Theme} class. 31 | * 32 | * @since 0.12.0 33 | */ 34 | public class ThemeTest { 35 | 36 | @DataProvider 37 | public Object[][] overridableThemes() { 38 | return new Object[][]{ 39 | {new Theme("t1", "p1"), new Theme("t1", "p2")}, 40 | {new Theme("t1", emptyList()), new Theme("t1", singletonList("p2"))}, 41 | {new Theme("t1", asList("p1", "p11")), new Theme("t1", asList("p2", "p22"))} 42 | }; 43 | } 44 | 45 | @Test(dataProvider = "overridableThemes") 46 | public void testCanOverrideBy(Theme theme1, Theme theme2) { 47 | Assert.assertTrue(theme1.canOverrideBy(theme2)); 48 | } 49 | 50 | @DataProvider 51 | public Object[][] equalThemes() { 52 | Theme theme = new Theme("t0", "p0"); 53 | return new Object[][]{ 54 | {theme, theme}, 55 | {new Theme("t1", "p1"), new Theme("t1", "p1")}, 56 | {new Theme("t1", emptyList()), new Theme("t1", emptyList())}, 57 | {new Theme("t1", singletonList("p1")), new Theme("t1", singletonList("p1"))}, 58 | {new Theme("t1", asList("p1", "p11")), new Theme("t1", asList("p1", "p11"))} 59 | }; 60 | } 61 | 62 | @Test(dataProvider = "equalThemes") 63 | public void testEquals(Theme theme1, Theme theme2) { 64 | Assert.assertEquals(theme1, theme2); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /components/org.wso2.carbon.uiserver/src/main/java/org/wso2/carbon/uiserver/internal/exception/AppCreationException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * WSO2 Inc. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | package org.wso2.carbon.uiserver.internal.exception; 20 | 21 | import org.wso2.carbon.uiserver.api.exception.UiServerRuntimeException; 22 | 23 | /** 24 | * Indicates an error occurred when creating a web app. 25 | * 26 | * @since 0.8.0 27 | */ 28 | public class AppCreationException extends UiServerRuntimeException { 29 | 30 | /** 31 | * Constructs a new exception with {@code null} as its detail message. The cause is not initialized, and may 32 | * subsequently be initialized by a call to {@link #initCause(Throwable)}. 33 | */ 34 | public AppCreationException() { 35 | } 36 | 37 | /** 38 | * Constructs a new exception with the specified detail message. The cause is not initialized, and may subsequently 39 | * be initialized by a call to {@link #initCause}. 40 | * 41 | * @param message the detail message of the exception 42 | */ 43 | public AppCreationException(String message) { 44 | super(message); 45 | } 46 | 47 | /** 48 | * Constructs a new exception with the specified cause and a detail message of {@code (cause==null ? null : 49 | * cause.toString())} which typically contains the class and detail message of the {@code cause}. 50 | * 51 | * @param cause the cause of the exception 52 | */ 53 | public AppCreationException(Throwable cause) { 54 | super(cause); 55 | } 56 | 57 | /** 58 | * Constructs a new exception with the specified detail message and cause. 59 | * 60 | * @param message the detail message of the exception 61 | * @param cause the cause of the exception 62 | */ 63 | public AppCreationException(String message, Throwable cause) { 64 | super(message, cause); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /components/org.wso2.carbon.uiserver/src/main/java/org/wso2/carbon/uiserver/internal/exception/FileOperationException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * WSO2 Inc. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | package org.wso2.carbon.uiserver.internal.exception; 20 | 21 | 22 | import org.wso2.carbon.uiserver.api.exception.UiServerRuntimeException; 23 | 24 | /** 25 | * Indicates an error occurred in a file system related operation. 26 | * 27 | * @since 0.8.0 28 | */ 29 | public class FileOperationException extends UiServerRuntimeException { 30 | 31 | /** 32 | * Constructs a new exception with {@code null} as its detail message. The cause is not initialized, and may 33 | * subsequently be initialized by a call to {@link #initCause(Throwable)}. 34 | */ 35 | public FileOperationException() { 36 | } 37 | 38 | /** 39 | * Constructs a new exception with the specified detail message. The cause is not initialized, and may 40 | * subsequently be initialized by a call to {@link #initCause}. 41 | * 42 | * @param message the detail message of the exception 43 | */ 44 | public FileOperationException(String message) { 45 | super(message); 46 | } 47 | 48 | /** 49 | * Constructs a new exception with the specified cause and a detail message of {@code (cause==null ? null : 50 | * cause.toString())} which typically contains the class and detail message of the {@code cause}. 51 | * 52 | * @param cause the cause of the exception 53 | */ 54 | public FileOperationException(Throwable cause) { 55 | super(cause); 56 | } 57 | 58 | /** 59 | * Constructs a new exception with the specified detail message and cause. 60 | * 61 | * @param message the detail message of the exception 62 | * @param cause the cause of the exception 63 | */ 64 | public FileOperationException(String message, Throwable cause) { 65 | super(message, cause); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /pull_request_template.md: -------------------------------------------------------------------------------- 1 | ## Purpose 2 | > Describe the problems, issues, or needs driving this feature/fix and include links to related issues in the following format: Resolves issue1, issue2, etc. 3 | 4 | ## Goals 5 | > Describe the solutions that this feature/fix will introduce to resolve the problems described above 6 | 7 | ## Approach 8 | > Describe how you are implementing the solutions. Include an animated GIF or screenshot if the change affects the UI (email documentation@wso2.com to review all UI text). Include a link to a Markdown file or Google doc if the feature write-up is too long to paste here. 9 | 10 | ## User stories 11 | > Summary of user stories addressed by this change> 12 | 13 | ## Release note 14 | > Brief description of the new feature or bug fix as it will appear in the release notes 15 | 16 | ## Documentation 17 | > Link(s) to product documentation that addresses the changes of this PR. If no doc impact, enter “N/A” plus brief explanation of why there’s no doc impact 18 | 19 | ## Training 20 | > Link to the PR for changes to the training content in https://github.com/wso2/WSO2-Training, if applicable 21 | 22 | ## Certification 23 | > Type “Sent” when you have provided new/updated certification questions, plus four answers for each question (correct answer highlighted in bold), based on this change. Certification questions/answers should be sent to certification@wso2.com and NOT pasted in this PR. If there is no impact on certification exams, type “N/A” and explain why. 24 | 25 | ## Marketing 26 | > Link to drafts of marketing content that will describe and promote this feature, including product page changes, technical articles, blog posts, videos, etc., if applicable 27 | 28 | ## Automation tests 29 | - Unit tests 30 | > Code coverage information 31 | - Integration tests 32 | > Details about the test cases and coverage 33 | 34 | ## Security checks 35 | - Followed secure coding standards in http://wso2.com/technical-reports/wso2-secure-engineering-guidelines? yes/no 36 | - Ran FindSecurityBugs plugin and verified report? yes/no 37 | - Confirmed that this PR doesn't commit any keys, passwords, tokens, usernames, or other secrets? yes/no 38 | 39 | ## Samples 40 | > Provide high-level details about the samples related to this feature 41 | 42 | ## Related PRs 43 | > List any other related PRs 44 | 45 | ## Migrations (if applicable) 46 | > Describe migration steps and platforms on which migration has been tested 47 | 48 | ## Test environment 49 | > List all JDK versions, operating systems, databases, and browser/versions on which this feature/fix was tested 50 | 51 | ## Learning 52 | > Describe the research phase and any blog posts, patterns, libraries, or add-ons you used to solve the problem. -------------------------------------------------------------------------------- /components/org.wso2.carbon.uiserver/src/main/java/org/wso2/carbon/uiserver/internal/exception/AppDeploymentEventListenerException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * WSO2 Inc. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | package org.wso2.carbon.uiserver.internal.exception; 20 | 21 | import org.wso2.carbon.uiserver.api.exception.UiServerRuntimeException; 22 | 23 | /** 24 | * Indicates an error occurred when invoking an app deployment event listener. 25 | * 26 | * @see org.wso2.carbon.uiserver.internal.deployment.AppDeploymentEventListener 27 | * @since 0.18.0 28 | */ 29 | public class AppDeploymentEventListenerException extends UiServerRuntimeException { 30 | 31 | /** 32 | * Constructs a new exception with {@code null} as its detail message. The cause is not initialized, and may 33 | * subsequently be initialized by a call to {@link #initCause(Throwable)}. 34 | */ 35 | public AppDeploymentEventListenerException() { 36 | } 37 | 38 | /** 39 | * Constructs a new exception with the specified detail message. The cause is not initialized, and may subsequently 40 | * be initialized by a call to {@link #initCause}. 41 | * 42 | * @param message the detail message of the exception 43 | */ 44 | public AppDeploymentEventListenerException(String message) { 45 | super(message); 46 | } 47 | 48 | /** 49 | * Constructs a new exception with the specified cause and a detail message of {@code (cause==null ? null : 50 | * cause.toString())} which typically contains the class and detail message of the {@code cause}. 51 | * 52 | * @param cause the cause of the exception 53 | */ 54 | public AppDeploymentEventListenerException(Throwable cause) { 55 | super(cause); 56 | } 57 | 58 | /** 59 | * Constructs a new exception with the specified detail message and cause. 60 | * 61 | * @param message the detail message of the exception 62 | * @param cause the cause of the exception 63 | */ 64 | public AppDeploymentEventListenerException(String message, Throwable cause) { 65 | super(message, cause); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /components/org.wso2.carbon.uiserver/src/test/java/org/wso2/carbon/uiserver/api/ExtensionTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * WSO2 Inc. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | package org.wso2.carbon.uiserver.api; 20 | 21 | import org.testng.Assert; 22 | import org.testng.annotations.DataProvider; 23 | import org.testng.annotations.Test; 24 | 25 | import static java.util.Arrays.asList; 26 | import static java.util.Collections.emptyList; 27 | import static java.util.Collections.singletonList; 28 | 29 | /** 30 | * Test cases for {@link Extension} class. 31 | * 32 | * @since 0.12.0 33 | */ 34 | public class ExtensionTest { 35 | 36 | @DataProvider 37 | public Object[][] overridableExtensions() { 38 | return new Object[][]{ 39 | {new Extension("e1", "t1", "p1"), new Extension("e1", "t1", "p2")}, 40 | {new Extension("e1", "t1", emptyList()), new Extension("e1", "t1", singletonList("p2"))}, 41 | {new Extension("e1", "t1", asList("p1", "p11")), new Extension("e1", "t1", asList("p2", "p22"))} 42 | }; 43 | } 44 | 45 | @Test(dataProvider = "overridableExtensions") 46 | public void testCanOverrideBy(Extension extension1, Extension extension2) { 47 | Assert.assertTrue(extension1.canOverrideBy(extension2)); 48 | } 49 | 50 | @DataProvider 51 | public Object[][] equalExtensions() { 52 | Extension extension = new Extension("e0", "t0", "p0"); 53 | return new Object[][]{ 54 | {extension, extension}, 55 | {new Extension("e1", "t1", "p1"), new Extension("e1", "t1", "p1")}, 56 | {new Extension("e1", "t1", emptyList()), new Extension("e1", "t1", emptyList())}, 57 | {new Extension("e1", "t1", singletonList("p1")), new Extension("e1", "t1", singletonList("p1"))}, 58 | {new Extension("e1", "t1", asList("p1", "p11")), new Extension("e1", "t1", asList("p1", "p11"))} 59 | }; 60 | } 61 | 62 | @Test(dataProvider = "equalExtensions") 63 | public void testEquals(Extension extension1, Extension extension2) { 64 | Assert.assertEquals(extension1, extension2); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /components/org.wso2.carbon.uiserver/src/test/java/org/wso2/carbon/uiserver/api/util/MultilocationalTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * WSO2 Inc. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | package org.wso2.carbon.uiserver.api.util; 20 | 21 | import com.google.common.collect.ImmutableList; 22 | import org.testng.Assert; 23 | import org.testng.annotations.Test; 24 | 25 | import java.util.List; 26 | 27 | /** 28 | * Test cases for {@link Multilocational} interface. 29 | * 30 | * @since 0.12.0 31 | */ 32 | public class MultilocationalTest { 33 | 34 | @Test 35 | public void testGetPaths() { 36 | ImmutableList paths = ImmutableList.of("p1", "p2"); 37 | Multilocational multilocational = createMultilocational(paths); 38 | 39 | Assert.assertEquals(multilocational.getPaths(), paths); 40 | } 41 | 42 | @Test 43 | public void testGetHighestPriorityPath() { 44 | ImmutableList paths = ImmutableList.of("p1", "p2"); 45 | Multilocational multilocational = createMultilocational(paths); 46 | 47 | Assert.assertEquals(multilocational.getHighestPriorityPath(), "p1"); 48 | } 49 | 50 | @Test 51 | public void testGetLeastPriorityPath() { 52 | ImmutableList paths = ImmutableList.of("p1", "p2"); 53 | Multilocational multilocational = createMultilocational(paths); 54 | 55 | Assert.assertEquals(multilocational.getLeastPriorityPath(), "p2"); 56 | } 57 | 58 | private static Multilocational createMultilocational(List paths) { 59 | return new MultilocationalImpl(paths); 60 | } 61 | 62 | /** 63 | * Implementation of {@link Multilocational} for unit tests. 64 | * 65 | * @since 0.12.0 66 | */ 67 | private static class MultilocationalImpl implements Multilocational { 68 | 69 | private final List paths; 70 | 71 | /** 72 | * Creates a new instance. 73 | * 74 | * @param paths paths 75 | */ 76 | public MultilocationalImpl(List paths) { 77 | this.paths = paths; 78 | } 79 | 80 | @Override 81 | public List getPaths() { 82 | return paths; 83 | } 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /components/org.wso2.carbon.uiserver/src/test/java/org/wso2/carbon/uiserver/internal/deployment/parser/YamlFileParserTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * WSO2 Inc. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | package org.wso2.carbon.uiserver.internal.deployment.parser; 20 | 21 | import org.testng.Assert; 22 | import org.testng.annotations.Test; 23 | import org.wso2.carbon.uiserver.internal.exception.ConfigurationException; 24 | import org.wso2.carbon.uiserver.internal.exception.FileOperationException; 25 | import org.wso2.carbon.uiserver.internal.reference.FileReference; 26 | 27 | import java.util.Map; 28 | 29 | import static org.mockito.Mockito.mock; 30 | import static org.mockito.Mockito.when; 31 | 32 | /** 33 | * Test cases for {@link YamlFileParser} class. 34 | * 35 | * @since 0.12.5 36 | */ 37 | public class YamlFileParserTest { 38 | 39 | @Test 40 | public void testParseWhenCannotReadFile() { 41 | FileReference fileReference = mock(FileReference.class); 42 | when(fileReference.getContent()).thenThrow(FileOperationException.class); 43 | 44 | Assert.assertThrows(ConfigurationException.class, () -> YamlFileParser.parse(fileReference, Map.class)); 45 | } 46 | 47 | @Test 48 | public void testParseInvalidYaml() { 49 | FileReference fileReference = mock(FileReference.class); 50 | when(fileReference.getContent()).thenReturn("foo: bar\n -: foobar"); 51 | 52 | Assert.assertThrows(ConfigurationException.class, () -> YamlFileParser.parse(fileReference, Map.class)); 53 | } 54 | 55 | @Test 56 | public void testParseEmptyYaml() { 57 | FileReference fileReference = mock(FileReference.class); 58 | when(fileReference.getContent()).thenReturn("# nothing here"); 59 | 60 | Assert.assertThrows(ConfigurationException.class, () -> YamlFileParser.parse(fileReference, Map.class)); 61 | } 62 | 63 | @Test 64 | public void testParse() { 65 | FileReference fileReference = mock(FileReference.class); 66 | when(fileReference.getContent()).thenReturn("foo: bar\nfoobar: barz"); 67 | 68 | Map map = YamlFileParser.parse(fileReference, Map.class); 69 | Assert.assertEquals(map.get("foo"), "bar"); 70 | Assert.assertEquals(map.get("foobar"), "barz"); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /components/org.wso2.carbon.uiserver/src/main/java/org/wso2/carbon/uiserver/api/Page.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * WSO2 Inc. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | package org.wso2.carbon.uiserver.api; 20 | 21 | import org.wso2.carbon.uiserver.api.exception.RenderingException; 22 | import org.wso2.carbon.uiserver.api.http.HttpRequest; 23 | 24 | import java.util.Objects; 25 | 26 | /** 27 | * Represents a page of a web app. 28 | * 29 | * @since 0.8.0 30 | */ 31 | public abstract class Page implements Comparable { 32 | 33 | private final UriPatten uriPatten; 34 | 35 | /** 36 | * Creates a new page. 37 | * 38 | * @param uriPatten URI pattern of the page 39 | */ 40 | public Page(UriPatten uriPatten) { 41 | this.uriPatten = uriPatten; 42 | } 43 | 44 | /** 45 | * Returns the URI pattern of this page. 46 | * 47 | * @return URI pattern of this page 48 | */ 49 | public UriPatten getUriPatten() { 50 | return uriPatten; 51 | } 52 | 53 | /** 54 | * Checks whether this page matches to the given URI. 55 | * 56 | * @param uri URI to be matched 57 | * @return {@code true} iff matches, otherwise {@code false} 58 | */ 59 | public boolean matches(String uri) { 60 | return uriPatten.matches(uri); 61 | } 62 | 63 | /** 64 | * Renders this page and returns a HTML document. 65 | * 66 | * @param request HTTP request 67 | * @param configuration configurations of the app 68 | * @return output html of page rendering 69 | * @throws RenderingException if an error occurred during page rendering 70 | */ 71 | public abstract String render(HttpRequest request, Configuration configuration) throws RenderingException; 72 | 73 | @Override 74 | public int compareTo(Page otherPage) { 75 | return (otherPage == null) ? 1 : this.uriPatten.compareTo(otherPage.uriPatten); 76 | } 77 | 78 | @Override 79 | public boolean equals(Object obj) { 80 | return (this == obj) || ((obj instanceof Page) && (this.compareTo((Page) obj) == 0)); 81 | } 82 | 83 | @Override 84 | public int hashCode() { 85 | return Objects.hash(uriPatten); 86 | } 87 | 88 | @Override 89 | public String toString() { 90 | return "Page{uriPatten=" + uriPatten + "}"; 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /components/org.wso2.carbon.uiserver/src/main/java/org/wso2/carbon/uiserver/internal/io/util/MimeMapper.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * WSO2 Inc. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | package org.wso2.carbon.uiserver.internal.io.util; 20 | 21 | import org.wso2.carbon.uiserver.api.exception.UiServerRuntimeException; 22 | import org.yaml.snakeyaml.Yaml; 23 | 24 | import java.io.IOException; 25 | import java.io.InputStream; 26 | import java.util.Map; 27 | import java.util.Optional; 28 | 29 | /** 30 | * Maps MIME types to file extensions. 31 | * 32 | * @since 0.8.0 33 | */ 34 | public class MimeMapper { 35 | 36 | private static final String FILE_NAME_MIME_TYPES = "mime-types.yaml"; 37 | private static Map mimeTypes; 38 | 39 | private MimeMapper() { 40 | } 41 | 42 | @SuppressWarnings("unchecked") 43 | private static Map loadMimeTypes() throws UiServerRuntimeException { 44 | try (InputStream inputStream = MimeMapper.class.getClassLoader().getResourceAsStream(FILE_NAME_MIME_TYPES)) { 45 | if (inputStream == null) { 46 | throw new UiServerRuntimeException( 47 | "Cannot find MIME types file '" + FILE_NAME_MIME_TYPES + "' in class path."); 48 | } 49 | return new Yaml().loadAs(inputStream, Map.class); 50 | } catch (IOException e) { 51 | throw new UiServerRuntimeException("Cannot read MIME types file '" + FILE_NAME_MIME_TYPES + "'.", e); 52 | } catch (Exception e) { 53 | throw new UiServerRuntimeException("MIME types file is '" + FILE_NAME_MIME_TYPES + "' is invalid.", e); 54 | } 55 | } 56 | 57 | /** 58 | * Returns the MIME type for the given file extension. 59 | * 60 | * @param extension file extension 61 | * @return MIME type for the given file extension 62 | * @throws UiServerRuntimeException if cannot find or read the MIME types file, or it is invalid 63 | */ 64 | public static Optional getMimeType(String extension) throws UiServerRuntimeException { 65 | if (mimeTypes == null) { 66 | synchronized (MimeMapper.class) { 67 | if (mimeTypes == null) { 68 | mimeTypes = loadMimeTypes(); 69 | } 70 | } 71 | } 72 | return Optional.ofNullable(mimeTypes.get(extension)); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /components/org.wso2.carbon.uiserver/src/main/java/org/wso2/carbon/uiserver/internal/http/PageRequestDispatcher.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * WSO2 Inc. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | package org.wso2.carbon.uiserver.internal.http; 20 | 21 | import org.wso2.carbon.uiserver.api.App; 22 | import org.wso2.carbon.uiserver.api.exception.PageNotFoundException; 23 | import org.wso2.carbon.uiserver.api.exception.PageRedirectException; 24 | import org.wso2.carbon.uiserver.api.exception.RenderingException; 25 | import org.wso2.carbon.uiserver.api.http.HttpRequest; 26 | import org.wso2.carbon.uiserver.api.http.HttpResponse; 27 | 28 | import static org.wso2.carbon.uiserver.api.http.HttpResponse.CONTENT_TYPE_TEXT_HTML; 29 | import static org.wso2.carbon.uiserver.api.http.HttpResponse.HEADER_LOCATION; 30 | 31 | /** 32 | * Dispatcher for HTTP request for pages. 33 | * 34 | * @since 0.13.4 35 | */ 36 | public class PageRequestDispatcher { 37 | 38 | private final App app; 39 | 40 | /** 41 | * Creates a new request dispatcher. 42 | * 43 | * @param app web app to be served 44 | */ 45 | public PageRequestDispatcher(App app) { 46 | this.app = app; 47 | } 48 | 49 | /** 50 | * Serves to the supplied HTTP request and returns a HTTP response. 51 | * 52 | * @param request HTTP request to be served 53 | * @return a HTTP response that carries the result 54 | */ 55 | public HttpResponse serve(HttpRequest request) { 56 | try { 57 | String html = app.renderPage(request); 58 | return ResponseBuilder.ok(html, CONTENT_TYPE_TEXT_HTML) 59 | .headers(app.getConfiguration().getResponseHeaders().forPages()) 60 | .build(); 61 | } catch (RenderingException e) { 62 | return ResponseBuilder 63 | .serverError("An error occurred when rendering page '" + request.getUriWithoutContextPath() + "'.") 64 | .build(); 65 | } catch (PageNotFoundException e) { 66 | return ResponseBuilder.notFound("Page '" + request.getUriWithoutContextPath() + "' does not exists.") 67 | .build(); 68 | } catch (PageRedirectException e) { 69 | return ResponseBuilder.status(e.getHttpStatusCode()) 70 | .header(HEADER_LOCATION, e.getRedirectUrl()) 71 | .build(); 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /components/org.wso2.carbon.uiserver/src/main/java/org/wso2/carbon/uiserver/internal/io/reference/ArtifactI18nResourceReference.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * WSO2 Inc. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | package org.wso2.carbon.uiserver.internal.io.reference; 20 | 21 | import com.google.gson.Gson; 22 | import com.google.gson.JsonParseException; 23 | import com.google.gson.reflect.TypeToken; 24 | import org.wso2.carbon.uiserver.internal.exception.FileOperationException; 25 | import org.wso2.carbon.uiserver.internal.io.util.PathUtils; 26 | import org.wso2.carbon.uiserver.internal.reference.I18nResourceReference; 27 | 28 | import java.io.BufferedReader; 29 | import java.io.IOException; 30 | import java.lang.reflect.Type; 31 | import java.nio.charset.StandardCharsets; 32 | import java.nio.file.Files; 33 | import java.nio.file.Path; 34 | import java.util.Locale; 35 | import java.util.Map; 36 | 37 | /** 38 | * A reference to an i18n resource inside a web app artifact. 39 | * 40 | * @since 0.8.0 41 | */ 42 | public class ArtifactI18nResourceReference implements I18nResourceReference { 43 | 44 | public static final String I18N_RESOURCE_FILE_EXTENSION = "json"; 45 | private static final Gson GSON = new Gson(); 46 | private static final Type GSON_TYPE = new TypeToken>() { }.getType(); 47 | 48 | private final Path messagesFile; 49 | 50 | /** 51 | * Creates a reference to the i18n resource specified by the path. 52 | * 53 | * @param messagesFile path to the i18n resource 54 | */ 55 | public ArtifactI18nResourceReference(Path messagesFile) { 56 | this.messagesFile = messagesFile; 57 | } 58 | 59 | @Override 60 | public Locale getLocale() throws FileOperationException { 61 | return Locale.forLanguageTag(PathUtils.getExtension(messagesFile)); 62 | } 63 | 64 | @Override 65 | public Map getMessages() throws FileOperationException { 66 | try { 67 | BufferedReader bufferedReader = Files.newBufferedReader(messagesFile, StandardCharsets.UTF_8); 68 | return GSON.fromJson(bufferedReader, GSON_TYPE); 69 | } catch (IOException e) { 70 | throw new FileOperationException("Cannot read content of i18n message file '" + messagesFile + "'."); 71 | } catch (JsonParseException e) { 72 | throw new FileOperationException("I18n message file '" + messagesFile + "' is not a valid JSON."); 73 | } 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /components/org.wso2.carbon.uiserver/src/main/java/org/wso2/carbon/uiserver/internal/http/util/IpAddressUtils.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * WSO2 Inc. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | package org.wso2.carbon.uiserver.internal.http.util; 20 | 21 | import org.slf4j.Logger; 22 | import org.slf4j.LoggerFactory; 23 | 24 | import java.net.Inet4Address; 25 | import java.net.InetAddress; 26 | import java.net.NetworkInterface; 27 | import java.net.SocketException; 28 | import java.util.Enumeration; 29 | import java.util.Optional; 30 | 31 | /** 32 | * Utility functions for Internet Protocol addresses. 33 | * 34 | * @since 0.18.0 35 | */ 36 | public class IpAddressUtils { 37 | 38 | private static final Logger LOGGER = LoggerFactory.getLogger(IpAddressUtils.class); 39 | private static String localInternetAddress; 40 | 41 | /** 42 | * Returns Internet Protocol version 4 (IPv4) address of this computer. 43 | * 44 | * @return IP address of this computer 45 | */ 46 | public static Optional getLocalIpAddress() { 47 | if (localInternetAddress != null) { 48 | return Optional.of(localInternetAddress); 49 | } 50 | 51 | try { 52 | Enumeration networkInterfaces = NetworkInterface.getNetworkInterfaces(); 53 | outer_loop: 54 | while (networkInterfaces.hasMoreElements()) { 55 | NetworkInterface networkInterface = networkInterfaces.nextElement(); 56 | if (!networkInterface.isUp() || networkInterface.isLoopback() || networkInterface.isVirtual()) { 57 | continue; 58 | } 59 | 60 | Enumeration inetAddresses = networkInterface.getInetAddresses(); 61 | while (inetAddresses.hasMoreElements()) { 62 | InetAddress inetAddress = inetAddresses.nextElement(); 63 | if ((inetAddress instanceof Inet4Address) && !inetAddress.isLoopbackAddress()) { 64 | localInternetAddress = inetAddress.getHostAddress(); 65 | break outer_loop; 66 | } 67 | } 68 | } 69 | } catch (SocketException e) { 70 | // Log level DEBUG since this is not a 'breaking' error. 71 | LOGGER.debug("Cannot access information on network interfaces.", e); 72 | } 73 | return Optional.ofNullable(localInternetAddress); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /components/org.wso2.carbon.uiserver/src/main/java/org/wso2/carbon/uiserver/api/util/Overridable.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * WSO2 Inc. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | package org.wso2.carbon.uiserver.api.util; 20 | 21 | import java.util.Objects; 22 | import java.util.Optional; 23 | 24 | /** 25 | * Represents an entity that can be overridden by another entity . 26 | * 27 | * @param the type of the objects that can be use to override this object 28 | * @since 0.12.0 29 | */ 30 | public interface Overridable { 31 | 32 | /** 33 | * Overrides this object (base) by the supplied object (override) and returns a new object that represents the 34 | * override. 35 | * 36 | * @param override the object that overrides this object 37 | * @return new object that represents the override 38 | * @throws IllegalArgumentException if this object cannot be overridden the the supplied object 39 | */ 40 | T override(T override); 41 | 42 | /** 43 | * Returns the base object of the override. 44 | * 45 | * @return {@code this} if has not been overridden, otherwise the base object 46 | */ 47 | T getBase(); 48 | 49 | /** 50 | * Returns the overriding object of the override. 51 | * 52 | * @return the overriding object of has been overridden, otherwise {@link Optional#empty() empty} 53 | */ 54 | default Optional getOverride() { 55 | return Optional.empty(); 56 | } 57 | 58 | /** 59 | * Returns whether this object has been overridden by some other object. 60 | * 61 | * @return {@code true} if has been overridden, otherwise {@code false} 62 | */ 63 | default boolean hasOverridden() { 64 | return this.getOverride().isPresent(); 65 | } 66 | 67 | /** 68 | * Returns whether this object has been overridden by the specified object. 69 | * 70 | * @param other other object to be checked 71 | * @return {@code true} if has been overridden by the supplied object, otherwise {@code false} 72 | */ 73 | default boolean hasOverriddenBy(T other) { 74 | return this.getOverride() 75 | .map(override -> Objects.equals(other, override)) 76 | .orElse(false); 77 | } 78 | 79 | /** 80 | * Returns whether this object can be overridden by the specified object. 81 | * 82 | * @param other other object to be checked 83 | * @return {@code true} if can be overridden, otherwise {@code false} 84 | */ 85 | default boolean canOverrideBy(T other) { 86 | return (other != null) && (this.hashCode() == other.hashCode()); 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /components/org.wso2.carbon.uiserver/src/main/java/org/wso2/carbon/uiserver/internal/deployment/msf4j/WebappMicroservice.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * WSO2 Inc. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | package org.wso2.carbon.uiserver.internal.deployment.msf4j; 20 | 21 | import org.wso2.carbon.uiserver.api.http.HttpRequest; 22 | import org.wso2.carbon.uiserver.api.http.HttpResponse; 23 | import org.wso2.carbon.uiserver.internal.http.msf4j.Msf4jHttpRequest; 24 | import org.wso2.msf4j.Microservice; 25 | import org.wso2.msf4j.Request; 26 | 27 | import java.util.function.Function; 28 | import javax.ws.rs.GET; 29 | import javax.ws.rs.Path; 30 | import javax.ws.rs.core.Context; 31 | import javax.ws.rs.core.NewCookie; 32 | import javax.ws.rs.core.Response; 33 | 34 | /** 35 | * Microservice that acts as the HTTP transport for a web app. 36 | * 37 | * @since 0.8.0 38 | */ 39 | public class WebappMicroservice implements Microservice { 40 | 41 | private static final String PATH_ROOT = ""; 42 | private static final String PATH_ALL = ".*"; 43 | 44 | private final Function httpListener; 45 | 46 | /** 47 | * Creates a new microservice. 48 | * 49 | * @param httpListener HTTP requests listener that handles the incoming HTTP requests 50 | */ 51 | public WebappMicroservice(Function httpListener) { 52 | this.httpListener = httpListener; 53 | } 54 | 55 | @GET 56 | @Path(PATH_ALL) 57 | public Response getAll(@Context Request request) { 58 | return getImpl(request); 59 | } 60 | 61 | @GET 62 | @Path(PATH_ROOT) 63 | public Response getRoot(@Context Request request) { 64 | return getImpl(request); 65 | } 66 | 67 | private Response getImpl(@Context Request request) { 68 | Msf4jHttpRequest httpRequest = new Msf4jHttpRequest(request); 69 | return buildResponse(httpListener.apply(httpRequest)); 70 | } 71 | 72 | private Response buildResponse(HttpResponse httpResponse) { 73 | Response.ResponseBuilder responseBuilder = Response.status(httpResponse.getStatus()); 74 | if (httpResponse.getContent() != null) { 75 | responseBuilder.entity(httpResponse.getContent()).type(httpResponse.getContentType()); 76 | } 77 | httpResponse.getHeaders().entrySet() 78 | .forEach(entry -> responseBuilder.header(entry.getKey(), entry.getValue())); 79 | httpResponse.getCookies().entrySet() 80 | .forEach(entry -> responseBuilder.cookie(new NewCookie(entry.getKey(), entry.getValue()))); 81 | return responseBuilder.build(); 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /components/org.wso2.carbon.uiserver/src/main/java/org/wso2/carbon/uiserver/internal/impl/HbsPage.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * WSO2 Inc. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | package org.wso2.carbon.uiserver.internal.impl; 20 | 21 | import com.github.jknack.handlebars.Context; 22 | import com.github.jknack.handlebars.Handlebars; 23 | import com.github.jknack.handlebars.HandlebarsException; 24 | import com.github.jknack.handlebars.Template; 25 | import org.wso2.carbon.uiserver.api.Configuration; 26 | import org.wso2.carbon.uiserver.api.Page; 27 | import org.wso2.carbon.uiserver.api.UriPatten; 28 | import org.wso2.carbon.uiserver.api.exception.RenderingException; 29 | import org.wso2.carbon.uiserver.api.http.HttpRequest; 30 | import org.wso2.carbon.uiserver.internal.exception.AppCreationException; 31 | import org.wso2.carbon.uiserver.internal.exception.FileOperationException; 32 | 33 | import java.io.IOException; 34 | import java.util.Collections; 35 | import java.util.Map; 36 | 37 | /** 38 | * Page based on a Handlebars template. 39 | * 40 | * @since 0.10.3 41 | */ 42 | public class HbsPage extends Page { 43 | 44 | private static final Handlebars HANDLEBARS = new Handlebars(); 45 | 46 | private final Template template; 47 | 48 | /** 49 | * Creates a new page based on a Handlebars template. 50 | * 51 | * @param uriPatten URI pattern of the page 52 | * @param template Handlebars template 53 | */ 54 | public HbsPage(UriPatten uriPatten, String template) { 55 | super(uriPatten); 56 | this.template = compile(template); 57 | } 58 | 59 | @Override 60 | public String render(HttpRequest request, Configuration configuration) throws RenderingException { 61 | Map model = Collections.singletonMap("@contextPath", request.getContextPath()); 62 | Context context = Context.newContext(model); 63 | try { 64 | return template.apply(context); 65 | } catch (IOException e) { 66 | throw new RenderingException("Cannot load page Handlebars template.", e); 67 | } catch (HandlebarsException e) { 68 | throw new RenderingException("Cannot render page Handlebars template.", e); 69 | } 70 | } 71 | 72 | private static Template compile(String template) { 73 | try { 74 | return HANDLEBARS.compileInline(template); 75 | } catch (IOException e) { 76 | throw new FileOperationException("Cannot load Handlebars template.", e); 77 | } catch (HandlebarsException e) { 78 | throw new AppCreationException("Cannot compile Handlebars template.", e); 79 | } 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /components/org.wso2.carbon.uiserver/src/test/java/org/wso2/carbon/uiserver/api/util/OverridableTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * WSO2 Inc. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | package org.wso2.carbon.uiserver.api.util; 20 | 21 | import org.testng.Assert; 22 | import org.testng.annotations.Test; 23 | 24 | import java.util.Optional; 25 | 26 | /** 27 | * Test cases for {@link Overridable} interface. 28 | * 29 | * @since 0.12.0 30 | */ 31 | public class OverridableTest { 32 | 33 | @Test 34 | public void testGetOverride() { 35 | Object override = new Object(); 36 | Overridable overridable = createOverridable(override); 37 | 38 | Assert.assertTrue(overridable.getOverride().isPresent()); 39 | Assert.assertEquals(overridable.getOverride().orElse(null), override); 40 | 41 | Assert.assertFalse(createOverridable(null).getOverride().isPresent()); 42 | } 43 | 44 | @Test 45 | public void testHasOverridden() { 46 | Assert.assertTrue(createOverridable(new Object()).hasOverridden()); 47 | Assert.assertFalse(createOverridable(null).hasOverridden()); 48 | } 49 | 50 | @Test 51 | public void testHasOverriddenBy() { 52 | Object override = new Object(); 53 | Overridable overridable = createOverridable(override); 54 | 55 | Assert.assertTrue(overridable.hasOverriddenBy(override)); 56 | Assert.assertFalse(overridable.hasOverriddenBy(new Object())); 57 | } 58 | 59 | private static Overridable createOverridable(Object override) { 60 | return new OverridableImpl(override); 61 | } 62 | 63 | /** 64 | * Implementation of {@link Overridable} for unit tests. 65 | * 66 | * @since 0.12.0 67 | */ 68 | private static class OverridableImpl implements Overridable { 69 | 70 | private final Object override; 71 | 72 | /** 73 | * Creates a new instance. 74 | * 75 | * @param override override 76 | */ 77 | public OverridableImpl(Object override) { 78 | this.override = override; 79 | } 80 | 81 | @Override 82 | public Object override(Object override) { 83 | throw new UnsupportedOperationException("This method is not needed for this unit test."); 84 | } 85 | 86 | @Override 87 | public Object getBase() { 88 | throw new UnsupportedOperationException("This method is not needed for this unit test."); 89 | } 90 | 91 | @Override 92 | public Optional getOverride() { 93 | return Optional.ofNullable(override); 94 | } 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /components/org.wso2.carbon.uiserver/src/main/java/org/wso2/carbon/uiserver/internal/http/RequestDispatcher.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * WSO2 Inc. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | package org.wso2.carbon.uiserver.internal.http; 20 | 21 | import org.slf4j.Logger; 22 | import org.slf4j.LoggerFactory; 23 | import org.wso2.carbon.uiserver.api.App; 24 | import org.wso2.carbon.uiserver.api.exception.UiServerRuntimeException; 25 | import org.wso2.carbon.uiserver.api.http.HttpRequest; 26 | import org.wso2.carbon.uiserver.api.http.HttpResponse; 27 | import org.wso2.carbon.uiserver.internal.io.http.StaticRequestDispatcher; 28 | 29 | /** 30 | * Dispatches HTTP requests. 31 | * 32 | * @since 0.8.0 33 | */ 34 | public class RequestDispatcher { 35 | 36 | private static final Logger LOGGER = LoggerFactory.getLogger(RequestDispatcher.class); 37 | 38 | private final PageRequestDispatcher pageRequestDispatcher; 39 | private final StaticRequestDispatcher staticRequestDispatcher; 40 | 41 | /** 42 | * Creates a new request dispatcher. 43 | * 44 | * @param app web app to be served 45 | */ 46 | public RequestDispatcher(App app) { 47 | this(new PageRequestDispatcher(app), new StaticRequestDispatcher(app)); 48 | } 49 | 50 | RequestDispatcher(PageRequestDispatcher pageRequestDispatcher, StaticRequestDispatcher staticRequestDispatcher) { 51 | this.pageRequestDispatcher = pageRequestDispatcher; 52 | this.staticRequestDispatcher = staticRequestDispatcher; 53 | } 54 | 55 | /** 56 | * Serves the specified HTTP request. 57 | * 58 | * @param request HTTP request to be served 59 | * @return HTTP response 60 | */ 61 | public HttpResponse serve(HttpRequest request) { 62 | if (!request.isValid()) { 63 | return ResponseBuilder.badRequest("URI '" + request.getUri() + "' is invalid.").build(); 64 | } 65 | 66 | try { 67 | if (request.isDefaultFaviconRequest()) { 68 | return staticRequestDispatcher.serveDefaultFavicon(request); 69 | } else if (request.isStaticResourceRequest()) { 70 | return staticRequestDispatcher.serve(request); 71 | } else { 72 | return pageRequestDispatcher.serve(request); 73 | } 74 | } catch (UiServerRuntimeException e) { 75 | LOGGER.error("An error occurred when serving for request '{}'.", request, e); 76 | return ResponseBuilder.serverError("A server occurred while serving for request.").build(); 77 | } catch (Exception e) { 78 | LOGGER.error("An unexpected error occurred when serving for request '{}'.", request, e); 79 | return ResponseBuilder.serverError("An unexpected server occurred while serving for request.").build(); 80 | } 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /components/org.wso2.carbon.uiserver/src/main/java/org/wso2/carbon/uiserver/api/Theme.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * WSO2 Inc. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | package org.wso2.carbon.uiserver.api; 20 | 21 | import org.wso2.carbon.uiserver.api.util.Multilocational; 22 | import org.wso2.carbon.uiserver.api.util.Overridable; 23 | import org.wso2.carbon.uiserver.internal.impl.OverriddenTheme; 24 | 25 | import java.util.Collections; 26 | import java.util.List; 27 | import java.util.Objects; 28 | 29 | /** 30 | * Represents a theme in a web app. 31 | * 32 | * @since 0.8.0 33 | */ 34 | public class Theme implements Multilocational, Overridable { 35 | 36 | private final String name; 37 | private final List paths; 38 | 39 | /** 40 | * Creates a new theme which can be located in the specified path. 41 | * 42 | * @param name name of the theme 43 | * @param path path to the theme 44 | */ 45 | public Theme(String name, String path) { 46 | this(name, Collections.singletonList(path)); 47 | } 48 | 49 | /** 50 | * Creates a new theme. 51 | * 52 | * @param name name of the theme 53 | * @param paths paths to the theme 54 | */ 55 | protected Theme(String name, List paths) { 56 | this.name = name; 57 | this.paths = paths; 58 | } 59 | 60 | /** 61 | * Returns the name of this theme. 62 | * 63 | * @return name of the theme 64 | */ 65 | public String getName() { 66 | return name; 67 | } 68 | 69 | /** 70 | * Returns paths that this theme can be located. 71 | * 72 | * @return paths of the theme 73 | */ 74 | @Override 75 | public List getPaths() { 76 | return paths; 77 | } 78 | 79 | @Override 80 | public Theme override(Theme override) { 81 | if (!canOverrideBy(override)) { 82 | throw new IllegalArgumentException(this + " cannot be overridden by " + override + " ."); 83 | } 84 | return new OverriddenTheme(this, override); 85 | } 86 | 87 | @Override 88 | public Theme getBase() { 89 | return this; 90 | } 91 | 92 | @Override 93 | public boolean equals(Object obj) { 94 | if (this == obj) { 95 | return true; 96 | } 97 | if (!(obj instanceof Theme)) { 98 | return false; 99 | } 100 | Theme other = (Theme) obj; 101 | return Objects.equals(name, other.name) && Objects.equals(paths, other.paths); 102 | } 103 | 104 | @Override 105 | public int hashCode() { 106 | return Objects.hash(name); 107 | } 108 | 109 | @Override 110 | public String toString() { 111 | return "Theme{name='" + name + "', paths=" + paths + "}"; 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ################# 2 | ## Java 3 | ################# 4 | *.class 5 | *.claz 6 | 7 | # Package files 8 | *.jar 9 | *.war 10 | *.ear 11 | 12 | 13 | ################# 14 | ## Eclipse 15 | ################# 16 | *.pydevproject 17 | .metadata 18 | .gradle 19 | bin/ 20 | tmp/ 21 | *.tmp 22 | *.bak 23 | *.swp 24 | *~.nib 25 | local.properties 26 | .settings/ 27 | .loadpath 28 | 29 | # Eclipse Core 30 | .project 31 | 32 | # External tool builders 33 | .externalToolBuilders/ 34 | 35 | # Locally stored "Eclipse launch configurations" 36 | *.launch 37 | 38 | # CDT-specific 39 | .cproject 40 | 41 | # JDT-specific (Eclipse Java Development Tools) 42 | .classpath 43 | 44 | # Java annotation processor (APT) 45 | .factorypath 46 | 47 | # PDT-specific 48 | .buildpath 49 | 50 | # sbteclipse plugin 51 | .target 52 | 53 | # TeXlipse plugin 54 | .texlipse 55 | 56 | 57 | ################# 58 | ## JetBrains IDEs 59 | ## IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio 60 | ################# 61 | *.iml 62 | 63 | ## Directory-based project format: 64 | .idea/ 65 | # if you remove the above rule, at least ignore the following: 66 | 67 | # User-specific stuff: 68 | # .idea/workspace.xml 69 | # .idea/tasks.xml 70 | # .idea/dictionaries 71 | 72 | # Sensitive or high-churn files: 73 | # .idea/dataSources.ids 74 | # .idea/dataSources.xml 75 | # .idea/sqlDataSources.xml 76 | # .idea/dynamic.xml 77 | # .idea/uiDesigner.xml 78 | 79 | # Gradle: 80 | # .idea/gradle.xml 81 | # .idea/libraries 82 | 83 | # Mongo Explorer plugin: 84 | # .idea/mongoSettings.xml 85 | 86 | ## File-based project format: 87 | *.ipr 88 | *.iws 89 | 90 | ## Plugin-specific files: 91 | 92 | # IntelliJ 93 | /out/ 94 | 95 | # mpeltonen/sbt-idea plugin 96 | .idea_modules/ 97 | 98 | # JIRA plugin 99 | atlassian-ide-plugin.xml 100 | 101 | # Crashlytics plugin (for Android Studio and IntelliJ) 102 | com_crashlytics_export_strings.xml 103 | crashlytics.properties 104 | crashlytics-build.properties 105 | 106 | 107 | ################# 108 | ## NetBeans 109 | ################# 110 | nbproject/private/ 111 | build/ 112 | nbbuild/ 113 | dist/ 114 | nbdist/ 115 | nbactions.xml 116 | nb-configuration.xml 117 | .nb-gradle/ 118 | 119 | 120 | ################# 121 | ## Linux 122 | ################# 123 | *~ 124 | 125 | # KDE directory preferences 126 | .directory 127 | 128 | # Linux trash folder which might appear on any partition or disk 129 | .Trash-* 130 | 131 | 132 | ################# 133 | ## OSX 134 | ################# 135 | .DS_Store 136 | .AppleDouble 137 | .LSOverride 138 | 139 | # Icon must end with two \r 140 | Icon 141 | 142 | 143 | # Thumbnails 144 | ._* 145 | 146 | # Files that might appear in the root of a volume 147 | .DocumentRevisions-V100 148 | .fseventsd 149 | .Spotlight-V100 150 | .TemporaryItems 151 | .Trashes 152 | .VolumeIcon.icns 153 | 154 | # Directories potentially created on remote AFP share 155 | .AppleDB 156 | .AppleDesktop 157 | Network Trash Folder 158 | Temporary Items 159 | .apdisk 160 | 161 | ################# 162 | ## Windows 163 | ################# 164 | # Windows image file caches 165 | Thumbs.db 166 | ehthumbs.db 167 | 168 | # Folder config file 169 | Desktop.ini 170 | 171 | # Recycle Bin used on file shares 172 | $RECYCLE.BIN/ 173 | 174 | # Windows Installer files 175 | *.cab 176 | *.msi 177 | *.msm 178 | *.msp 179 | 180 | # Windows shortcuts 181 | *.lnk 182 | 183 | ################# 184 | ## Maven 185 | ################# 186 | target 187 | dependency-reduced-pom.xml 188 | -------------------------------------------------------------------------------- /components/org.wso2.carbon.uiserver/src/test/java/org/wso2/carbon/uiserver/internal/http/PageRequestDispatcherTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * WSO2 Inc. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | package org.wso2.carbon.uiserver.internal.http; 20 | 21 | import org.testng.Assert; 22 | import org.testng.annotations.Test; 23 | import org.wso2.carbon.uiserver.api.App; 24 | import org.wso2.carbon.uiserver.api.Configuration; 25 | import org.wso2.carbon.uiserver.api.exception.PageNotFoundException; 26 | import org.wso2.carbon.uiserver.api.exception.PageRedirectException; 27 | import org.wso2.carbon.uiserver.api.exception.RenderingException; 28 | import org.wso2.carbon.uiserver.api.http.HttpRequest; 29 | import org.wso2.carbon.uiserver.api.http.HttpResponse; 30 | 31 | import static org.mockito.ArgumentMatchers.any; 32 | import static org.mockito.Mockito.mock; 33 | import static org.mockito.Mockito.when; 34 | 35 | /** 36 | * Test cases for {@link PageRequestDispatcher} class. 37 | * 38 | * @since 0.13.4 39 | */ 40 | public class PageRequestDispatcherTest { 41 | 42 | @Test 43 | public void testServe() { 44 | App app = mock(App.class); 45 | when(app.renderPage(any())).thenReturn("

some html

"); 46 | when(app.getConfiguration()).thenReturn(Configuration.DEFAULT_CONFIGURATION); 47 | 48 | HttpResponse response = new PageRequestDispatcher(app).serve(mock(HttpRequest.class)); 49 | Assert.assertEquals(response.getStatus(), HttpResponse.STATUS_OK); 50 | Assert.assertEquals(response.getContent(), "

some html

"); 51 | Assert.assertEquals(response.getContentType(), HttpResponse.CONTENT_TYPE_TEXT_HTML); 52 | } 53 | 54 | @Test 55 | public void testServeWithRenderingException() { 56 | App app = mock(App.class); 57 | when(app.renderPage(any())).thenThrow(RenderingException.class); 58 | 59 | HttpResponse response = new PageRequestDispatcher(app).serve(mock(HttpRequest.class)); 60 | Assert.assertEquals(response.getStatus(), HttpResponse.STATUS_INTERNAL_SERVER_ERROR); 61 | } 62 | 63 | @Test 64 | public void testServeWithPageNotFoundException() { 65 | App app = mock(App.class); 66 | when(app.renderPage(any())).thenThrow(PageNotFoundException.class); 67 | 68 | HttpResponse response = new PageRequestDispatcher(app).serve(mock(HttpRequest.class)); 69 | Assert.assertEquals(response.getStatus(), HttpResponse.STATUS_NOT_FOUND); 70 | } 71 | 72 | @Test 73 | public void testServeWithPageRedirectException() { 74 | App app = mock(App.class); 75 | when(app.renderPage(any())).thenThrow(new PageRedirectException("redirect/url")); 76 | 77 | HttpResponse response = new PageRequestDispatcher(app).serve(mock(HttpRequest.class)); 78 | Assert.assertEquals(response.getStatus(), HttpResponse.STATUS_FOUND); 79 | Assert.assertEquals(response.getHeaders().get(HttpResponse.HEADER_LOCATION), "redirect/url"); 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /components/org.wso2.carbon.uiserver/src/main/java/org/wso2/carbon/uiserver/internal/deployment/parser/ConfigurationYaml.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * WSO2 Inc. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | package org.wso2.carbon.uiserver.internal.deployment.parser; 20 | 21 | import org.wso2.carbon.uiserver.api.Configuration; 22 | 23 | import java.util.Map; 24 | 25 | /** 26 | * Bean class that represents the {@code configuration.yaml} file of a web app. 27 | * 28 | * @since 0.12.1 29 | */ 30 | public class ConfigurationYaml { 31 | 32 | private ResponseHeaders responseHeaders; 33 | 34 | /** 35 | * Returns {@code responseHeaders} config value. 36 | * 37 | * @return {@code responseHeaders} config. 38 | */ 39 | public ResponseHeaders getResponseHeaders() { 40 | return responseHeaders; 41 | } 42 | 43 | /** 44 | * Sets {@code responseHeaders} config value. 45 | * 46 | * @param responseHeaders config value 47 | */ 48 | public void setResponseHeaders(ResponseHeaders responseHeaders) { 49 | this.responseHeaders = responseHeaders; 50 | } 51 | 52 | /** 53 | * Returns this YAML configuration as a {@link Configuration} object. 54 | * 55 | * @return {@link Configuration} object 56 | */ 57 | public Configuration toConfiguration() { 58 | return new Configuration(new Configuration.HttpResponseHeaders(this.responseHeaders.getPages(), 59 | this.responseHeaders.getResources())); 60 | } 61 | 62 | /** 63 | * Bean class for {@code responseHeaders} config. 64 | * 65 | * @since 0.12.1 66 | */ 67 | public static class ResponseHeaders { 68 | 69 | private Map pages; 70 | private Map resources; 71 | 72 | /** 73 | * Returns {@code pages} config value. 74 | * 75 | * @return {@code pages} config value. 76 | */ 77 | public Map getPages() { 78 | return pages; 79 | } 80 | 81 | /** 82 | * Sets {@code pages} config value. 83 | * 84 | * @param pages config value. 85 | */ 86 | public void setPages(Map pages) { 87 | this.pages = pages; 88 | } 89 | 90 | /** 91 | * Returns {@code resources} config value. 92 | * 93 | * @return {@code resources} config value 94 | */ 95 | public Map getResources() { 96 | return resources; 97 | } 98 | 99 | /** 100 | * Sets {@code resources} config value. 101 | * 102 | * @param resources config value 103 | */ 104 | public void setResources(Map resources) { 105 | this.resources = resources; 106 | } 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /components/org.wso2.carbon.uiserver/src/main/java/org/wso2/carbon/uiserver/internal/deployment/msf4j/MicroserviceRegistration.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * WSO2 Inc. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | package org.wso2.carbon.uiserver.internal.deployment.msf4j; 20 | 21 | import org.osgi.framework.ServiceRegistration; 22 | import org.slf4j.Logger; 23 | import org.slf4j.LoggerFactory; 24 | import org.wso2.carbon.uiserver.internal.http.HttpTransport; 25 | import org.wso2.msf4j.Microservice; 26 | 27 | import java.util.Objects; 28 | 29 | /** 30 | * Represents a Microservice registration to the HTTP transport(s). 31 | * 32 | * @since 0.15.0 33 | */ 34 | public class MicroserviceRegistration { 35 | 36 | private static final Logger LOGGER = LoggerFactory.getLogger(MicroserviceRegistration.class); 37 | 38 | private final HttpTransport httpTransport; 39 | private final ServiceRegistration microserviceRegistration; 40 | 41 | /** 42 | * Creates a new Microservice service registration. 43 | * 44 | * @param httpTransport HTTP transport 45 | * @param microserviceRegistration Microservice OSGi service registration 46 | */ 47 | public MicroserviceRegistration(HttpTransport httpTransport, 48 | ServiceRegistration microserviceRegistration) { 49 | this.httpTransport = httpTransport; 50 | this.microserviceRegistration = microserviceRegistration; 51 | } 52 | 53 | /** 54 | * Returns the HTTP transport that this registration occurred. 55 | * 56 | * @return relevant HTTP transport 57 | */ 58 | public HttpTransport getRegisteredHttpTransport() { 59 | return httpTransport; 60 | } 61 | 62 | /** 63 | * Unregister the Microservice that associated with this registration from the transport(s). 64 | * 65 | * @throws IllegalStateException if Microservice is already unregistered 66 | */ 67 | public void unregister() { 68 | microserviceRegistration.unregister(); 69 | LOGGER.debug("Microservice unregistered from HTTP transport {}.", httpTransport); 70 | } 71 | 72 | @Override 73 | public boolean equals(Object obj) { 74 | if (this == obj) { 75 | return true; 76 | } 77 | if (!(obj instanceof MicroserviceRegistration)) { 78 | return false; 79 | } 80 | MicroserviceRegistration other = (MicroserviceRegistration) obj; 81 | return Objects.equals(httpTransport, other.httpTransport) && 82 | Objects.equals(microserviceRegistration, other.microserviceRegistration); 83 | } 84 | 85 | @Override 86 | public int hashCode() { 87 | return Objects.hash(httpTransport, microserviceRegistration); 88 | } 89 | 90 | @Override 91 | public String toString() { 92 | return "MicroserviceRegistration{httpTransport=" + httpTransport + ", microserviceRegistration=" + 93 | microserviceRegistration + "}"; 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /components/org.wso2.carbon.uiserver/src/main/java/org/wso2/carbon/uiserver/internal/deployment/parser/YamlFileParser.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * WSO2 Inc. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | package org.wso2.carbon.uiserver.internal.deployment.parser; 20 | 21 | import org.wso2.carbon.uiserver.internal.exception.ConfigurationException; 22 | import org.wso2.carbon.uiserver.internal.exception.FileOperationException; 23 | import org.wso2.carbon.uiserver.internal.reference.FileReference; 24 | import org.yaml.snakeyaml.Yaml; 25 | import org.yaml.snakeyaml.constructor.Constructor; 26 | 27 | /** 28 | * Parser for YAML configuration files in web apps. 29 | * 30 | * @since 0.12.1 31 | */ 32 | public class YamlFileParser { 33 | 34 | /** 35 | * Parses the given YAML configuration file and de-serialize the content into given bean type. 36 | * 37 | * @param yamlFile reference to the YAML configuration file 38 | * @param type class of the bean to be used when de-serializing 39 | * @param type of the bean class to be used when de-serializing 40 | * @return returns the populated bean instance 41 | * @throws ConfigurationException if cannot read or parse the content of the specified YAML file 42 | */ 43 | public static T parse(FileReference yamlFile, Class type) throws ConfigurationException { 44 | T loadedBean; 45 | try { 46 | loadedBean = new Yaml(new ClassLoaderConstructor(type)).loadAs(yamlFile.getContent(), type); 47 | } catch (FileOperationException e) { 48 | throw new ConfigurationException( 49 | "Cannot read the YAML configuration file '" + yamlFile.getFilePath() + "'.", e); 50 | } catch (Exception e) { 51 | throw new ConfigurationException( 52 | "Cannot parse the YAML configuration file '" + yamlFile.getFilePath() + "'.", e); 53 | } 54 | if (loadedBean == null) { 55 | // Either configuration file is empty or has only comments. 56 | throw new ConfigurationException( 57 | "Cannot load the YAML configuration file '" + yamlFile.getFilePath() + "' as it is empty."); 58 | } 59 | return loadedBean; 60 | } 61 | 62 | /** 63 | * OSGi friendly YAML constructor that loads classes through a given class object. 64 | * 65 | * @since 0.12.1 66 | */ 67 | private static class ClassLoaderConstructor extends Constructor { 68 | 69 | private final ClassLoader classLoader; 70 | 71 | /** 72 | * Creates a new constructor. 73 | * 74 | * @param aClass class that uses for class loading 75 | */ 76 | public ClassLoaderConstructor(Class aClass) { 77 | super(Object.class); 78 | this.classLoader = aClass.getClassLoader(); 79 | } 80 | 81 | @Override 82 | protected Class getClassForName(String name) throws ClassNotFoundException { 83 | return Class.forName(name, true, classLoader); 84 | } 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /components/org.wso2.carbon.uiserver/src/test/java/org/wso2/carbon/uiserver/api/I18nResourceTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * WSO2 Inc. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | package org.wso2.carbon.uiserver.api; 20 | 21 | import com.google.common.collect.ImmutableMap; 22 | import com.google.common.collect.ImmutableSet; 23 | import org.testng.Assert; 24 | import org.testng.annotations.DataProvider; 25 | import org.testng.annotations.Test; 26 | 27 | import java.util.Locale; 28 | import java.util.Set; 29 | 30 | import static java.util.Collections.emptyMap; 31 | 32 | /** 33 | * Test cases for {@link I18nResource} class. 34 | * 35 | * @since 0.12.0 36 | */ 37 | public class I18nResourceTest { 38 | 39 | @Test 40 | public void testGetMessage() { 41 | I18nResource i18nResource = new I18nResource(Locale.US, ImmutableMap.of("welcome", "Hello!", 42 | "welcome-name", "Hello {0}!")); 43 | 44 | Assert.assertEquals(i18nResource.getMessage("bye", null, "Bye!"), "Bye!"); 45 | Assert.assertEquals(i18nResource.getMessage("welcome", null, null), "Hello!"); 46 | Assert.assertEquals(i18nResource.getMessage("welcome-name", new Object[]{"Alice"}, null), "Hello Alice!"); 47 | } 48 | 49 | @Test 50 | public void testGetMatchingLocale() { 51 | Set availableLocales = ImmutableSet.of(Locale.FRENCH, Locale.US, Locale.CANADA); 52 | 53 | Assert.assertEquals(I18nResource.getMatchingLocale(null, availableLocales), null); 54 | Assert.assertEquals(I18nResource.getMatchingLocale("", availableLocales), null); 55 | Assert.assertEquals(I18nResource.getMatchingLocale("foo", availableLocales), null); 56 | 57 | Assert.assertEquals(I18nResource.getMatchingLocale("en", availableLocales), Locale.US); 58 | Assert.assertEquals(I18nResource.getMatchingLocale("en-US", availableLocales), Locale.US); 59 | Assert.assertEquals(I18nResource.getMatchingLocale("fr, en;q=0.9, en-GB;q=0.8, en-US;q=0.7", 60 | availableLocales), Locale.FRENCH); 61 | Assert.assertEquals(I18nResource.getMatchingLocale("si, en;q=0.9, en-GB;q=0.8, en-US;q=0.7, en-CA;q=0.5", 62 | availableLocales), Locale.US); 63 | } 64 | 65 | @DataProvider 66 | public Object[][] equalI18nResources() { 67 | I18nResource i18nResource = new I18nResource(Locale.US, null); 68 | return new Object[][]{ 69 | {i18nResource, i18nResource}, 70 | {new I18nResource(Locale.US, null), new I18nResource(Locale.US, null)}, 71 | {new I18nResource(Locale.US, emptyMap()), new I18nResource(Locale.US, emptyMap())}, 72 | {new I18nResource(Locale.US, ImmutableMap.of("hello", "Welcome!")), 73 | new I18nResource(Locale.US, ImmutableMap.of("hello", "Welcome!"))} 74 | }; 75 | } 76 | 77 | @Test(dataProvider = "equalI18nResources") 78 | public void testEqual(I18nResource i18nResource1, I18nResource i18nResource2) { 79 | Assert.assertEquals(i18nResource1, i18nResource2); 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /components/org.wso2.carbon.uiserver/src/main/java/org/wso2/carbon/uiserver/internal/deployment/AppRegistry.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * WSO2 Inc. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | package org.wso2.carbon.uiserver.internal.deployment; 20 | 21 | import org.wso2.carbon.uiserver.api.App; 22 | 23 | import java.util.Collection; 24 | import java.util.HashMap; 25 | import java.util.Map; 26 | import java.util.Optional; 27 | import java.util.function.Predicate; 28 | 29 | /** 30 | * Registry that holds created web apps. 31 | * 32 | * @since 0.12.0 33 | */ 34 | public class AppRegistry { 35 | 36 | private final Map apps = new HashMap<>(); 37 | 38 | /** 39 | * Adds an app to this registry. 40 | * 41 | * @param app app to be added 42 | * @return a key that can be used later to retrieve the added app object 43 | * @see #get(String) 44 | */ 45 | public String add(App app) { 46 | String key = keyFor(app); 47 | apps.put(key, app); 48 | return key; 49 | } 50 | 51 | /** 52 | * Returns the app in this registry associated for the supplied key. 53 | * 54 | * @param key key whose associated app to be returned 55 | * @return associated app, or {@link Optional#empty() empty} if there is no app for the key 56 | * @see #add(App) 57 | */ 58 | public Optional get(String key) { 59 | return Optional.ofNullable(apps.get(key)); 60 | } 61 | 62 | /** 63 | * Returns all apps added to this registry. 64 | * 65 | * @return all apps added to the registry 66 | */ 67 | public Collection getAll() { 68 | return apps.values(); 69 | } 70 | 71 | /** 72 | * Removes & returns the app in this registry associated for the supplied key. 73 | * 74 | * @param key key whose associated app to be removed & returned 75 | * @return associated app, or {@link Optional#empty() empty} if there is no app for the key 76 | * @see #remove(App) 77 | */ 78 | public Optional remove(String key) { 79 | return Optional.ofNullable(apps.remove(key)); 80 | } 81 | 82 | /** 83 | * Removes the specified app from this register. Nothing changes if the specified app doesn't exist in the 84 | * registry. 85 | * 86 | * @return {@code true} if the app was found & removed, otherwise {@code false} 87 | */ 88 | public boolean remove(App app) { 89 | return apps.remove(keyFor(app)) != null; 90 | } 91 | 92 | /** 93 | * Returns the very first app in this registry that satisfies the specified perdicate. 94 | * 95 | * @param predicate a non-interfering, stateless predicate to apply to app to determine if it should be chosen 96 | * @return very first app that satisfies the predicate, if non found then {@link Optional#empty()} 97 | */ 98 | public Optional find(Predicate predicate) { 99 | return apps.values().stream().filter(predicate).findFirst(); 100 | } 101 | 102 | /** 103 | * Removes all apps in this registry. 104 | */ 105 | public void clear() { 106 | apps.clear(); 107 | } 108 | 109 | private static String keyFor(App app) { 110 | return app.getName() + app.getPaths(); 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /components/org.wso2.carbon.uiserver/src/main/java/org/wso2/carbon/uiserver/api/ServerConfiguration.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * WSO2 Inc. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | package org.wso2.carbon.uiserver.api; 20 | 21 | import org.wso2.carbon.config.annotation.Configuration; 22 | import org.wso2.carbon.config.annotation.Element; 23 | 24 | import java.util.Collections; 25 | import java.util.Map; 26 | import java.util.Optional; 27 | 28 | /** 29 | * Bean class for server configurations. 30 | * 31 | * @since 0.12.6 32 | */ 33 | @Configuration(namespace = "wso2.carbon-ui-server", description = "Configurations for Carbon UI Server") 34 | public class ServerConfiguration { 35 | 36 | @Element(description = "Configurations for web apps.\n" + 37 | "Here key is the name of the web app abd value is configurations for that web app.") 38 | private Map apps = Collections.emptyMap(); 39 | 40 | /** 41 | * Returns configurations for the specified app. 42 | * 43 | * @param appName name of the app 44 | * @return server configurations of the app 45 | */ 46 | public Optional getConfigurationForApp(String appName) { 47 | return Optional.ofNullable(apps.get(appName)); 48 | } 49 | 50 | /** 51 | * Bean class for configurations of a web app. 52 | * 53 | * @since 0.18.0 54 | */ 55 | public static class AppConfiguration { 56 | 57 | @Element(description = "Context path of this web app.\n" + 58 | "This overrides the default context path (which is '/'+) of the app. " + 59 | "Context path should start with a '/' (e.g. '/foo').") 60 | private String contextPath; 61 | 62 | @Element(description = "ID of the HTTP listener configuration that this web app should be deployed.\n" + 63 | "'listenerConfigurations' can be found under 'wso2.transport.http' namespace. " + 64 | "If absent, this web app will be deployed to all available HTTPS transports.") 65 | private String transportId; 66 | 67 | /** 68 | * Returns the context path in this app configuration. 69 | * 70 | * @return the context path 71 | * @throws IllegalArgumentException if configured context path is invalid 72 | */ 73 | public Optional getContextPath() throws IllegalArgumentException { 74 | if ((contextPath != null) && (contextPath.charAt(0) != '/')) { 75 | throw new IllegalArgumentException( 76 | "Configured context path '" + contextPath + "' is invalid as it does not start with a '/'."); 77 | } 78 | return Optional.ofNullable(contextPath); 79 | } 80 | 81 | /** 82 | * Returns the transport ID in this app configuration. 83 | * 84 | * @return the transport ID 85 | * @throws IllegalArgumentException if configured transport ID is invalid 86 | */ 87 | public Optional getTransportId() throws IllegalArgumentException { 88 | if ((transportId != null) && transportId.isEmpty()) { 89 | throw new IllegalArgumentException("Configured transport ID is invalid as it cannot be a empty."); 90 | } 91 | return Optional.ofNullable(transportId); 92 | } 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /components/org.wso2.carbon.uiserver/src/main/java/org/wso2/carbon/uiserver/api/Extension.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * WSO2 Inc. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | package org.wso2.carbon.uiserver.api; 20 | 21 | import org.wso2.carbon.uiserver.api.util.Multilocational; 22 | import org.wso2.carbon.uiserver.api.util.Overridable; 23 | import org.wso2.carbon.uiserver.internal.impl.OverriddenExtension; 24 | 25 | import java.util.Collections; 26 | import java.util.List; 27 | import java.util.Objects; 28 | 29 | /** 30 | * Represents an extension of a web app. 31 | * 32 | * @since 0.8.0 33 | */ 34 | public class Extension implements Multilocational, Overridable { 35 | 36 | private final String name; 37 | private final String type; 38 | private final List paths; 39 | 40 | /** 41 | * Creates a new extension which can be located in the specified path. 42 | * 43 | * @param name name of the extension 44 | * @param type type of the extension 45 | * @param path path to the extension 46 | */ 47 | public Extension(String name, String type, String path) { 48 | this(name, type, Collections.singletonList(path)); 49 | } 50 | 51 | /** 52 | * Creates a new extension. 53 | * 54 | * @param name name of the extension 55 | * @param type type of the extension 56 | * @param paths paths to the extension 57 | */ 58 | protected Extension(String name, String type, List paths) { 59 | this.name = name; 60 | this.type = type; 61 | this.paths = paths; 62 | } 63 | 64 | /** 65 | * Returns the name of this extension. 66 | * 67 | * @return name of this extension 68 | */ 69 | public String getName() { 70 | return name; 71 | } 72 | 73 | /** 74 | * Returns the type of this extension. 75 | * 76 | * @return type of the extension 77 | */ 78 | public String getType() { 79 | return type; 80 | } 81 | 82 | /** 83 | * Returns paths that this extension can be located. 84 | * 85 | * @return paths of the theme 86 | */ 87 | @Override 88 | public List getPaths() { 89 | return paths; 90 | } 91 | 92 | @Override 93 | public Extension override(Extension override) { 94 | if (!canOverrideBy(override)) { 95 | throw new IllegalArgumentException(this + " cannot be overridden by " + override + " ."); 96 | } 97 | return new OverriddenExtension(this, override); 98 | } 99 | 100 | @Override 101 | public Extension getBase() { 102 | return this; 103 | } 104 | 105 | @Override 106 | public boolean equals(Object obj) { 107 | if (this == obj) { 108 | return true; 109 | } 110 | if (!(obj instanceof Extension)) { 111 | return false; 112 | } 113 | Extension other = (Extension) obj; 114 | return Objects.equals(name, other.name) && Objects.equals(type, other.type) && 115 | Objects.equals(paths, other.paths); 116 | } 117 | 118 | @Override 119 | public int hashCode() { 120 | return Objects.hash(name, type); 121 | } 122 | 123 | @Override 124 | public String toString() { 125 | return "Extension{name='" + name + "', type='" + type + "', paths=" + paths + "}"; 126 | } 127 | } 128 | -------------------------------------------------------------------------------- /components/org.wso2.carbon.uiserver/src/test/java/org/wso2/carbon/uiserver/internal/http/HttpTransportTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * WSO2 Inc. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | package org.wso2.carbon.uiserver.internal.http; 20 | 21 | import org.testng.Assert; 22 | import org.testng.annotations.DataProvider; 23 | import org.testng.annotations.Test; 24 | import org.wso2.carbon.uiserver.internal.http.util.IpAddressUtils; 25 | 26 | /** 27 | * Test cases for {@link HttpTransport} class. 28 | * 29 | * @since 0.15.0 30 | */ 31 | public class HttpTransportTest { 32 | 33 | @Test 34 | public void test() { 35 | final String listenerInterfaceId = "foo"; 36 | final String listenerConfigurationId = "bar"; 37 | final String scheme = "http"; 38 | final String host = "localhost"; 39 | final int port = 9292; 40 | 41 | HttpTransport httpTransport = new HttpTransport(listenerInterfaceId, listenerConfigurationId, scheme, host, 42 | port); 43 | Assert.assertEquals(httpTransport.getListenerInterfaceId(), listenerInterfaceId); 44 | Assert.assertEquals(httpTransport.getListenerConfigurationId(), listenerConfigurationId); 45 | Assert.assertEquals(httpTransport.getScheme(), scheme); 46 | Assert.assertEquals(httpTransport.getHost(), host); 47 | Assert.assertEquals(httpTransport.getPort(), port); 48 | } 49 | 50 | @Test 51 | public void testIsSecured() { 52 | Assert.assertFalse(createHttpTransport("foo", "bar", "http").isSecured()); 53 | Assert.assertTrue(createHttpTransport("bar", "foo", "HTTPS").isSecured()); 54 | } 55 | 56 | @DataProvider 57 | public Object[][] httpTransports() { 58 | return new Object[][]{ 59 | {createHttpTransport("localhost"), IpAddressUtils.getLocalIpAddress().orElse("localhost")}, 60 | {createHttpTransport("127.0.0.1"), IpAddressUtils.getLocalIpAddress().orElse("127.0.01")}, 61 | {createHttpTransport("0.0.0.0"), IpAddressUtils.getLocalIpAddress().orElse("0.0.0.0")}, 62 | {createHttpTransport("::1"), IpAddressUtils.getLocalIpAddress().orElse("::1")}, 63 | {createHttpTransport("192.168.1.1"), "192.168.1.1"} 64 | }; 65 | } 66 | 67 | @Test(dataProvider = "httpTransports") 68 | public void testGetUrlFor(HttpTransport httpTransport, String hostname) { 69 | Assert.assertEquals(httpTransport.getUrlFor("/test"), "http://" + hostname + ":9090/test"); 70 | } 71 | 72 | @Test 73 | public void testEquals() { 74 | Assert.assertNotEquals(null, createHttpTransport("foo", "bar", "http")); 75 | Assert.assertNotEquals(new Object(), createHttpTransport("foo", "bar", "http")); 76 | Assert.assertNotEquals(createHttpTransport("foo", "bar", "https"), createHttpTransport("foo2", "bar", "http")); 77 | Assert.assertNotEquals(createHttpTransport("foo", "bar", "https"), createHttpTransport("foo2", "bar2", "http")); 78 | 79 | Assert.assertEquals(createHttpTransport("foo", "bar", "https"), createHttpTransport("foo", "bar", "http")); 80 | } 81 | 82 | private static HttpTransport createHttpTransport(String listenerInterfaceId, String listenerConfigurationId, 83 | String scheme) { 84 | return new HttpTransport(listenerInterfaceId, listenerConfigurationId, scheme, "localhost", 9292); 85 | } 86 | 87 | private static HttpTransport createHttpTransport(String host) { 88 | return new HttpTransport("foo", "bar", "http", host, 9090); 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /components/org.wso2.carbon.uiserver/src/main/java/org/wso2/carbon/uiserver/internal/reference/AppReference.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * WSO2 Inc. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | package org.wso2.carbon.uiserver.internal.reference; 20 | 21 | import org.wso2.carbon.uiserver.internal.exception.FileOperationException; 22 | 23 | import java.util.Optional; 24 | import java.util.Set; 25 | 26 | /** 27 | * A reference to a web app artifact. 28 | * 29 | * @since 0.8.0 30 | */ 31 | public interface AppReference { 32 | 33 | /** 34 | * Name of the directory that contains pages. 35 | */ 36 | String DIR_NAME_PAGES = "pages"; 37 | 38 | /** 39 | * Name of the directory that contains themes. 40 | */ 41 | String DIR_NAME_THEMES = "themes"; 42 | 43 | /** 44 | * Name of the directory that contains extensions. 45 | */ 46 | String DIR_NAME_EXTENSIONS = "extensions"; 47 | 48 | /** 49 | * Name of the directory that contains i18n resources. 50 | */ 51 | String DIR_NAME_I18N = "i18n"; 52 | 53 | /** 54 | * Name of the directory that contains public static resources. 55 | */ 56 | String DIR_NAME_PUBLIC_RESOURCES = "public"; 57 | 58 | /** 59 | * Name of the file that has the app configurations. 60 | */ 61 | String FILE_NAME_CONFIGURATION = "configuration.yaml"; 62 | 63 | /** 64 | * Returns the name of the app represented by this reference. 65 | * 66 | * @return name of the app 67 | * @throws FileOperationException if cannot read app name 68 | */ 69 | String getName() throws FileOperationException; 70 | 71 | /** 72 | * Returns references for the pages that belongs to the app represented by this reference. 73 | * 74 | * @return references for pages of this app 75 | * @throws FileOperationException if cannot find or read pages 76 | */ 77 | Set getPageReferences() throws FileOperationException; 78 | 79 | /** 80 | * Returns references for the extensions that belongs to the app represented by this reference. 81 | * 82 | * @return references for extensions of this app 83 | * @throws FileOperationException if cannot find or read extensions 84 | */ 85 | Set getExtensionReferences() throws FileOperationException; 86 | 87 | /** 88 | * Returns references for the themes that belongs to the app represented by this reference. 89 | * 90 | * @return references for themes of this app 91 | * @throws FileOperationException if cannot find or read themes 92 | */ 93 | Set getThemeReferences() throws FileOperationException; 94 | 95 | /** 96 | * Returns references for the i18n resources that belongs to the app represented by this reference. 97 | * 98 | * @return references for i18n resources of this app 99 | * @throws FileOperationException if cannot find or read i18n resources 100 | */ 101 | Set getI18nResourceReferences() throws FileOperationException; 102 | 103 | /** 104 | * Returns a reference to the configuration file of the app represented by this reference. 105 | * 106 | * @return if exists a reference to the configuration file of this app, otherwise {@link Optional#empty() empty}. 107 | */ 108 | Optional getConfiguration() throws FileOperationException; 109 | 110 | /** 111 | * Returns the absolute path to the app represented by this reference. 112 | * 113 | * @return absolute path to the app 114 | * @throws FileOperationException if cannot obtain the path 115 | */ 116 | String getPath() throws FileOperationException; 117 | } 118 | -------------------------------------------------------------------------------- /components/org.wso2.carbon.uiserver/src/main/java/org/wso2/carbon/uiserver/internal/impl/OverriddenApp.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * WSO2 Inc. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | package org.wso2.carbon.uiserver.internal.impl; 20 | 21 | import com.google.common.collect.ImmutableList; 22 | import com.google.common.collect.ImmutableSet; 23 | import org.wso2.carbon.uiserver.api.App; 24 | import org.wso2.carbon.uiserver.api.Configuration; 25 | import org.wso2.carbon.uiserver.api.Extension; 26 | import org.wso2.carbon.uiserver.api.I18nResource; 27 | import org.wso2.carbon.uiserver.api.Page; 28 | import org.wso2.carbon.uiserver.api.Theme; 29 | 30 | import java.util.HashSet; 31 | import java.util.List; 32 | import java.util.Map; 33 | import java.util.Objects; 34 | import java.util.Optional; 35 | import java.util.Set; 36 | import java.util.SortedSet; 37 | import java.util.TreeSet; 38 | import java.util.function.Function; 39 | import java.util.stream.Collectors; 40 | 41 | /** 42 | * Represents an overridden web app. 43 | * 44 | * @since 0.12.0 45 | */ 46 | public class OverriddenApp extends App { 47 | 48 | private final App base; 49 | private final App override; 50 | 51 | /** 52 | * Creates a new overridden app. 53 | * 54 | * @param base base app 55 | * @param override app that overrides the {@code base} app 56 | */ 57 | public OverriddenApp(App base, App override) { 58 | super(override.getName(), override.getContextPath(), 59 | getPagesFrom(base, override), getExtensionsFrom(base, override), getThemesFrom(base, override), 60 | getI18nResourcesFrom(base, override), getConfigurationFrom(base, override), getPathsFrom(base, override)); 61 | this.base = base; 62 | this.override = override; 63 | } 64 | 65 | @Override 66 | public App getBase() { 67 | return base; 68 | } 69 | 70 | @Override 71 | public Optional getOverride() { 72 | return Optional.of(override); 73 | } 74 | 75 | private static SortedSet getPagesFrom(App base, App override) { 76 | SortedSet pages = new TreeSet<>(getPagesOf(override)); 77 | pages.addAll(getPagesOf(base)); 78 | return pages; 79 | } 80 | 81 | private static Set getExtensionsFrom(App base, App override) { 82 | Function getKey = extension -> (extension.getType() + extension.getName()); 83 | Map extensions = getExtensionsOf(base).stream() 84 | .collect(Collectors.toMap(getKey, Function.identity())); 85 | for (Extension extension : getExtensionsOf(override)) { 86 | extensions.merge(getKey.apply(extension), extension, Extension::override); 87 | } 88 | return new HashSet<>(extensions.values()); 89 | } 90 | 91 | private static Set getThemesFrom(App base, App override) { 92 | Map themes = getThemesOf(base).stream() 93 | .collect(Collectors.toMap(Theme::getName, Function.identity())); 94 | for (Theme theme : getThemesOf(override)) { 95 | themes.merge(theme.getName(), theme, Theme::override); 96 | } 97 | return new HashSet<>(themes.values()); 98 | } 99 | 100 | private static Set getI18nResourcesFrom(App base, App override) { 101 | return ImmutableSet.builder() 102 | .addAll(getI18nResourcesOf(override)) 103 | .addAll(getI18nResourcesOf(base)) 104 | .build(); 105 | } 106 | 107 | private static Configuration getConfigurationFrom(App base, App override) { 108 | return Objects.equals(override.getConfiguration(), Configuration.DEFAULT_CONFIGURATION) ? 109 | base.getConfiguration() : 110 | override.getConfiguration(); 111 | } 112 | 113 | private static List getPathsFrom(App base, App override) { 114 | return ImmutableList.builder() 115 | .addAll(override.getPaths()) 116 | .addAll(base.getPaths()) 117 | .build(); 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /components/org.wso2.carbon.uiserver/src/main/java/org/wso2/carbon/uiserver/api/Configuration.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * WSO2 Inc. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | package org.wso2.carbon.uiserver.api; 20 | 21 | import java.util.Collections; 22 | import java.util.HashMap; 23 | import java.util.Map; 24 | 25 | import static org.wso2.carbon.uiserver.api.http.HttpResponse.HEADER_CACHE_CONTROL; 26 | import static org.wso2.carbon.uiserver.api.http.HttpResponse.HEADER_EXPIRES; 27 | import static org.wso2.carbon.uiserver.api.http.HttpResponse.HEADER_PRAGMA; 28 | import static org.wso2.carbon.uiserver.api.http.HttpResponse.HEADER_X_CONTENT_TYPE_OPTIONS; 29 | import static org.wso2.carbon.uiserver.api.http.HttpResponse.HEADER_X_FRAME_OPTIONS; 30 | import static org.wso2.carbon.uiserver.api.http.HttpResponse.HEADER_X_XSS_PROTECTION; 31 | 32 | import static java.util.Collections.emptyMap; 33 | 34 | /** 35 | * Represents a configurations for a web App. 36 | * 37 | * @since 0.8.0 38 | */ 39 | public class Configuration { 40 | 41 | /** 42 | * Default configuration for an app. 43 | */ 44 | public static final Configuration DEFAULT_CONFIGURATION; 45 | 46 | private final HttpResponseHeaders responseHeaders; 47 | 48 | static { 49 | DEFAULT_CONFIGURATION = new Configuration(new HttpResponseHeaders(emptyMap(), emptyMap())); 50 | } 51 | 52 | /** 53 | * Creates a new configuration. 54 | * 55 | * @param responseHeaders HTTP response headers configuration 56 | */ 57 | public Configuration(HttpResponseHeaders responseHeaders) { 58 | this.responseHeaders = responseHeaders; 59 | } 60 | 61 | /** 62 | * Returns HTTP response headers configuration in this app configuration. 63 | * 64 | * @return HTTP response headers configuration 65 | */ 66 | public HttpResponseHeaders getResponseHeaders() { 67 | return responseHeaders; 68 | } 69 | 70 | /** 71 | * Represents a HTTP response headers configuration. 72 | * 73 | * @since 0.8.0 74 | */ 75 | public static class HttpResponseHeaders { 76 | 77 | private final Map pages; 78 | private final Map staticResources; 79 | 80 | /** 81 | * Creates a new configuration. 82 | * 83 | * @param pages HTTP response headers for pages 84 | * @param staticResources HTTP response headers for static resources 85 | */ 86 | public HttpResponseHeaders(Map pages, Map staticResources) { 87 | Map pagesHttpHeaders = new HashMap<>(); 88 | pagesHttpHeaders.put(HEADER_X_CONTENT_TYPE_OPTIONS, "nosniff"); 89 | pagesHttpHeaders.put(HEADER_X_XSS_PROTECTION, "1; mode=block"); 90 | pagesHttpHeaders.put(HEADER_CACHE_CONTROL, "no-store, no-cache, must-revalidate, private"); 91 | pagesHttpHeaders.put(HEADER_EXPIRES, "0"); 92 | pagesHttpHeaders.put(HEADER_PRAGMA, "no-cache"); 93 | pagesHttpHeaders.put(HEADER_X_FRAME_OPTIONS, "DENY"); 94 | pagesHttpHeaders.putAll(pages); 95 | this.pages = Collections.unmodifiableMap(pagesHttpHeaders); 96 | 97 | Map staticResourcesHttpHeaders = new HashMap<>(); 98 | staticResourcesHttpHeaders.put(HEADER_CACHE_CONTROL, "public,max-age=2592000"); 99 | staticResourcesHttpHeaders.putAll(staticResources); 100 | this.staticResources = Collections.unmodifiableMap(staticResourcesHttpHeaders); 101 | } 102 | 103 | /** 104 | * Returns HTTP response headers for pages. 105 | * 106 | * @return HTTP response headers for pages 107 | */ 108 | public Map forPages() { 109 | return pages; 110 | } 111 | 112 | /** 113 | * Returns HTTP response headers for static resources. 114 | * 115 | * @return HTTP response headers for static resources 116 | */ 117 | public Map forStaticResources() { 118 | return staticResources; 119 | } 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /components/org.wso2.carbon.uiserver/src/main/java/org/wso2/carbon/uiserver/api/I18nResource.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * WSO2 Inc. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | package org.wso2.carbon.uiserver.api; 20 | 21 | import java.text.MessageFormat; 22 | import java.util.List; 23 | import java.util.Locale; 24 | import java.util.Map; 25 | import java.util.Objects; 26 | import java.util.Set; 27 | 28 | /** 29 | * Represents an i18n resource in a web app. 30 | * 31 | * @since 0.12.0 32 | */ 33 | public class I18nResource { 34 | 35 | private final Locale locale; 36 | private final Map messages; 37 | 38 | /** 39 | * Creates a new i18n resource. 40 | * 41 | * @param locale locale of the i18n resource 42 | * @param messages messages of the i18n resource 43 | */ 44 | public I18nResource(Locale locale, Map messages) { 45 | this.locale = locale; 46 | this.messages = messages; 47 | } 48 | 49 | /** 50 | * Returns the locale of this i18n resource. 51 | * 52 | * @return locale of the i18n resource 53 | */ 54 | public Locale getLocale() { 55 | return locale; 56 | } 57 | 58 | /** 59 | * Returns the formatted message of the given message key. If no message is found for the given message key, then 60 | * the specified default message will be returned. 61 | * 62 | * @param messageKey key of the message 63 | * @param messageParams parameters to format the message, or {@code null} if there are no parameters 64 | * @param defaultMessage default message, which will be returned if no message is found for the given message key in 65 | * the given locale 66 | * @return the formatted message or the default message if no message was found for the given message key in the 67 | * given locale 68 | */ 69 | public String getMessage(String messageKey, Object[] messageParams, String defaultMessage) { 70 | String message = messages.get(messageKey); 71 | if (message == null) { 72 | return defaultMessage; 73 | } 74 | 75 | return ((messageParams == null) || (messageParams.length == 0)) ? message : 76 | new MessageFormat(message, locale).format(messageParams); 77 | } 78 | 79 | @Override 80 | public boolean equals(Object obj) { 81 | if (this == obj) { 82 | return true; 83 | } 84 | if (!(obj instanceof I18nResource)) { 85 | return false; 86 | } 87 | I18nResource other = (I18nResource) obj; 88 | return Objects.equals(locale, other.locale) && Objects.equals(messages, other.messages); 89 | } 90 | 91 | @Override 92 | public int hashCode() { 93 | return Objects.hash(locale); 94 | } 95 | 96 | @Override 97 | public String toString() { 98 | return "I18nResource{locale=" + locale + "}"; 99 | } 100 | 101 | /** 102 | * Returns the best matching locale chosen from a set of available locales for the given language ranges. 103 | * 104 | * @param languageRanges a list of comma-separated language ranges or a list of language ranges in the form of the 105 | * "Accept-Language" header defined in 106 | * RFC 107 | * 2616 108 | * @param availableLocales available locales to choose from 109 | * @return Locale the best matching locale, or {@code null} if nothing matches 110 | */ 111 | public static Locale getMatchingLocale(String languageRanges, Set availableLocales) { 112 | if ((languageRanges == null) || languageRanges.isEmpty()) { 113 | return null; 114 | } 115 | 116 | List matchingLocales; 117 | try { 118 | matchingLocales = Locale.filter(Locale.LanguageRange.parse(languageRanges), availableLocales); 119 | } catch (IllegalArgumentException e) { 120 | // languageRanges is ill formed 121 | return null; 122 | } 123 | return matchingLocales.isEmpty() ? null : matchingLocales.get(0); 124 | } 125 | } 126 | -------------------------------------------------------------------------------- /components/org.wso2.carbon.uiserver/src/test/java/org/wso2/carbon/uiserver/internal/deployment/AppRegistryTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * WSO2 Inc. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | package org.wso2.carbon.uiserver.internal.deployment; 20 | 21 | import org.testng.Assert; 22 | import org.testng.annotations.Test; 23 | import org.wso2.carbon.uiserver.api.App; 24 | 25 | import java.util.Collections; 26 | 27 | /** 28 | * Test cases for {@link AppRegistry} class. 29 | * 30 | * @since 0.12.0 31 | */ 32 | public class AppRegistryTest { 33 | 34 | @Test 35 | public void testAddGet() { 36 | AppRegistry appRegistry = new AppRegistry(); 37 | App a1 = createApp("a1", "p1"); 38 | String k1 = appRegistry.add(a1); 39 | App a2 = createApp("a2", "p2"); 40 | appRegistry.add(a2); 41 | 42 | Assert.assertTrue(appRegistry.get(k1).isPresent(), "App " + a1 + " should be in the app registry."); 43 | Assert.assertEquals(appRegistry.get(k1).orElse(null), a1); 44 | Assert.assertFalse(appRegistry.get("some-key").isPresent(), 45 | "There shouldn't be an app for key 'some-key' in the app registry."); 46 | } 47 | 48 | @Test 49 | public void testGetAll() { 50 | AppRegistry appRegistry = new AppRegistry(); 51 | App a1 = createApp("a1", "p1"); 52 | appRegistry.add(a1); 53 | App a2 = createApp("a2", "p2"); 54 | appRegistry.add(a2); 55 | 56 | Assert.assertEquals(appRegistry.getAll().size(), 2); 57 | Assert.assertTrue(appRegistry.getAll().contains(a1), "App " + a1 + " should be in the app registry."); 58 | Assert.assertTrue(appRegistry.getAll().contains(a2), "App " + a2 + " should be in the app registry."); 59 | } 60 | 61 | @Test 62 | public void testRemove() { 63 | AppRegistry appRegistry = new AppRegistry(); 64 | App a1 = createApp("a1", "p1"); 65 | String k1 = appRegistry.add(a1); 66 | App a2 = createApp("a2", "p2"); 67 | appRegistry.add(a2); 68 | App a3 = createApp("a3", "p3"); 69 | 70 | Assert.assertTrue(appRegistry.remove(k1).isPresent(), "App " + a1 + " should be in the app registry."); 71 | Assert.assertFalse(appRegistry.remove("some-key").isPresent(), 72 | "There shouldn't be an app for key 'some-key' in the app registry."); 73 | Assert.assertTrue(appRegistry.remove(a2), "App " + a2 + " should be in the app registry."); 74 | Assert.assertFalse(appRegistry.remove(a3), "App " + a3 + " shouldn't be in the app registry."); 75 | } 76 | 77 | @Test 78 | public void testFind() { 79 | AppRegistry appRegistry = new AppRegistry(); 80 | App a1 = createApp("a1", "p1"); 81 | appRegistry.add(a1); 82 | App a2 = createApp("a2", "p2"); 83 | appRegistry.add(a2); 84 | 85 | Assert.assertTrue(appRegistry.find(app -> a1 == app).isPresent(), 86 | "App " + a1 + " should be in the app registry."); 87 | Assert.assertFalse(appRegistry.find(app -> app.getName().equals("foo")).isPresent()); 88 | } 89 | 90 | @Test 91 | public void testClear() { 92 | AppRegistry appRegistry = new AppRegistry(); 93 | App a1 = createApp("a1", "p1"); 94 | String k1 = appRegistry.add(a1); 95 | App a2 = createApp("a2", "p2"); 96 | appRegistry.add(a2); 97 | 98 | appRegistry.clear(); 99 | Assert.assertFalse(appRegistry.get(k1).isPresent(), 100 | "App " + a1 + " shouldn't be in the app registry after clearing."); 101 | Assert.assertEquals(appRegistry.getAll().size(), 0); 102 | Assert.assertFalse(appRegistry.remove(k1).isPresent(), 103 | "App " + a1 + " shouldn't be in the app registry after clearing."); 104 | Assert.assertFalse(appRegistry.remove(a2), "App " + a2 + " shouldn't be in the app registry after clearing."); 105 | } 106 | 107 | private static App createApp(String name, String path) { 108 | return new App(name, "/" + name, Collections.emptySortedSet(), Collections.emptySet(), Collections.emptySet(), 109 | Collections.emptySet(), null, path); 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /components/org.wso2.carbon.uiserver/src/test/java/org/wso2/carbon/uiserver/internal/http/RequestDispatcherTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * WSO2 Inc. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | package org.wso2.carbon.uiserver.internal.http; 20 | 21 | import org.testng.Assert; 22 | import org.testng.annotations.Test; 23 | import org.wso2.carbon.uiserver.api.exception.UiServerRuntimeException; 24 | import org.wso2.carbon.uiserver.api.http.HttpRequest; 25 | import org.wso2.carbon.uiserver.api.http.HttpResponse; 26 | import org.wso2.carbon.uiserver.internal.io.http.StaticRequestDispatcher; 27 | 28 | import static org.mockito.ArgumentMatchers.any; 29 | import static org.mockito.Mockito.mock; 30 | import static org.mockito.Mockito.verify; 31 | import static org.mockito.Mockito.when; 32 | 33 | /** 34 | * Test cases for {@link RequestDispatcher} class. 35 | * 36 | * @since 0.13.4 37 | */ 38 | public class RequestDispatcherTest { 39 | 40 | @Test 41 | public void testServeInvalidRequest() { 42 | HttpRequest request = mock(HttpRequest.class); 43 | when(request.isValid()).thenReturn(false); 44 | 45 | HttpResponse response = new RequestDispatcher(null).serve(request); 46 | Assert.assertEquals(response.getStatus(), HttpResponse.STATUS_BAD_REQUEST); 47 | Assert.assertNotNull(response.getContent()); 48 | } 49 | 50 | @Test 51 | public void testServeFaviconRequest() { 52 | HttpRequest request = mock(HttpRequest.class); 53 | when(request.isValid()).thenReturn(true); 54 | when(request.isDefaultFaviconRequest()).thenReturn(true); 55 | StaticRequestDispatcher staticRequestDispatcher = mock(StaticRequestDispatcher.class); 56 | 57 | new RequestDispatcher(null, staticRequestDispatcher).serve(request); 58 | verify(staticRequestDispatcher).serveDefaultFavicon(request); 59 | } 60 | 61 | @Test 62 | public void testServeStaticRequest() { 63 | HttpRequest request = mock(HttpRequest.class); 64 | when(request.isValid()).thenReturn(true); 65 | when(request.isDefaultFaviconRequest()).thenReturn(false); 66 | when(request.isStaticResourceRequest()).thenReturn(true); 67 | StaticRequestDispatcher staticRequestDispatcher = mock(StaticRequestDispatcher.class); 68 | 69 | new RequestDispatcher(null, staticRequestDispatcher).serve(request); 70 | verify(staticRequestDispatcher).serve(request); 71 | } 72 | 73 | @Test 74 | public void testServePageRequest() { 75 | HttpRequest request = createPageRequest(); 76 | PageRequestDispatcher pageRequestDispatcher = mock(PageRequestDispatcher.class); 77 | 78 | new RequestDispatcher(pageRequestDispatcher, null).serve(request); 79 | verify(pageRequestDispatcher).serve(request); 80 | } 81 | 82 | @Test 83 | public void testServeWhenUISRuntimeException() { 84 | HttpRequest request = createPageRequest(); 85 | PageRequestDispatcher pageRequestDispatcher = mock(PageRequestDispatcher.class); 86 | when(pageRequestDispatcher.serve(any())).thenThrow(UiServerRuntimeException.class); 87 | 88 | HttpResponse response = new RequestDispatcher(pageRequestDispatcher, null).serve(request); 89 | Assert.assertEquals(response.getStatus(), HttpResponse.STATUS_INTERNAL_SERVER_ERROR); 90 | Assert.assertNotNull(response.getContent()); 91 | } 92 | 93 | @Test 94 | public void testServeWhenException() { 95 | HttpRequest request = createPageRequest(); 96 | PageRequestDispatcher pageRequestDispatcher = mock(PageRequestDispatcher.class); 97 | when(pageRequestDispatcher.serve(any())).thenThrow(Exception.class); 98 | 99 | HttpResponse response = new RequestDispatcher(pageRequestDispatcher, null).serve(request); 100 | Assert.assertEquals(response.getStatus(), HttpResponse.STATUS_INTERNAL_SERVER_ERROR); 101 | Assert.assertNotNull(response.getContent()); 102 | } 103 | 104 | private static HttpRequest createPageRequest() { 105 | HttpRequest request = mock(HttpRequest.class); 106 | when(request.isValid()).thenReturn(true); 107 | when(request.isDefaultFaviconRequest()).thenReturn(false); 108 | when(request.isStaticResourceRequest()).thenReturn(false); 109 | return request; 110 | } 111 | } 112 | --------------------------------------------------------------------------------