├── NOTICE ├── core ├── src │ └── main │ │ └── java │ │ └── com │ │ └── nateyolles │ │ └── aem │ │ └── osgiannotationdemo │ │ └── core │ │ ├── services │ │ ├── SampleFelixService.java │ │ ├── SampleOsgiService.java │ │ └── impl │ │ │ ├── Configuration.java │ │ │ ├── SampleOsgiServiceImpl.java │ │ │ └── SampleFelixServiceImpl.java │ │ ├── listeners │ │ ├── SampleOsgiResourceListener.java │ │ └── SampleFelixResourceListener.java │ │ ├── filters │ │ ├── SampleFelixFilter.java │ │ └── SampleOsgiFilter.java │ │ ├── schedulers │ │ ├── SampleFelixScheduledTask.java │ │ └── SampleOsgiScheduledTask.java │ │ └── servlets │ │ ├── SampleOsgiServlet.java │ │ └── SampleFelixServlet.java └── pom.xml ├── .gitignore ├── README.md ├── LICENSE └── pom.xml /NOTICE: -------------------------------------------------------------------------------- 1 | OSGI Annotation Demo 2 | Copyright 2017 Nate Yolles 3 | 4 | This product includes boilerplate from 5 | AEM project archetype (https://github.com/Adobe-Marketing-Cloud/aem-project-archetype). 6 | -------------------------------------------------------------------------------- /core/src/main/java/com/nateyolles/aem/osgiannotationdemo/core/services/SampleFelixService.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Nate Yolles 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.nateyolles.aem.osgiannotationdemo.core.services; 17 | 18 | public interface SampleFelixService { 19 | String getSettings(); 20 | } 21 | -------------------------------------------------------------------------------- /core/src/main/java/com/nateyolles/aem/osgiannotationdemo/core/services/SampleOsgiService.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Nate Yolles 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.nateyolles.aem.osgiannotationdemo.core.services; 17 | 18 | public interface SampleOsgiService { 19 | String getSettings(); 20 | } 21 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by https://www.gitignore.io/api/eclipse,java,maven 2 | 3 | ### Eclipse ### 4 | *.pydevproject 5 | .metadata 6 | .gradle 7 | bin/ 8 | tmp/ 9 | *.tmp 10 | *.bak 11 | *.swp 12 | *~.nib 13 | local.properties 14 | .settings/ 15 | .loadpath 16 | 17 | # Eclipse Core 18 | .project 19 | 20 | # External tool builders 21 | .externalToolBuilders/ 22 | 23 | # Locally stored "Eclipse launch configurations" 24 | *.launch 25 | 26 | # CDT-specific 27 | .cproject 28 | 29 | # JDT-specific (Eclipse Java Development Tools) 30 | .classpath 31 | 32 | # Java annotation processor (APT) 33 | .factorypath 34 | 35 | # PDT-specific 36 | .buildpath 37 | 38 | # sbteclipse plugin 39 | .target 40 | 41 | # TeXlipse plugin 42 | .texlipse 43 | 44 | 45 | ### Java ### 46 | *.class 47 | 48 | # Mobile Tools for Java (J2ME) 49 | .mtj.tmp/ 50 | 51 | # Package Files # 52 | *.jar 53 | *.war 54 | *.ear 55 | 56 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 57 | hs_err_pid* 58 | 59 | 60 | ### Maven ### 61 | target/ 62 | pom.xml.tag 63 | pom.xml.releaseBackup 64 | pom.xml.versionsBackup 65 | pom.xml.next 66 | release.properties 67 | dependency-reduced-pom.xml 68 | buildNumber.properties 69 | .mvn/timing.properties 70 | 71 | ### Vault ### 72 | .vlt 73 | 74 | ### IntelliJ ### 75 | .idea/ 76 | *.iml 77 | -------------------------------------------------------------------------------- /core/src/main/java/com/nateyolles/aem/osgiannotationdemo/core/listeners/SampleOsgiResourceListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Nate Yolles 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.nateyolles.aem.osgiannotationdemo.core.listeners; 17 | 18 | import org.apache.sling.api.SlingConstants; 19 | import org.osgi.service.component.annotations.Component; 20 | import org.osgi.service.event.Event; 21 | import org.osgi.service.event.EventConstants; 22 | import org.osgi.service.event.EventHandler; 23 | import org.slf4j.Logger; 24 | import org.slf4j.LoggerFactory; 25 | 26 | @Component( 27 | immediate = true, 28 | service = EventHandler.class, 29 | property = { 30 | EventConstants.EVENT_FILTER + "=(path=/content/*)", 31 | EventConstants.EVENT_TOPIC + "=" + SlingConstants.TOPIC_RESOURCE_ADDED, 32 | EventConstants.EVENT_TOPIC + "=" + SlingConstants.TOPIC_RESOURCE_CHANGED, 33 | EventConstants.EVENT_TOPIC + "=" + SlingConstants.TOPIC_RESOURCE_REMOVED 34 | }, 35 | configurationPid = "com.nateyolles.aem.osgiannotationdemo.core.schedulers.SampleOsgiScheduledTask" 36 | ) 37 | public class SampleOsgiResourceListener implements EventHandler { 38 | 39 | private final Logger logger = LoggerFactory.getLogger(getClass()); 40 | 41 | public void handleEvent(final Event event) { 42 | logger.info("OSGi EventHandler: {} at: {}", 43 | event.getTopic(), event.getProperty(SlingConstants.PROPERTY_PATH)); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /core/src/main/java/com/nateyolles/aem/osgiannotationdemo/core/filters/SampleFelixFilter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Nate Yolles 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.nateyolles.aem.osgiannotationdemo.core.filters; 17 | 18 | import java.io.IOException; 19 | 20 | import javax.servlet.Filter; 21 | import javax.servlet.FilterChain; 22 | import javax.servlet.FilterConfig; 23 | import javax.servlet.ServletException; 24 | import javax.servlet.ServletRequest; 25 | import javax.servlet.ServletResponse; 26 | 27 | import org.apache.felix.scr.annotations.sling.SlingFilter; 28 | import org.apache.felix.scr.annotations.sling.SlingFilterScope; 29 | import org.apache.sling.api.SlingHttpServletRequest; 30 | import org.slf4j.Logger; 31 | import org.slf4j.LoggerFactory; 32 | 33 | @SlingFilter( 34 | order = Integer.MIN_VALUE, 35 | pattern = "/content/(.*)", 36 | scope = SlingFilterScope.REQUEST 37 | ) 38 | public class SampleFelixFilter implements Filter { 39 | 40 | private final Logger logger = LoggerFactory.getLogger(getClass()); 41 | 42 | @Override 43 | public void doFilter(final ServletRequest request, final ServletResponse response, 44 | final FilterChain filterChain) throws IOException, ServletException { 45 | 46 | final SlingHttpServletRequest slingRequest = (SlingHttpServletRequest) request; 47 | logger.info("Felix Filter: request for {}", slingRequest.getRequestPathInfo().getResourcePath()); 48 | 49 | filterChain.doFilter(request, response); 50 | } 51 | 52 | @Override 53 | public void init(FilterConfig filterConfig) { 54 | } 55 | 56 | @Override 57 | public void destroy() { 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /core/src/main/java/com/nateyolles/aem/osgiannotationdemo/core/listeners/SampleFelixResourceListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Nate Yolles 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.nateyolles.aem.osgiannotationdemo.core.listeners; 17 | 18 | import org.apache.felix.scr.annotations.Component; 19 | import org.apache.felix.scr.annotations.Properties; 20 | import org.apache.felix.scr.annotations.Property; 21 | import org.apache.felix.scr.annotations.Service; 22 | import org.apache.sling.api.SlingConstants; 23 | import org.osgi.service.event.Event; 24 | import org.osgi.service.event.EventConstants; 25 | import org.osgi.service.event.EventHandler; 26 | import org.slf4j.Logger; 27 | import org.slf4j.LoggerFactory; 28 | 29 | @Component( 30 | immediate = true 31 | ) 32 | @Service(value = EventHandler.class) 33 | @Properties({ 34 | /* 35 | * Set propertyPrivate = true if you generate metatype = true. 36 | */ 37 | @Property( 38 | name = EventConstants.EVENT_TOPIC, 39 | value = { 40 | SlingConstants.TOPIC_RESOURCE_ADDED, 41 | SlingConstants.TOPIC_RESOURCE_CHANGED, 42 | SlingConstants.TOPIC_RESOURCE_REMOVED 43 | } 44 | ), 45 | @Property( 46 | name = EventConstants.EVENT_FILTER, 47 | //propertyPrivate = true, 48 | value = "(path=/content/*)" 49 | ) 50 | }) 51 | public class SampleFelixResourceListener implements EventHandler { 52 | 53 | private final Logger logger = LoggerFactory.getLogger(getClass()); 54 | 55 | public void handleEvent(final Event event) { 56 | logger.info("Felix EventHander: {} at: {}", 57 | event.getTopic(), event.getProperty(SlingConstants.PROPERTY_PATH)); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /core/src/main/java/com/nateyolles/aem/osgiannotationdemo/core/filters/SampleOsgiFilter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Nate Yolles 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.nateyolles.aem.osgiannotationdemo.core.filters; 17 | 18 | import java.io.IOException; 19 | 20 | import javax.servlet.Filter; 21 | import javax.servlet.FilterChain; 22 | import javax.servlet.FilterConfig; 23 | import javax.servlet.ServletException; 24 | import javax.servlet.ServletRequest; 25 | import javax.servlet.ServletResponse; 26 | 27 | import org.osgi.service.component.annotations.Component; 28 | import org.apache.sling.api.SlingHttpServletRequest; 29 | import org.slf4j.Logger; 30 | import org.slf4j.LoggerFactory; 31 | 32 | @Component( 33 | configurationPid = "com.nateyolles.aem.osgiannotationdemo.core.filters.SampleOsgiFilter", 34 | service = { Filter.class }, 35 | property = { 36 | "sling.filter.scope=request", 37 | "sling.filter.pattern=/content/(.*)", 38 | "service.ranking:Integer=" + Integer.MAX_VALUE, 39 | } 40 | ) 41 | public class SampleOsgiFilter implements Filter { 42 | 43 | private final Logger logger = LoggerFactory.getLogger(getClass()); 44 | 45 | @Override 46 | public void doFilter(final ServletRequest request, final ServletResponse response, 47 | final FilterChain filterChain) throws IOException, ServletException { 48 | 49 | final SlingHttpServletRequest slingRequest = (SlingHttpServletRequest) request; 50 | logger.info("OSGi Filter: request for {}", slingRequest.getRequestPathInfo().getResourcePath()); 51 | 52 | filterChain.doFilter(request, response); 53 | } 54 | 55 | @Override 56 | public void init(FilterConfig filterConfig) { 57 | } 58 | 59 | @Override 60 | public void destroy() { 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /core/src/main/java/com/nateyolles/aem/osgiannotationdemo/core/schedulers/SampleFelixScheduledTask.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Nate Yolles 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.nateyolles.aem.osgiannotationdemo.core.schedulers; 17 | 18 | import java.util.Map; 19 | 20 | import org.apache.commons.lang3.StringUtils; 21 | import org.apache.felix.scr.annotations.Activate; 22 | import org.apache.felix.scr.annotations.Component; 23 | import org.apache.felix.scr.annotations.Properties; 24 | import org.apache.felix.scr.annotations.Property; 25 | import org.apache.felix.scr.annotations.Service; 26 | import org.apache.sling.commons.osgi.PropertiesUtil; 27 | import org.slf4j.Logger; 28 | import org.slf4j.LoggerFactory; 29 | 30 | @Component( 31 | metatype = true, 32 | label = "Annotation Demo Scheduler - Felix", 33 | description = "Sample Scheduler using Felix SCR annotations." 34 | ) 35 | @Service(value = Runnable.class) 36 | @Properties({ 37 | @Property( 38 | name = "scheduler.expression", 39 | value = "0 * * * * ?", 40 | description = "Cron-job expression. Default: run every minute." 41 | ), 42 | @Property( 43 | name = "scheduler.concurrent", 44 | boolValue = false, 45 | description = "Schedule task concurrently" 46 | ) 47 | }) 48 | public class SampleFelixScheduledTask implements Runnable { 49 | 50 | private final Logger logger = LoggerFactory.getLogger(getClass()); 51 | 52 | @Override 53 | public void run() { 54 | logger.info("Sample Felix Scheduler is now running, myParameter='{}'", myParameter); 55 | } 56 | 57 | @Property( 58 | label = "My Parameter", 59 | description = "Sample String parameter" 60 | ) 61 | public static final String MY_PARAMETER = "myParameter"; 62 | private String myParameter; 63 | 64 | @Activate 65 | protected void activate(final Map config) { 66 | configure(config); 67 | } 68 | 69 | private void configure(final Map config) { 70 | myParameter = PropertiesUtil.toString(config.get(MY_PARAMETER), StringUtils.EMPTY); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /core/src/main/java/com/nateyolles/aem/osgiannotationdemo/core/schedulers/SampleOsgiScheduledTask.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Nate Yolles 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.nateyolles.aem.osgiannotationdemo.core.schedulers; 17 | 18 | import org.apache.commons.lang3.StringUtils; 19 | import org.osgi.service.component.annotations.Activate; 20 | import org.osgi.service.component.annotations.Component; 21 | import org.osgi.service.metatype.annotations.AttributeDefinition; 22 | import org.osgi.service.metatype.annotations.AttributeType; 23 | import org.osgi.service.metatype.annotations.Designate; 24 | import org.osgi.service.metatype.annotations.ObjectClassDefinition; 25 | import org.slf4j.Logger; 26 | import org.slf4j.LoggerFactory; 27 | 28 | @Component( 29 | immediate = true, 30 | configurationPid = "com.nateyolles.aem.osgiannotationdemo.core.schedulers.SampleOsgiScheduledTask" 31 | // If you wanted the properties to be private 32 | // property = { 33 | // "scheduler.expression=* * * * * ?", 34 | // "scheduler.concurrent:Boolean=false" 35 | // } 36 | ) 37 | @Designate(ocd = SampleOsgiScheduledTask.Configuration.class) 38 | public class SampleOsgiScheduledTask implements Runnable { 39 | 40 | private final Logger logger = LoggerFactory.getLogger(getClass()); 41 | 42 | @Override 43 | public void run() { 44 | logger.info("Sample OSGi Scheduler is now running, myParameter='{}'", myParameter); 45 | } 46 | 47 | private String myParameter; 48 | 49 | @Activate 50 | protected void activate(Configuration config) { 51 | myParameter = config.myParameter(); 52 | } 53 | 54 | @ObjectClassDefinition(name="Annotation Demo Scheduler - OSGi") 55 | public @interface Configuration { 56 | @AttributeDefinition( 57 | name="My parameter", 58 | description="Sample String parameter") 59 | String myParameter() default StringUtils.EMPTY; 60 | 61 | @AttributeDefinition( 62 | name = "Concurrent", 63 | description = "Schedule task concurrently", 64 | type = AttributeType.BOOLEAN 65 | ) 66 | boolean scheduler_concurrent() default true; 67 | 68 | @AttributeDefinition( 69 | name = "Expression", 70 | description = "Cron-job expression. Default: run every minute.", 71 | type = AttributeType.STRING 72 | ) 73 | String scheduler_expression() default "0 * * * * ?"; 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /core/src/main/java/com/nateyolles/aem/osgiannotationdemo/core/services/impl/Configuration.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Nate Yolles 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.nateyolles.aem.osgiannotationdemo.core.services.impl; 17 | 18 | import org.apache.commons.lang3.StringUtils; 19 | import org.osgi.service.metatype.annotations.AttributeDefinition; 20 | import org.osgi.service.metatype.annotations.AttributeType; 21 | import org.osgi.service.metatype.annotations.ObjectClassDefinition; 22 | import org.osgi.service.metatype.annotations.Option; 23 | 24 | @ObjectClassDefinition(name = "Annotation Demo Service - OSGi") 25 | public @interface Configuration { 26 | 27 | @AttributeDefinition( 28 | name = "Boolean Property", 29 | description = "Sample boolean value", 30 | type = AttributeType.BOOLEAN 31 | ) 32 | boolean servicename_propertyname_boolean() default true; 33 | 34 | @AttributeDefinition( 35 | name = "String Property", 36 | description = "Sample String property", 37 | type = AttributeType.STRING 38 | ) 39 | String servicename_propertyname_string() default "foo"; 40 | 41 | @AttributeDefinition( 42 | name = "Dropdown property", 43 | description = "Sample dropdown property", 44 | options = { 45 | @Option(label = "DAYS", value = "DAYS"), 46 | @Option(label = "HOURS", value = "HOURS"), 47 | @Option(label = "MILLISECONDS", value = "MILLISECONDS"), 48 | @Option(label = "MINUTES", value = "MINUTES"), 49 | @Option(label = "SECONDS", value = "SECONDS") 50 | } 51 | ) 52 | String servicename_propertyname_dropdown() default StringUtils.EMPTY; 53 | 54 | @AttributeDefinition( 55 | name = "String Array Property", 56 | description = "Sample String array property", 57 | type = AttributeType.STRING 58 | ) 59 | String[] servicename_propertyname_string_array() default {"foo", "bar"}; 60 | 61 | /* 62 | * To create password field, either set the AttributeType or have the 63 | * property name end with "*.password" (or both). 64 | */ 65 | @AttributeDefinition( 66 | name = "Password Property", 67 | description = "Sample password property", 68 | type = AttributeType.PASSWORD 69 | ) 70 | String servicename_propertyname_password() default StringUtils.EMPTY; 71 | 72 | @AttributeDefinition( 73 | name = "Long Property", 74 | description = "Sample long property", 75 | type = AttributeType.LONG 76 | ) 77 | long servicename_propertyname_long() default 0L; 78 | } 79 | -------------------------------------------------------------------------------- /core/src/main/java/com/nateyolles/aem/osgiannotationdemo/core/services/impl/SampleOsgiServiceImpl.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Nate Yolles 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.nateyolles.aem.osgiannotationdemo.core.services.impl; 17 | 18 | import org.apache.commons.lang3.ArrayUtils; 19 | import org.apache.sling.api.resource.ResourceResolverFactory; 20 | import org.osgi.service.component.annotations.Activate; 21 | import org.osgi.service.component.annotations.Component; 22 | import org.osgi.service.component.annotations.Deactivate; 23 | import org.osgi.service.component.annotations.Modified; 24 | import org.osgi.service.component.annotations.Reference; 25 | import org.osgi.service.metatype.annotations.Designate; 26 | 27 | import com.nateyolles.aem.osgiannotationdemo.core.services.SampleOsgiService; 28 | 29 | @Component( 30 | immediate = true, 31 | service = SampleOsgiService.class, 32 | configurationPid = "com.nateyolles.aem.osgiannotationdemo.core.services.impl.SampleOsgiServiceImpl" 33 | ) 34 | @Designate( 35 | ocd = Configuration.class 36 | ) 37 | public class SampleOsgiServiceImpl implements SampleOsgiService { 38 | 39 | @Reference 40 | private ResourceResolverFactory resolverFactory; 41 | 42 | boolean booleanProp; 43 | String stringProp; 44 | String dropdownProp; 45 | String[] stringArrayProp; 46 | char[] passwordProp; 47 | long longProp; 48 | 49 | @Override 50 | public String getSettings() { 51 | StringBuilder sb = new StringBuilder(); 52 | sb.append("Sample OSGi Service:\n"); 53 | sb.append("booleanProp: " + booleanProp + "\n"); 54 | sb.append("stringProp: " + stringProp + "\n"); 55 | sb.append("dropdownProp: " + dropdownProp + "\n"); 56 | sb.append("stringArrayProp: " + ArrayUtils.toString(stringArrayProp) + "\n"); 57 | sb.append("passwordProp: " + String.valueOf(passwordProp) + "\n"); 58 | sb.append("longProp: " + longProp + "\n"); 59 | 60 | return sb.toString(); 61 | } 62 | 63 | @Activate 64 | @Modified 65 | protected final void activate(Configuration config) { 66 | booleanProp = config.servicename_propertyname_boolean(); 67 | stringProp = config.servicename_propertyname_string(); 68 | dropdownProp = config.servicename_propertyname_dropdown(); 69 | stringArrayProp = config.servicename_propertyname_string_array(); 70 | passwordProp = config.servicename_propertyname_password().toCharArray(); 71 | longProp = config.servicename_propertyname_long(); 72 | } 73 | 74 | @Deactivate 75 | protected void deactivate() { 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /core/src/main/java/com/nateyolles/aem/osgiannotationdemo/core/servlets/SampleOsgiServlet.java: -------------------------------------------------------------------------------- 1 | package com.nateyolles.aem.osgiannotationdemo.core.servlets; 2 | 3 | /* 4 | * Copyright 2017 Nate Yolles 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | import java.io.IOException; 19 | import java.io.PrintWriter; 20 | 21 | import javax.servlet.Servlet; 22 | import javax.servlet.ServletException; 23 | 24 | import org.apache.sling.api.SlingHttpServletRequest; 25 | import org.apache.sling.api.SlingHttpServletResponse; 26 | import org.apache.sling.api.servlets.SlingSafeMethodsServlet; 27 | import org.osgi.service.component.annotations.Activate; 28 | import org.osgi.service.component.annotations.Component; 29 | import org.osgi.service.component.annotations.Modified; 30 | import org.osgi.service.component.annotations.Reference; 31 | import org.osgi.service.metatype.annotations.AttributeDefinition; 32 | import org.osgi.service.metatype.annotations.Designate; 33 | import org.osgi.service.metatype.annotations.ObjectClassDefinition; 34 | 35 | import com.nateyolles.aem.osgiannotationdemo.core.services.SampleOsgiService; 36 | 37 | @Component( 38 | immediate = true, 39 | service = Servlet.class, 40 | property = { 41 | "sling.servlet.extensions=txt", 42 | "sling.servlet.paths=/bin/osgi", 43 | "sling.servlet.paths=/bin/foo", 44 | "sling.servlet.methods=get" 45 | }, 46 | configurationPid = "com.nateyolles.aem.osgiannotationdemo.core.servlets.SampleOsgiServlet" 47 | ) 48 | @Designate(ocd=SampleOsgiServlet.Configuration.class) 49 | public class SampleOsgiServlet extends SlingSafeMethodsServlet { 50 | 51 | private static final long serialVersionUID = 1L; 52 | 53 | @Reference 54 | private SampleOsgiService sampleOsgiService; 55 | 56 | private boolean enabled; 57 | 58 | @Override 59 | protected void doGet(final SlingHttpServletRequest req, 60 | final SlingHttpServletResponse resp) throws ServletException, IOException { 61 | 62 | PrintWriter out = resp.getWriter(); 63 | 64 | resp.setContentType("text/plain"); 65 | out.write("Annotation Demo Servlet - OSGi - enabled: " + enabled + "\n"); 66 | out.write(sampleOsgiService.getSettings()); 67 | } 68 | 69 | @Activate 70 | @Modified 71 | protected void Activate(Configuration config) { 72 | enabled = config.enabled(); 73 | } 74 | 75 | @ObjectClassDefinition(name = "Annotation Demo Servlet - OSGi") 76 | public @interface Configuration { 77 | @AttributeDefinition( 78 | name = "Enable", 79 | description = "Sample boolean property" 80 | ) 81 | boolean enabled() default false; 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /core/src/main/java/com/nateyolles/aem/osgiannotationdemo/core/servlets/SampleFelixServlet.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Nate Yolles 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.nateyolles.aem.osgiannotationdemo.core.servlets; 17 | 18 | import java.io.IOException; 19 | import java.io.PrintWriter; 20 | import java.util.Collections; 21 | import java.util.Map; 22 | 23 | import javax.servlet.ServletException; 24 | 25 | import org.apache.felix.scr.annotations.Activate; 26 | import org.apache.felix.scr.annotations.Component; 27 | import org.apache.felix.scr.annotations.Modified; 28 | import org.apache.felix.scr.annotations.Property; 29 | import org.apache.felix.scr.annotations.Reference; 30 | import org.apache.felix.scr.annotations.sling.SlingServlet; 31 | import org.apache.sling.api.SlingHttpServletRequest; 32 | import org.apache.sling.api.SlingHttpServletResponse; 33 | import org.apache.sling.api.servlets.SlingSafeMethodsServlet; 34 | import org.apache.sling.commons.osgi.PropertiesUtil; 35 | 36 | import com.nateyolles.aem.osgiannotationdemo.core.services.SampleFelixService; 37 | 38 | @SlingServlet( 39 | metatype = true, 40 | paths = {"/bin/felix"}, 41 | methods = "GET", 42 | label = "Annotation Demo Servlet - Felix", 43 | description = "Sample servlet using Felix SCR annotations" 44 | ) 45 | public class SampleFelixServlet extends SlingSafeMethodsServlet { 46 | 47 | private static final long serialVersionUID = 1L; 48 | 49 | @Reference 50 | private SampleFelixService sampleFelixService; 51 | 52 | @Property( 53 | label = "Enable", 54 | name = SampleFelixServlet.ENABLE_SERVICE, 55 | description = "Sample boolean property", 56 | boolValue = SampleFelixServlet.ENABLE_SERVICE_DEFAULT 57 | ) 58 | public static final String ENABLE_SERVICE = "enabled"; 59 | private static final boolean ENABLE_SERVICE_DEFAULT = false; 60 | private boolean enabled; 61 | 62 | @Override 63 | protected void doGet(final SlingHttpServletRequest req, 64 | final SlingHttpServletResponse resp) throws ServletException, IOException { 65 | 66 | PrintWriter out = resp.getWriter(); 67 | 68 | resp.setContentType("text/plain"); 69 | out.write("Annotation Demo Servlet - Felix - enabled: " + enabled + "\n"); 70 | out.write(sampleFelixService.getSettings()); 71 | } 72 | 73 | @Activate 74 | @Modified 75 | protected final void activate(final Map config) { 76 | Map properties = Collections.emptyMap(); 77 | 78 | if (config != null) { 79 | properties = config; 80 | } 81 | 82 | enabled = PropertiesUtil.toBoolean(properties.get(ENABLE_SERVICE), ENABLE_SERVICE_DEFAULT); 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # AEM OSGi Declarative Services Annotations 2 | 3 | This project demonstrates the basics of using the [OSGi Declarative Services annotations](http://enroute.osgi.org/services/org.osgi.service.component.html) along side the more familiar [Felix SCR annotations](http://felix.apache.org/documentation/subprojects/apache-felix-maven-scr-plugin/scr-annotations.html). 4 | 5 | Examples are given for both annotation styles in each of a servlet, service, filter, scheduler and an event handler / listener. These five examples are common AEM project requirements and the examples can be extrapolated out for anything else such as MBeans, Adapters, Workflow Process Steps, Replication Preprocessors, etc... 6 | 7 | Note the service example creates the Configuration as a separate class while the other examples create the Configuration as a subclass. 8 | 9 | View the associated blog post at [http://www.nateyolles.com/blog/2017/05/osgi-declarative-services-annotations-in-aem](http://www.nateyolles.com/blog/2017/05/osgi-declarative-services-annotations-in-aem). 10 | 11 | ## How to build 12 | 13 | This project has been built and tested in AEM 6.2. 14 | 15 | To build all the modules run in the project root directory the following command with Maven 3: 16 | 17 | mvn clean install 18 | 19 | Or to deploy the bundle to the author, run 20 | 21 | mvn clean install -PautoInstallBundle 22 | 23 | ## Test 24 | 25 | Below are a some cURL commands to help you test the components. Navigate to the [Felix Configuration](http://localhost:4502/system/console/configMgr) console to update component properties. 26 | 27 | ### Servlets and Services 28 | 29 | Make a GET request to the servlets which consume the services and respond back with plain text: 30 | 31 | ```bash 32 | curl -u admin:admin http://localhost:4502/bin/felix 33 | curl -u admin:admin http://localhost:4502/bin/osgi 34 | ``` 35 | 36 | * [/system/console/configMgr/com.nateyolles.aem.osgiannotationdemo.core.servlets.SampleFelixServlet](http://localhost:4502/system/console/configMgr/com.nateyolles.aem.osgiannotationdemo.core.servlets.SampleFelixServlet) 37 | * [/system/console/configMgr/com.nateyolles.aem.osgiannotationdemo.core.servlets.SampleOsgiServlet](http://localhost:4502/system/console/configMgr/com.nateyolles.aem.osgiannotationdemo.core.servlets.SampleOsgiServlet) 38 | * [/system/console/configMgr/com.nateyolles.aem.osgiannotationdemo.core.services.impl.SampleFelixServiceImpl](http://localhost:4502/system/console/configMgr/com.nateyolles.aem.osgiannotationdemo.core.services.impl.SampleFelixServiceImpl) 39 | * [/system/console/configMgr/com.nateyolles.aem.osgiannotationdemo.core.services.impl.SampleOsgiServiceImpl](http://localhost:4502/system/console/configMgr/com.nateyolles.aem.osgiannotationdemo.core.services.impl.SampleFelixServiceImpl) 40 | 41 | ### Event Handler 42 | 43 | Create a new node under `/content` and watch the logs: 44 | 45 | ```bash 46 | curl -u admin:admin http://localhost:4502/content/foo -F"myproperty=bar" 47 | ``` 48 | 49 | ### Scheduler 50 | 51 | View the logs to see the scheduler running every 60 seconds by default. 52 | 53 | * [/system/console/configMgr/com.nateyolles.aem.osgiannotationdemo.core.schedulers.SampleFelixScheduledTask](http://localhost:4502/system/console/configMgr/com.nateyolles.aem.osgiannotationdemo.core.schedulers.SampleFelixScheduledTask) 54 | * [/system/console/configMgr/com.nateyolles.aem.osgiannotationdemo.core.schedulers.SampleOsgiScheduledTask](http://localhost:4502/system/console/configMgr/com.nateyolles.aem.osgiannotationdemo.core.schedulers.SampleOsgiScheduledTask) 55 | 56 | ### Filters 57 | 58 | Make a request to a resouce under `/content` and watch the logs: 59 | 60 | ```bash 61 | curl -u admin:admin http://localhost:4502/content/geometrixx/en/products/triangle.html 62 | ``` 63 | 64 | ## Maven settings 65 | 66 | The project comes with the auto-public repository configured. To setup the repository in your Maven settings, refer to: 67 | 68 | http://helpx.adobe.com/experience-manager/kb/SetUpTheAdobeMavenRepository.html 69 | -------------------------------------------------------------------------------- /core/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 19 | 4.0.0 20 | 21 | com.nateyolles.aem 22 | osgi-annotation-demo 23 | 1.0-SNAPSHOT 24 | ../pom.xml 25 | 26 | osgi-annotation-demo.core 27 | bundle 28 | OSGi Annotation Demo - Core 29 | Core bundle for OSGi Annotation Demo 30 | 31 | 32 | 33 | org.apache.felix 34 | maven-scr-plugin 35 | 36 | 37 | org.apache.sling 38 | maven-sling-plugin 39 | 40 | 41 | org.apache.felix 42 | maven-bundle-plugin 43 | true 44 | 45 | 46 | 47 | javax.inject;version=0.0.0,* 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | org.apache.felix 58 | org.apache.felix.scr 59 | 60 | 61 | org.apache.felix 62 | org.apache.felix.framework 63 | 64 | 65 | org.apache.felix 66 | org.apache.felix.eventadmin 67 | 68 | 69 | org.apache.felix 70 | org.apache.felix.scr.annotations 71 | 72 | 73 | 74 | 75 | org.osgi 76 | org.osgi.service.metatype.annotations 77 | 78 | 79 | org.osgi 80 | org.osgi.service.component.annotations 81 | 82 | 83 | 84 | 85 | org.apache.commons 86 | commons-lang3 87 | 88 | 89 | org.slf4j 90 | slf4j-api 91 | 92 | 93 | javax.jcr 94 | jcr 95 | 96 | 97 | javax.servlet 98 | servlet-api 99 | 100 | 101 | 102 | 103 | com.adobe.aem 104 | uber-jar 105 | obfuscated-apis 106 | 107 | 108 | 109 | 110 | -------------------------------------------------------------------------------- /core/src/main/java/com/nateyolles/aem/osgiannotationdemo/core/services/impl/SampleFelixServiceImpl.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Nate Yolles 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.nateyolles.aem.osgiannotationdemo.core.services.impl; 17 | 18 | import java.util.Collections; 19 | import java.util.Map; 20 | 21 | import org.apache.commons.lang3.ArrayUtils; 22 | import org.apache.commons.lang3.StringUtils; 23 | import org.apache.felix.scr.annotations.Activate; 24 | import org.apache.felix.scr.annotations.Component; 25 | import org.apache.felix.scr.annotations.ConfigurationPolicy; 26 | import org.apache.felix.scr.annotations.Deactivate; 27 | import org.apache.felix.scr.annotations.Modified; 28 | import org.apache.felix.scr.annotations.Properties; 29 | import org.apache.felix.scr.annotations.Property; 30 | import org.apache.felix.scr.annotations.PropertyOption; 31 | import org.apache.felix.scr.annotations.PropertyUnbounded; 32 | import org.apache.felix.scr.annotations.Reference; 33 | import org.apache.felix.scr.annotations.Service; 34 | import org.apache.sling.api.resource.ResourceResolverFactory; 35 | import org.apache.sling.commons.osgi.PropertiesUtil; 36 | 37 | import com.nateyolles.aem.osgiannotationdemo.core.services.SampleFelixService; 38 | 39 | @Component( 40 | metatype = true, 41 | label = "Annotation Demo Service - Felix", 42 | description = "Sample service with various Felix SCR annotations" 43 | ) 44 | @Service(value = SampleFelixService.class) 45 | @Properties({ 46 | @Property( 47 | label = "Boolean Property", 48 | name = SampleFelixServiceImpl.BOOLEAN_PROPERTY_NAME, 49 | description = "Sample boolean value", 50 | boolValue = SampleFelixServiceImpl.BOOLEAN_PROPERTY_DEFAULT_VALUE 51 | ), 52 | @Property( 53 | label = "String Property", 54 | description = "Sample String property", 55 | name = SampleFelixServiceImpl.STRING_PROPERTY_NAME, 56 | value = SampleFelixServiceImpl.STRING_PROPERTY_DEFAULT_VALUE 57 | ), 58 | @Property( 59 | label = "Dropdown Property", 60 | name = SampleFelixServiceImpl.DROPDOWN_PROPERTY_NAME, 61 | description = "Sample dropdown property", 62 | value=SampleFelixServiceImpl.DROPDOWN_PROPERTY_DEFAULT_VALUE, 63 | options = { 64 | @PropertyOption(name = "DAYS", value = "DAYS"), 65 | @PropertyOption(name = "HOURS", value = "HOURS"), 66 | @PropertyOption(name = "MILLISECONDS", value = "MILLISECONDS"), 67 | @PropertyOption(name = "MINUTES", value = "MINUTES"), 68 | @PropertyOption(name = "SECONDS", value = "SECONDS") 69 | }), 70 | /* 71 | * To create a user expandable field of Strings, use either 72 | * unbounded = PropetyUnbounded.ARRAY or cardinality = a positive integer 73 | * such as Integer.MAX_VALUE. 74 | */ 75 | @Property( 76 | label = "String Array Property (unbounded)", 77 | name = SampleFelixServiceImpl.STRING_ARRAY_PROPERTY_NAME, 78 | description = "Sample String array property (unbounded)", 79 | unbounded = PropertyUnbounded.ARRAY 80 | ), 81 | /* 82 | * To create password field, either set the AttributeType or have the 83 | * property name end with "*.password" (or both). 84 | */ 85 | @Property( 86 | label = "Password Property", 87 | description = "Sample password property", 88 | name = SampleFelixServiceImpl.PASSWORD_PROPERTY_NAME, 89 | passwordValue = StringUtils.EMPTY 90 | ), 91 | @Property( 92 | label = "Long Property", 93 | description = "Sample long property", 94 | name = SampleFelixServiceImpl.LONG_PROPERTY_NAME, 95 | longValue = SampleFelixServiceImpl.LONG_PROPERTY_DEFAULT_VALUE 96 | ) 97 | }) 98 | public class SampleFelixServiceImpl implements SampleFelixService { 99 | 100 | @Reference 101 | private ResourceResolverFactory resolverFactory; 102 | 103 | 104 | public static final String BOOLEAN_PROPERTY_NAME = "servicename.propertyname.boolean"; 105 | public static final boolean BOOLEAN_PROPERTY_DEFAULT_VALUE = false; 106 | 107 | public static final String STRING_PROPERTY_NAME = "servicename.propertyname.string"; 108 | public static final String STRING_PROPERTY_DEFAULT_VALUE = "foo"; 109 | 110 | public static final String PASSWORD_PROPERTY_NAME = "servicename.propertyname.password"; 111 | 112 | public static final String STRING_ARRAY_PROPERTY_NAME = "servicename.propertyname.stringarray.unbounded"; 113 | 114 | public static final String STRING_ARRAY_2_PROPERTY_NAME = "servicename.propertyname.stringarray.cardinality"; 115 | 116 | public static final String DROPDOWN_PROPERTY_NAME = "servicename.propertyname.dropdown"; 117 | public static final String DROPDOWN_PROPERTY_DEFAULT_VALUE = "SECONDS"; 118 | 119 | public static final String LONG_PROPERTY_NAME = "servicename.propertyname.long"; 120 | public static final long LONG_PROPERTY_DEFAULT_VALUE = 0L; 121 | 122 | boolean booleanProp; 123 | String stringProp; 124 | String dropdownProp; 125 | String[] stringArrayProp; 126 | char[] passwordProp; 127 | long longProp; 128 | 129 | @Override 130 | public String getSettings() { 131 | StringBuilder sb = new StringBuilder(); 132 | sb.append("Sample Felix Service:\n"); 133 | sb.append("booleanProp: " + booleanProp + "\n"); 134 | sb.append("stringProp: " + stringProp + "\n"); 135 | sb.append("dropdownProp: " + dropdownProp + "\n"); 136 | sb.append("stringArrayProp: " + ArrayUtils.toString(stringArrayProp) + "\n"); 137 | sb.append("passwordProp: " + String.valueOf(passwordProp) + "\n"); 138 | sb.append("longProp: " + longProp + "\n"); 139 | 140 | return sb.toString(); 141 | } 142 | 143 | @Activate 144 | @Modified 145 | protected final void activate(final Map config) { 146 | Map properties = Collections.emptyMap(); 147 | 148 | if (config != null) { 149 | properties = config; 150 | } 151 | 152 | booleanProp = PropertiesUtil.toBoolean(properties.get(BOOLEAN_PROPERTY_NAME), BOOLEAN_PROPERTY_DEFAULT_VALUE); 153 | stringProp = PropertiesUtil.toString(properties.get(STRING_PROPERTY_NAME), STRING_PROPERTY_DEFAULT_VALUE); 154 | dropdownProp = PropertiesUtil.toString(properties.get(DROPDOWN_PROPERTY_NAME), DROPDOWN_PROPERTY_DEFAULT_VALUE); 155 | stringArrayProp = PropertiesUtil.toStringArray(properties.get(STRING_ARRAY_PROPERTY_NAME)); 156 | passwordProp = PropertiesUtil.toString(properties.get(PASSWORD_PROPERTY_NAME), "").toCharArray(); 157 | longProp = PropertiesUtil.toLong(properties.get(LONG_PROPERTY_NAME), LONG_PROPERTY_DEFAULT_VALUE); 158 | } 159 | 160 | @Deactivate 161 | protected void deactivate() { 162 | } 163 | } 164 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright [yyyy] [name of copyright owner] 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. 203 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 4.0.0 19 | com.nateyolles.aem 20 | osgi-annotation-demo 21 | pom 22 | 1.0-SNAPSHOT 23 | OSGi Annotation Demo 24 | 25 | 26 | core 27 | 28 | 29 | 30 | localhost 31 | 4502 32 | localhost 33 | 4503 34 | admin 35 | admin 36 | admin 37 | admin 38 | 39 | UTF-8 40 | UTF-8 41 | 42 | 43 | 44 | 45 | 46 | 47 | org.apache.maven.plugins 48 | maven-enforcer-plugin 49 | 50 | 51 | enforce-maven 52 | 53 | enforce 54 | 55 | 56 | 57 | 58 | [2.2.1,) 59 | 60 | 61 | Project must be compiled with Java 8 or higher 62 | 1.8.0 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | org.apache.maven.plugins 72 | maven-compiler-plugin 73 | 74 | 1.8 75 | 1.8 76 | 77 | 78 | 79 | 80 | org.apache.maven.plugins 81 | maven-idea-plugin 82 | 2.2.1 83 | 84 | 1.8 85 | true 86 | true 87 | 88 | 89 | 90 | 91 | org.apache.maven.plugins 92 | maven-eclipse-plugin 93 | 2.9 94 | 95 | true 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | org.apache.maven.plugins 104 | maven-clean-plugin 105 | 2.6.1 106 | 107 | 108 | 109 | org.apache.maven.plugins 110 | maven-resources-plugin 111 | 2.7 112 | 113 | 114 | 115 | org.apache.maven.plugins 116 | maven-compiler-plugin 117 | 3.2 118 | 119 | 120 | 121 | 122 | 123 | org.apache.felix 124 | maven-scr-plugin 125 | 1.20.0 126 | 127 | 128 | generate-scr-scrdescriptor 129 | 130 | scr 131 | 132 | 133 | 134 | 135 | Nate Yolles 136 | 137 | 138 | 139 | 140 | 141 | ${project.build.directory}/classes 142 | 143 | 144 | 145 | org.slf4j 146 | slf4j-simple 147 | 1.5.11 148 | 149 | 150 | 151 | 152 | 153 | org.apache.maven.plugins 154 | maven-install-plugin 155 | 2.5.2 156 | 157 | 158 | 159 | org.apache.maven.plugins 160 | maven-deploy-plugin 161 | 2.8.2 162 | 163 | 164 | 165 | org.apache.sling 166 | maven-sling-plugin 167 | 2.1.8 168 | 169 | http://${aem.host}:${aem.port}/system/console 170 | WebConsole 171 | 172 | 173 | 174 | 175 | org.apache.felix 176 | maven-bundle-plugin 177 | 3.2.0 178 | true 179 | 180 | 181 | 182 | org.apache.maven.plugins 183 | maven-enforcer-plugin 184 | 1.4 185 | 186 | 187 | 188 | org.apache.maven.plugins 189 | maven-dependency-plugin 190 | 2.10 191 | 192 | 193 | 194 | org.codehaus.mojo 195 | build-helper-maven-plugin 196 | 1.9.1 197 | 198 | 199 | 200 | org.eclipse.m2e 201 | lifecycle-mapping 202 | 1.0.0 203 | 204 | 205 | 206 | 207 | 208 | org.apache.maven.plugins 209 | maven-enforcer-plugin 210 | [1.0.0,) 211 | 212 | enforce 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | org.apache.maven.plugins 223 | 224 | 225 | maven-dependency-plugin 226 | 227 | 228 | [2.2,) 229 | 230 | 231 | copy-dependencies 232 | unpack 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | org.codehaus.mojo 243 | 244 | 245 | build-helper-maven-plugin 246 | 247 | 248 | [1.5,) 249 | 250 | 251 | 252 | reserve-network-port 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | adobe-public 274 | 275 | 276 | true 277 | 278 | 279 | 280 | adobe-public-releases 281 | Adobe Public Releases 282 | https://repo.adobe.com/nexus/content/groups/public 283 | 284 | 285 | 286 | 287 | adobe-public-releases 288 | Adobe Public Repository 289 | https://repo.adobe.com/nexus/content/groups/public 290 | 291 | true 292 | never 293 | 294 | 295 | false 296 | 297 | 298 | 299 | 300 | 301 | 302 | adobe-public-releases 303 | Adobe Public Repository 304 | https://repo.adobe.com/nexus/content/groups/public 305 | 306 | true 307 | never 308 | 309 | 310 | false 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | autoInstallBundle 319 | 328 | 329 | false 330 | 331 | 332 | 333 | 334 | 335 | org.apache.sling 336 | maven-sling-plugin 337 | 338 | 339 | install-bundle 340 | 341 | install 342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | 354 | 355 | 356 | 357 | 358 | 359 | 360 | org.apache.felix 361 | org.apache.felix.scr 362 | 1.6.3-R1409029 363 | provided 364 | 365 | 366 | org.apache.felix 367 | org.apache.felix.scr.annotations 368 | 1.12.0 369 | provided 370 | 371 | 372 | org.apache.felix 373 | org.apache.felix.framework 374 | 5.6.0 375 | provided 376 | 377 | 378 | org.apache.felix 379 | org.apache.felix.eventadmin 380 | 1.4.8 381 | provided 382 | 383 | 384 | 385 | 386 | org.osgi 387 | org.osgi.service.metatype.annotations 388 | 1.3.0 389 | 390 | 391 | org.osgi 392 | org.osgi.service.component.annotations 393 | 1.3.0 394 | provided 395 | 396 | 397 | 398 | 399 | org.apache.commons 400 | commons-lang3 401 | 3.4 402 | provided 403 | 404 | 405 | org.slf4j 406 | slf4j-api 407 | 1.5.11 408 | provided 409 | 410 | 411 | javax.servlet 412 | servlet-api 413 | 2.5 414 | provided 415 | 416 | 417 | javax.servlet.jsp 418 | jsp-api 419 | 2.1 420 | provided 421 | 422 | 423 | javax.jcr 424 | jcr 425 | 2.0 426 | provided 427 | 428 | 429 | 430 | 431 | com.adobe.aem 432 | uber-jar 433 | 6.2.0 434 | provided 435 | obfuscated-apis 436 | 437 | 438 | 439 | 440 | 441 | 442 | --------------------------------------------------------------------------------